Payment Providers

Extend PteroCA with custom payment gateways.

Payment Provider Interface

<?php
namespace Plugins\MyPlugin\Provider;

use App\Core\Payment\PaymentProviderInterface;
use App\Core\Payment\DTO\PaymentSessionDTO;

class MyPaymentProvider implements PaymentProviderInterface
{
    public function __construct(
        private readonly MyPaymentAdapter $adapter,
        private readonly LoggerInterface $logger,
    ) {}

    public function getIdentifier(): string
    {
        return 'my-provider';
    }

    public function getDisplayName(): string
    {
        return 'My Payment Provider';
    }

    public function isConfigured(): bool
    {
        // Check if required settings are present
        $apiKey = $this->pluginSettings->get('my-plugin', 'api_key');
        return !empty($apiKey);
    }

    public function createSession(
        string $userId,
        float $amount,
        string $currency,
        array $metadata = []
    ): ?PaymentSessionDTO {
        try {
            $session = $this->adapter->createPaymentSession(
                amount: $amount,
                currency: $currency,
                metadata: $metadata
            );

            return new PaymentSessionDTO(
                id: $session['id'],
                status: $session['status'],
                amount: $amount,
                currency: $currency,
                checkoutUrl: $session['checkout_url'],
                metadata: $metadata
            );
        } catch (\Exception $e) {
            $this->logger->error('Payment session creation failed', [
                'provider' => $this->getIdentifier(),
                'error' => $e->getMessage()
            ]);

            return null;
        }
    }

    public function retrieveSession(string $sessionId): ?PaymentSessionDTO
    {
        try {
            $session = $this->adapter->getSession($sessionId);

            return new PaymentSessionDTO(
                id: $session['id'],
                status: $session['status'],
                amount: $session['amount'],
                currency: $session['currency'],
                checkoutUrl: $session['checkout_url'],
                metadata: $session['metadata']
            );
        } catch (\Exception $e) {
            $this->logger->error('Payment session retrieval failed', [
                'provider' => $this->getIdentifier(),
                'session_id' => $sessionId,
                'error' => $e->getMessage()
            ]);

            return null;
        }
    }

    public function getIcon(): string
    {
        return 'fab fa-cc-stripe';  // FontAwesome icon
    }

    public function getDescription(): string
    {
        return 'Accept payments via My Payment Provider';
    }

    public function getSupportedCurrencies(): array
    {
        return ['USD', 'EUR', 'GBP', 'PLN'];
    }

    public function getMetadata(): array
    {
        return [
            'website' => 'https://myprovider.com',
            'support_email' => '[email protected]',
        ];
    }

    public function getSuccessCallbackRoute(): string
    {
        return 'plugin_my_plugin_payment_success';
    }

    public function getCancelCallbackRoute(): string
    {
        return 'plugin_my_plugin_payment_cancel';
    }

    public function extractSessionIdFromCallback(Request $request): ?string
    {
        return $request->query->get('session_id');
    }

    public function buildSuccessUrl(string $baseUrl): string
    {
        return $baseUrl . '?status=success';
    }

    public function buildCancelUrl(string $baseUrl): string
    {
        return $baseUrl . '?status=cancelled';
    }
}

Required Interface Methods

Core Methods

  • getIdentifier(): Unique provider identifier (e.g., "my-provider")

  • getDisplayName(): Human-readable name shown to users

  • getIcon(): FontAwesome icon class for UI display

  • getDescription(): Brief description of the payment provider

  • isConfigured(): Check if provider has required settings configured

  • getSupportedCurrencies(): Array of ISO currency codes supported

  • getMetadata(): Additional provider information (website, support contact)

Session Management

  • createSession(): Create a new payment session and return checkout URL

  • retrieveSession(): Retrieve existing session data by session ID

Callback Handling

  • getSuccessCallbackRoute(): Route name for successful payment redirect

  • getCancelCallbackRoute(): Route name for cancelled payment redirect

  • extractSessionIdFromCallback(): Extract session ID from callback request

  • buildSuccessUrl(): Build complete success redirect URL with parameters

  • buildCancelUrl(): Build complete cancel redirect URL with parameters

Payment Adapter Pattern

Wrap external SDKs with an adapter:

Webhook Handling

Service Registration

Important: Payment providers must be:

  • Tagged with payment.provider

  • Marked as public: true

External SDK Integration

Add SDK to plugin's composer.json:

Install dependencies:

Configuration Schema

Define settings in plugin.json:

Testing Payment Provider

Error Handling

Security Best Practices

  1. Validate webhooks: Always verify signatures

  2. Use HTTPS: Never send API keys over HTTP

  3. Store secrets securely: Use password field type in config

  4. Log all transactions: Track payments for auditing

  5. Handle errors gracefully: Don't expose sensitive details

  6. Idempotency: Handle duplicate webhook calls

  7. Rate limiting: Respect API rate limits

Last updated