comfino/sdk-for-magento2

Comfino PHP SDK adapter for Magento 2 - wires Magento native services to SDK PSR interfaces.

Maintainers

Package info

github.com/comfino/sdk-for-magento2

Type:magento2-module

pkg:composer/comfino/sdk-for-magento2

Transparency log

Statistics

Installs: 4

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-07-22 09:45 UTC

This package is auto-updated.

Last update: 2026-07-22 09:58:32 UTC


README

Comfino

Comfino SDK for Magento 2

Latest Version PHP Version Build Status Software License Total Downloads API Documentation

Magento 2 adapter layer for the Comfino PHP SDK

This package wires Magento 2's native services into the PSR interfaces expected by comfino/php-sdk. It is a thin adapter layer with no business logic — all integration behaviour lives in the upstream SDK.

It is a required dependency of the official Comfino Magento 2 payment plugin and is not intended for standalone use.

What it provides

Adapter class Magento service PSR interface
Comfino\Magento\Http\MagentoHttpClientAdapter Magento\Framework\HTTP\Client\Curl PSR-18 ClientInterface
Comfino\Magento\Cache\MagentoCacheAdapter Magento\Framework\Cache\FrontendInterface PSR-6 CacheItemPoolInterface + Symfony TagAwareCacheInterface
Comfino\Magento\Cache\CacheItem PSR-6 CacheItemInterface + Symfony ItemInterface
Comfino\Magento\Http\MagentoServerRequestConverter Magento\Framework\App\Request\Http PSR-7 ServerRequestInterface
Comfino\Magento\Bootstrap Static initializer Wires adapters into comfino/php-sdk singletons

Requirements

  • PHP 8.1 or higher
  • Magento 2.3 or higher (magento/framework >= 103.0.4)
  • comfino/php-sdk
  • Composer

Installation

composer require comfino/sdk-for-magento2

This package is pulled in automatically when you install the Comfino Magento 2 payment plugin.

Usage

Call Bootstrap::init() once during Magento DI resolution, typically from the plugin's own observer or bootstrap class injected via etc/events.xml:

use Comfino\Magento\Bootstrap as SdkBootstrap;
use Comfino\Magento\Cache\MagentoCacheAdapter;
use Comfino\Magento\Http\MagentoHttpClientAdapter;
use Magento\Framework\Cache\FrontendInterface;
use Magento\Framework\HTTP\Client\Curl as MagentoCurl;
use Magento\Framework\Serialize\SerializerInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Log\LoggerInterface;

class BootstrapObserver implements \Magento\Framework\Event\ObserverInterface
{
    private bool $initialized = false;

    public function __construct(
        private readonly MagentoCurl $curl,
        private readonly RequestFactoryInterface $requestFactory,
        private readonly StreamFactoryInterface $streamFactory,
        private readonly FrontendInterface $cache,
        private readonly SerializerInterface $serializer,
        private readonly LoggerInterface $logger,
    ) {}

    public function execute(\Magento\Framework\Event\Observer $observer): void
    {
        if ($this->initialized) {
            return;
        }

        SdkBootstrap::init(
            httpClient: new MagentoHttpClientAdapter($this->curl, $this->requestFactory, $this->streamFactory),
            requestFactory: $this->requestFactory,
            streamFactory: $this->streamFactory,
            cachePool: new MagentoCacheAdapter($this->cache, $this->serializer),
            logger: $this->logger,
        );

        $this->initialized = true;
    }
}

After Bootstrap::init(), retrieve the wired services for use with ApiClientFactory:

use Comfino\Backend\Factory\ApiClientFactory;
use Comfino\Magento\Bootstrap as SdkBootstrap;

$client = (new ApiClientFactory())->createClient(
    httpClient: SdkBootstrap::getHttpClient(),
    requestFactory: SdkBootstrap::getRequestFactory(),
    streamFactory: SdkBootstrap::getStreamFactory(),
    apiKey: $config->getApiKey(),
);

Webhook handling

Convert an incoming Magento HTTP request to a PSR-7 ServerRequestInterface for the SDK's WebhookManager:

use Comfino\Backend\Webhook\WebhookManager;
use Comfino\Magento\Http\MagentoServerRequestConverter;

class WebhookController extends \Magento\Framework\App\Action\Action
{
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        private readonly MagentoServerRequestConverter $converter,
        private readonly WebhookManager $webhookManager,
    ) {
        parent::__construct($context);
    }

    public function execute(): \Magento\Framework\App\ResponseInterface
    {
        $serverRequest = $this->converter->convert($this->getRequest());
        $this->webhookManager->processRequest('status_notification', $serverRequest);

        return $this->getResponse()->setBody('OK');
    }
}

Adapter notes

HTTP adapter

MagentoHttpClientAdapter wraps Magento\Framework\HTTP\Client\Curl as a PSR-18 client. Key behaviours:

  • Response headers are not forwarded — Magento\Framework\HTTP\Client\Curl does not expose them. This is safe because Comfino\Api\AbstractClient only sets request headers and never reads response headers.
  • HTTP status 0 (connection timeout or DNS failure) is detected and thrown as NetworkException (implements Psr\Http\Client\NetworkExceptionInterface), which the SDK's retry executor treats as retryable.
  • Non-standard verbs (PUT, DELETE, PATCH) are routed via CURLOPT_CUSTOMREQUEST since Magento's Curl client exposes only get() and post() publicly.
  • Timeout escalation is supported via TimeoutAwareClientInterface::updateTimeouts(), called by the SDK's ExponentialBackoffRetryPolicy on each retry attempt.

Cache adapter

MagentoCacheAdapter wraps Magento\Framework\Cache\FrontendInterface as a PSR-6 pool:

  • All keys are prefixed with comfino_ to avoid collisions.
  • All entries are tagged with comfino for bulk invalidation via clear(). Per-item tags set via CacheItem::setTags() are merged with the base comfino tag on save.
  • Values are serialized using the injected Magento\Framework\Serialize\SerializerInterface.
  • Implements Symfony\Contracts\Cache\TagAwareCacheInterface: invalidateTags() delegates to Magento's FrontendInterface::clean(CLEANING_MODE_MATCHING_TAG, …).

Development

The bin/ wrappers delegate to a PHP 8.1 Docker container when docker-compose is available, or fall back to the host PHP.

# Start the development container.
docker-compose up -d

# Install dependencies.
./bin/composer install

# Run all tests.
./bin/phpunit

# Generate HTML coverage report (Xdebug container starts automatically).
./bin/phpunit --coverage-html coverage

PSR standards

  • PSR-4 autoloading
  • PSR-6 cache
  • PSR-7 HTTP messages
  • PSR-17 HTTP factories
  • PSR-18 HTTP client
  • PSR-12 coding style

License

BSD 3-Clause License. See LICENSE for details.

Support

Bug reports and feature requests: GitHub issue tracker.

Contributing

The GitHub repository is a read-only public mirror that receives automated clean-snapshot releases. Please report bugs and suggest improvements via the issue tracker.