jeffreyvanhees/laravel-online-payment-platform

Laravel connector for Online Payment Platform API using SaloonPHP

v0.0.24 2025-07-29 10:26 UTC

README

Latest Version on Packagist Tests Coverage Total Downloads

A modern Laravel package for integrating with the Online Payment Platform API. Built with SaloonPHP and Spatie Laravel Data for an excellent developer experience.

Warning

This package is not affiliated with, endorsed by, or officially connected to Online Payment Platform B.V. It is an independent, community-driven implementation for integrating with their API. Also, this package is not intended for production use yet. It is still in development and may contain breaking changes.

โœจ Features

  • ๐Ÿš€ Laravel 11 & 12 Support - Full support for the latest Laravel versions
  • ๐Ÿ›ก๏ธ Type Safety - Fully typed DTOs using Spatie Laravel Data
  • ๐Ÿ—๏ธ Service Container - Native Laravel service container integration
  • ๐ŸŽญ Facade Support - Clean, expressive API using Laravel facades
  • ๐Ÿ”ง SaloonPHP Foundation - Built on the robust SaloonPHP HTTP client
  • ๐Ÿงช Comprehensive Testing - HTTP recording/replay for reliable tests
  • ๐Ÿ“š Intuitive API - Fluent interface: OnlinePaymentPlatform::merchants()->ubos()->create()
  • ๐Ÿ”„ Environment Support - Seamless sandbox/production switching
  • โšก Exception Handling - Detailed custom exceptions for all error scenarios
  • ๐Ÿ”„ Pagination Support - Built-in pagination with SaloonPHP

๐Ÿ“‹ Requirements

  • PHP 8.2 or higher
  • Laravel 11.0 or 12.0

๐Ÿš€ Installation

Install the package via Composer:

composer require jeffreyvanhees/laravel-online-payment-platform

Publish the configuration file:

php artisan vendor:publish --tag=opp-config

Configure your API credentials and URLs in your .env file:

# API Configuration
OPP_API_KEY=your_production_api_key_here
OPP_SANDBOX_API_KEY=your_sandbox_api_key_here
OPP_SANDBOX=true

# URL Configuration (optional - set default URLs for webhooks/notifications)
OPP_NOTIFY_URL=https://yourapp.com/webhooks/opp
OPP_RETURN_URL=https://yourapp.com/payment/return

# Webhook Configuration (optional)
OPP_NOTIFY_SECRET=your_webhook_secret

๐Ÿ“š API Documentation

๐Ÿ“‹ API Endpoints Index

  • Merchants - Create consumer/business merchants, manage contacts, addresses, UBOs, and profiles
  • Transactions - Create payments, retrieve status, update transaction details
  • Refunds - Process transaction refunds and list refund history
  • Global Settlements - Platform-wide settlement reporting and detailed rows
  • Charges - Balance transfers between merchants and fee management
  • Mandates - SEPA Direct Debit mandates and recurring transactions
  • Withdrawals - Merchant payouts to bank accounts
  • Disputes - Handle transaction disputes and chargebacks
  • Files - Upload and manage documents for verification/evidence
  • Partners - Partner configuration and settings management
  • Pagination - Handle paginated API responses

๐ŸŽฏ Usage

The package provides multiple ways to interact with the Online Payment Platform API:

Using the Facade (Recommended)

The facade provides the cleanest and most Laravel-like API:

<?php

use OnlinePaymentPlatform;
use JeffreyVanHees\OnlinePaymentPlatform\Data\Requests\Merchants\CreateConsumerMerchantData;

// Create a consumer merchant using DTO
$merchantData = new CreateConsumerMerchantData(
    type: 'consumer',
    country: 'NLD',
    emailaddress: 'john.doe@example.com',
    first_name: 'John',
    last_name: 'Doe',
);

$response = OnlinePaymentPlatform::merchants()->create($merchantData);

if ($response->successful()) {
    $merchant = $response->dto();
    echo "Created merchant: {$merchant->uid}";
}

Using Dependency Injection

Inject the connector directly into your classes (or create instances using the make() method):

<?php

namespace App\Services;

use JeffreyVanHees\OnlinePaymentPlatform\OnlinePaymentPlatformConnector;
use JeffreyVanHees\OnlinePaymentPlatform\Data\Requests\Merchants\CreateConsumerMerchantData;

class PaymentService
{
    public function __construct(
        private OnlinePaymentPlatformConnector $opp
    ) {}

    public function createMerchant(CreateConsumerMerchantData $merchantData): string
    {
        $response = $this->opp->merchants()->create($merchantData);
        
        if (!$response->successful()) {
            throw new \Exception('Failed to create merchant');
        }

        return $response->dto()->uid;
    }
    
    // Or create connector instances directly
    public function createQuickConnection(): OnlinePaymentPlatformConnector
    {
        return OnlinePaymentPlatformConnector::make(
            apiKey: config('opp.api_key'),
            sandbox: config('opp.sandbox')
        );
    }
}

Using Type-Safe DTOs

For maximum type safety and IDE support, use the provided Data Transfer Objects:

<?php

use OnlinePaymentPlatform;
use JeffreyVanHees\OnlinePaymentPlatform\Data\Requests\Merchants\CreateConsumerMerchantData;
use JeffreyVanHees\OnlinePaymentPlatform\Data\Requests\Transactions\CreateTransactionData;
use JeffreyVanHees\OnlinePaymentPlatform\Data\Common\ProductData;

// Create merchant using DTO
$merchantData = new CreateConsumerMerchantData(
    type: 'consumer',
    country: 'NLD',
    emailaddress: 'jane.doe@example.com',
    first_name: 'Jane',
    last_name: 'Doe',
    notify_url: 'https://yoursite.com/webhooks/opp'
);

$merchantResponse = OnlinePaymentPlatform::merchants()->create($merchantData);
$merchant = $merchantResponse->dto();

// Create transaction with products
$transactionData = new CreateTransactionData(
    merchant_uid: $merchant->uid,
    total_price: 2850, // โ‚ฌ28.50 in cents
    return_url: 'https://yoursite.com/payment/return',
    notify_url: 'https://yoursite.com/webhooks/opp',
    products: ProductData::collect([
        [
            'name' => 'Big Tasty',
            'quantity' => 1,
            'price' => 2500,
        ],
        [
            'name' => 'Milkshake Strawberry',
            'quantity' => 1,
            'price' => 350,
        ],
    ])
);

$transactionResponse = OnlinePaymentPlatform::transactions()->create($transactionData);
$transaction = $transactionResponse->dto();

echo "Payment URL: {$transaction->redirect_url}";

Merchants

use JeffreyVanHees\OnlinePaymentPlatform\Data\Requests\Merchants\{
    CreateConsumerMerchantData,
    CreateBusinessMerchantData
};

// Create consumer merchant
$consumerData = new CreateConsumerMerchantData(
    type: 'consumer',
    country: 'NLD',
    emailaddress: 'user@example.com',
    first_name: 'John',
    last_name: 'Doe',
    notify_url: 'https://yoursite.com/webhooks/opp',
);

$consumer = OnlinePaymentPlatform::merchants()->create($consumerData);

// Note: For consumer merchants, name_first/name_last in requests become 'name' field in responses
// For business merchants, legal_name in requests becomes 'name' field in responses

// Create business merchant
$businessData = new CreateBusinessMerchantData(
    type: 'business',
    country: 'NLD',
    emailaddress: 'business@example.com',
    coc_nr: '12345678',
    legal_name: 'Example B.V.',
    notify_url: 'https://yoursite.com/webhooks/opp',
);

$business = OnlinePaymentPlatform::merchants()->create($businessData);

// Retrieve and list merchants
$merchant = OnlinePaymentPlatform::merchants()->get('mer_123456789');
$merchants = OnlinePaymentPlatform::merchants()->list(['limit' => 50]);

// Add contacts and addresses
$contact = OnlinePaymentPlatform::merchants()->contacts('mer_123456789')->add([
    'type' => 'representative',
    'gender' => 'm',
    'title' => 'mr',
    'name' => [
        'first' => 'John',
        'last' => 'Smith',
        'initials' => 'J.S.',
        'names_given' => 'John',
    ],
    'emailaddresses' => [
        ['emailaddress' => 'john@example.com']
    ],
    'phonenumbers' => [
        ['phonenumber' => '+31612345678']
    ],
]);

$address = OnlinePaymentPlatform::merchants()->addresses('mer_123456789')->add([
    'type' => 'business',
    'address_line_1' => 'Main Street 123',
    'city' => 'Amsterdam',
    'zipcode' => '1000 AA',
    'country' => 'NLD',
]);

// Manage Ultimate Beneficial Owners (UBOs) for business merchants
$ubo = OnlinePaymentPlatform::merchants()->ubos('mer_123456789')->create([
    'name_first' => 'John',
    'name_last' => 'Doe', 
    'date_of_birth' => '1980-01-15',
    'country_of_residence' => 'NLD',
    'is_decision_maker' => true,
    'percentage_of_shares' => 25.5,
]);

// Create merchant profiles for different configurations
$profile = OnlinePaymentPlatform::merchants()->profiles('mer_123456789')->create([
    'name' => 'E-commerce Profile',
    'description' => 'Settings for online store',
    'notify_url' => 'https://store.example.com/webhook',
    'return_url' => 'https://store.example.com/success',
    'is_default' => false,
]);

// Update merchant information
$updated = OnlinePaymentPlatform::merchants()->update('mer_123456789', [
    'emailaddress' => 'newemail@example.com',
    'notify_url' => 'https://newdomain.com/webhook',
    'return_url' => 'https://newdomain.com/return',
]);

// Migrate consumer merchant to business merchant
$migrated = OnlinePaymentPlatform::merchants()->migrate('mer_123456789', [
    'type' => 'business',
    'legal_name' => 'Example Business B.V.',
    'coc_nr' => '12345678',
]);

// Get available payment methods for merchant
$paymentMethods = OnlinePaymentPlatform::merchants()->paymentMethods('mer_123456789')->list();

// Get merchant profile balance
$balance = OnlinePaymentPlatform::merchants()->profiles('mer_123456789')->balance('pro_987654321');

Update Operations

The SDK provides comprehensive update functionality for all merchant-related resources:

use JeffreyVanHees\OnlinePaymentPlatform\Data\Requests\Merchants;

// Update merchant address
$addressData = new Merchants\UpdateMerchantAddressData(
    street: 'Updated Street 456',
    housenumber: '12B',
    city: 'Rotterdam',
    zipcode: '3000 AA'
);
$updatedAddress = OnlinePaymentPlatform::merchants()->addresses('mer_123456789')->update('addr_123456789', $addressData);

// Update bank account information
$bankAccountData = new Merchants\UpdateMerchantBankAccountData(
    reference: 'updated-bank-ref-123',
    return_url: 'https://store.example.com/bank-return',
    notify_url: 'https://store.example.com/bank-notify'
);
$updatedBankAccount = OnlinePaymentPlatform::merchants()->bankAccounts('mer_123456789')->update('ba_123456789', $bankAccountData);

// Update contact information
$contactData = new Merchants\UpdateMerchantContactData(
    name: 'Jane Doe Updated',
    email: 'jane.updated@example.com',
    phone: '+31612345679'
);
$updatedContact = OnlinePaymentPlatform::merchants()->contacts('mer_123456789')->update('con_123456789', $contactData);

// Update merchant profile
$profileData = new Merchants\UpdateMerchantProfileData(
    name: 'Updated E-commerce Profile',
    description: 'Updated settings for online store',
    url: 'https://store.example.com',
    notify_url: 'https://store.example.com/updated-webhook',
    return_url: 'https://store.example.com/updated-success'
);
$updatedProfile = OnlinePaymentPlatform::merchants()->profiles('mer_123456789')->update('pro_123456789', $profileData);

// Update UBO information
$uboData = new Merchants\UpdateMerchantUBOData(
    name: 'John Doe Updated',
    name_prefix: 'Mr.',
    date_of_birth: '1980-01-15',
    country_of_residence: 'NLD',
    percentage_of_shares: 30.0
);
$updatedUBO = OnlinePaymentPlatform::merchants()->ubos('mer_123456789')->update('ubo_123456789', $uboData);

// Delete operations (where supported)
$deleteResult = OnlinePaymentPlatform::merchants()->profiles('mer_123456789')->delete('pro_123456789');

Sandbox Testing & Status Updates

For testing purposes, the SDK provides sandbox-only methods to simulate status changes:

// Note: These methods only work in sandbox environment and will throw 
// SandboxOnlyException in production

// Update merchant status (sandbox only)
$statusResult = OnlinePaymentPlatform::merchants()->updateStatus('mer_123456789', 'live');
// Available statuses: pending, live, terminated, suspended, blocked

// Update bank account status (sandbox only)  
$bankStatusResult = OnlinePaymentPlatform::merchants()->bankAccounts('mer_123456789')->updateStatus('ba_123456789', 'approved');
// Available statuses: pending, approved, disapproved
// Status flows: new -> pending -> approved/disapproved, approved -> disapproved -> approved

// Update contact status (sandbox only)
$contactStatusResult = OnlinePaymentPlatform::merchants()->contacts('mer_123456789')->updateStatus('con_123456789', 'verified');
// Available statuses: pending, verified, unverified
// Status flows: pending -> unverified/verified, unverified -> verified

// Update UBO status (sandbox only)
$uboStatusResult = OnlinePaymentPlatform::merchants()->ubos('mer_123456789')->updateStatus('ubo_123456789', 'verified');
// Available statuses: pending, verified, unverified  
// Status flows: pending -> unverified/verified, unverified -> verified

Flexible Input Types

All SDK methods accept both DTOs and arrays for maximum flexibility:

// Using DTOs (recommended for type safety)
$contactData = new Merchants\UpdateMerchantContactData(
    name: 'John Updated',
    email: 'john.updated@example.com'
);
$result = OnlinePaymentPlatform::merchants()->contacts('mer_123')->update('con_123', $contactData);

// Using arrays (convenient for simple updates)
$result = OnlinePaymentPlatform::merchants()->contacts('mer_123')->update('con_123', [
    'name' => 'John Updated',
    'email' => 'john.updated@example.com'
]);

// Status updates accept DTO, array, or string
$result = OnlinePaymentPlatform::merchants()->updateStatus('mer_123', 'live'); // string
$result = OnlinePaymentPlatform::merchants()->updateStatus('mer_123', ['status' => 'live']); // array
$result = OnlinePaymentPlatform::merchants()->updateStatus('mer_123', new Merchants\UpdateMerchantStatusData('live')); // DTO

Transactions

// Create transactions
$transaction = OnlinePaymentPlatform::transactions()->create([
    'merchant_uid' => 'mer_123456789',
    'total_price' => 1000, // โ‚ฌ10.00 in cents
    'products' => [
        [
            'name' => 'Product Name',
            'quantity' => 1,
            'price' => 1000,
        ],
    ],
    'return_url' => 'https://yoursite.com/payment/return',
    'notify_url' => 'https://yoursite.com/webhooks/opp',
]);

// Retrieve and list transactions
$transaction = OnlinePaymentPlatform::transactions()->get('tra_987654321');
$transactions = OnlinePaymentPlatform::transactions()->list(['limit' => 100]);

// Update transaction
$updated = OnlinePaymentPlatform::transactions()->update('tra_987654321', [
    'description' => 'Updated description',
]);

Refunds

use JeffreyVanHees\OnlinePaymentPlatform\Data\Requests\Transactions\CreateRefundData;

// Create a refund for a transaction
$refundData = new CreateRefundData(
    amount: 1000, // โ‚ฌ10.00 in cents
    payout_description: 'Refund for defective product',
    internal_reason: 'product_defect',
    metadata: ['reason' => 'customer_complaint']
);

$refund = OnlinePaymentPlatform::transactions()->refunds('tra_123456789')->create($refundData);

// List all refunds for a transaction
$refunds = OnlinePaymentPlatform::transactions()->refunds('tra_123456789')->list();

// Access refund data
if ($refund->successful()) {
    $refundData = $refund->dto();
    echo "Refund created: {$refundData->uid}";
    echo "Status: {$refundData->status}";
    echo "Amount: {$refundData->amount} cents";
}

Global Settlements

// List all platform settlements
$settlements = OnlinePaymentPlatform::settlements()->list([
    'status' => 'completed',
    'limit' => 50
]);

// Get detailed settlement specification rows
$settlementRows = OnlinePaymentPlatform::settlements()->specificationRows(
    settlementUid: 'set_123456789',
    specificationUid: 'spec_987654321'
);

// Access settlement data
foreach ($settlements->dto()->data as $settlement) {
    echo "Settlement: {$settlement->uid}";
    echo "Status: {$settlement->status}";
    echo "Total Amount: {$settlement->total_amount}";
    echo "Period: {$settlement->period_start} - {$settlement->period_end}";
}

// Access settlement row details
foreach ($settlementRows->dto()->data as $row) {
    echo "Type: {$row->type}";
    echo "Reference: {$row->reference}";
    echo "Amount: {$row->amount}";
    if ($row->amount_payable) {
        echo "Amount Payable: {$row->amount_payable}";
    }
}

Charges

// Create charges for balance transfers between merchants
$charge = OnlinePaymentPlatform::charges()->create([
    'type' => 'balance',
    'amount' => 1500, // โ‚ฌ15.00 in cents
    'from_owner_uid' => 'mer_123456789',
    'to_owner_uid' => 'mer_987654321',
    'description' => 'Monthly platform fee',
    'metadata' => ['invoice_id' => 'INV-2024-001'],
]);

// Retrieve charge details
$charge = OnlinePaymentPlatform::charges()->get('cha_123456789');

// List charges with filters
$charges = OnlinePaymentPlatform::charges()->list([
    'from_owner_uid' => 'mer_123456789',
    'status' => 'completed',
    'limit' => 50,
]);

Mandates

// Create SEPA Direct Debit mandate
$mandate = OnlinePaymentPlatform::mandates()->create([
    'merchant_uid' => 'mer_123456789',
    'holder_name' => 'John Doe',
    'iban' => 'NL91ABNA0417164300',
    'bic' => 'ABNANL2A',
    'description' => 'Monthly meal plan mandate',
    'reference' => 'MEALPLAN-2024',
]);

// Retrieve mandate
$mandate = OnlinePaymentPlatform::mandates()->get('man_123456789');

// Create transaction using mandate
$transaction = OnlinePaymentPlatform::mandates()->transactions('man_123456789')->create([
    'amount' => 2500, // โ‚ฌ25.00 in cents
    'description' => 'Monthly meal plan payment',
]);

// Delete mandate
OnlinePaymentPlatform::mandates()->delete('man_123456789');

Withdrawals

// Create withdrawal to merchant's bank account
$withdrawal = OnlinePaymentPlatform::withdrawals()->create('mer_123456789', [
    'amount' => 50000, // โ‚ฌ500.00 in cents
    'currency' => 'EUR',
    'bank_account_uid' => 'ban_123456789',
    'description' => 'Weekly payout',
    'reference' => 'PAYOUT-2024-W01',
]);

// Retrieve withdrawal status
$withdrawal = OnlinePaymentPlatform::withdrawals()->get('wit_123456789');

// List withdrawals for a merchant
$withdrawals = OnlinePaymentPlatform::withdrawals()->list([
    'merchant_uid' => 'mer_123456789',
    'status' => 'completed',
    'limit' => 25,
]);

// Cancel pending withdrawal
OnlinePaymentPlatform::withdrawals()->delete('wit_123456789');

Disputes

// Create dispute for a transaction
$dispute = OnlinePaymentPlatform::disputes()->create([
    'transaction_uid' => 'tra_123456789',
    'amount' => 1000, // โ‚ฌ10.00 in cents
    'reason' => 'Product not received',
    'message' => 'Customer claims product was never delivered',
    'evidence' => [
        'tracking_number' => 'TRACK123456',
        'shipping_date' => '2024-01-15',
    ],
]);

// Retrieve dispute with transaction details
$dispute = OnlinePaymentPlatform::disputes()->get('dis_123456789', [
    'include' => 'transaction',
]);

// List all disputes
$disputes = OnlinePaymentPlatform::disputes()->list([
    'status' => 'pending',
    'created_after' => '2024-01-01',
]);

Files

// Create file upload token
$upload = OnlinePaymentPlatform::files()->createUpload([
    'filename' => 'invoice.pdf',
    'purpose' => 'dispute_evidence',
]);

// Upload the actual file
$file = OnlinePaymentPlatform::files()->upload(
    fileUid: $upload->dto()->uid,
    token: $upload->dto()->token,
    filePath: '/path/to/invoice.pdf',
    fileName: 'invoice.pdf'
);

// List uploaded files
$files = OnlinePaymentPlatform::files()->list([
    'purpose' => 'dispute_evidence',
    'created_after' => '2024-01-01',
]);

Partners

// Get partner configuration
$config = OnlinePaymentPlatform::partners()->getConfiguration();

// Update partner settings (only notify_url is updatable)
$updated = OnlinePaymentPlatform::partners()->updateConfiguration([
    'notify_url' => 'https://partner.example.com/webhooks',
]);

// Get merchant balance via partner
$merchantBalance = OnlinePaymentPlatform::partners()->getMerchantBalance('mer_123456789');

Pagination

When building API integrations, you may encounter scenarios where the server doesn't provide all results in a single response. Instead, it divides results into several pages. This strategy is called pagination, and integrating it into your application can be tedious and repetitive.

With this SDK, you can leverage SaloonPHP's powerful pagination plugin to reduce boilerplate code and iterate through every result across every page in one loop. When you set a limit, it will automatically fetch as many pages as necessary to get all results.

// Get single page of results
$response = OnlinePaymentPlatform::merchants()->list(['limit' => 25]);
$merchants = $response->dto();

// Process single page
foreach ($merchants->data as $merchant) {
    echo "Merchant: {$merchant->uid} - {$merchant->emailaddress}\n";
}

// โœจ Magic: Iterate through ALL pages automatically
foreach (OnlinePaymentPlatform::merchants()->list(['limit' => 25])->paginate() as $response) {
    $merchants = $response->dto();
    
    foreach ($merchants->data as $merchant) {
        echo "Merchant: {$merchant->uid} - {$merchant->emailaddress}\n";
    }
    
    echo "Processed page with " . count($merchants->data) . " merchants\n";
}

// The paginate() method handles all the complexity:
// - Automatically fetches next pages
// - Handles different pagination strategies  
// - Stops when no more results
// - Memory efficient iteration

Key Benefits:

  • Automatic: No manual page tracking or URL construction
  • Memory Efficient: Processes one page at a time, not all at once
  • Error Resilient: Handles API errors gracefully
  • Flexible: Works with any limit size you specify

โš™๏ธ Configuration

The configuration file (config/opp.php) allows you to customize various aspects:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | API Credentials
    |--------------------------------------------------------------------------
    */
    'api_key' => env('OPP_API_KEY'),
    'sandbox_api_key' => env('OPP_SANDBOX_API_KEY'),

    /*
    |--------------------------------------------------------------------------
    | Environment
    |--------------------------------------------------------------------------
    */
    'sandbox' => env('OPP_SANDBOX', true),

    /*
    |--------------------------------------------------------------------------
    | HTTP Configuration
    |--------------------------------------------------------------------------
    */
    'timeout' => env('OPP_TIMEOUT', 30),
    'retry' => [
        'times' => env('OPP_RETRY_TIMES', 3),
        'sleep' => env('OPP_RETRY_SLEEP', 1000),
    ],
];

๐Ÿšจ Error Handling

The package provides detailed exception handling:

use JeffreyVanHees\OnlinePaymentPlatform\Exceptions\{
    OppException,
    AuthenticationException,
    ValidationException,
    RateLimitException,
    ApiException
};

try {
    $response = OnlinePaymentPlatform::merchants()->create($invalidData);
} catch (ValidationException $e) {
    // Handle validation errors
    $errors = $e->getValidationErrors();
    foreach ($errors as $field => $messages) {
        echo "{$field}: " . implode(', ', $messages);
    }
} catch (AuthenticationException $e) {
    // Handle authentication issues
    echo "Authentication failed: " . $e->getMessage();
} catch (RateLimitException $e) {
    // Handle rate limiting
    echo "Rate limit exceeded. Retry after: " . $e->getRetryAfter();
} catch (OppException $e) {
    // Handle general API errors
    echo "API Error: " . $e->getMessage();
}

๐Ÿงช Testing

Run the test suite:

# Run all tests
composer test

# Run tests with coverage report
composer test-coverage

# Generate HTML coverage report
composer test-coverage-html

# Generate Clover XML coverage report  
composer test-coverage-clover

# Record new HTTP interactions (requires real API credentials)
composer record

# Run tests using recorded interactions
composer replay

Test Coverage

The package includes comprehensive tests covering all API endpoints with 85.2% code coverage:

  • โœ… 302 tests covering all major endpoints and DTOs
  • โœ… 1250 assertions ensuring functionality
  • โœ… Merchant operations - CRUD, contacts, addresses, bank accounts, settlements, UBOs, profiles
  • โœ… Transaction lifecycle - create, retrieve, update, delete
  • โœ… Payment flows - charges, mandates, withdrawals, disputes
  • โœ… File operations - upload, retrieval, management
  • โœ… Partner configuration - settings management
  • โœ… Error handling - graceful sandbox environment handling

Coverage reports are generated in multiple formats:

  • Terminal: Real-time coverage during test runs
  • HTML: Detailed browsable report in coverage-report/
  • XML: Machine-readable format for CI/CD integration

๐Ÿ“– Advanced Usage

Custom HTTP Client Configuration

Note: The package automatically registers the connector in Laravel's service container using the configuration from config/opp.php. No manual service provider binding is needed.

use JeffreyVanHees\OnlinePaymentPlatform\OnlinePaymentPlatformConnector;

// Using constructor
$connector = new OnlinePaymentPlatformConnector(
    apiKey: 'your-api-key',
    sandbox: true
);

// Or using the static make() method
$connector = OnlinePaymentPlatformConnector::make('your-api-key', true);
$connector = OnlinePaymentPlatformConnector::make('your-api-key'); // defaults to sandbox
$connector = OnlinePaymentPlatformConnector::make('your-api-key', false); // production

// Add custom middleware
$connector->middleware()->onRequest(function ($request) {
    $request->headers()->add('Custom-Header', 'value');
    return $request;
});

// Add retry logic
$connector->middleware()->onResponse(function ($response) {
    if ($response->status() === 429) {
        sleep(1);
        return $response->throw(); // Retry
    }
    return $response;
});

๐Ÿš€ Releases

This package uses automated versioning and releases:

  • Automatic: Patch version bump on every push to main branch
  • Manual: Use commit messages to control version bumps:
    • [major] in commit message โ†’ Major version bump (e.g., 1.0.0 โ†’ 2.0.0)
    • [minor] in commit message โ†’ Minor version bump (e.g., 1.0.0 โ†’ 1.1.0)
    • Default โ†’ Patch version bump (e.g., 1.0.0 โ†’ 1.0.1)
  • Skip Release: Add [skip release] to commit message to skip version bump

Manual Release Trigger

You can also manually trigger a release via GitHub Actions:

  1. Go to Actions โ†’ Release workflow
  2. Click "Run workflow"
  3. Select the version bump type (patch/minor/major)

๐Ÿค Contributing

Please see CONTRIBUTING.md for details on how to contribute.

๐Ÿ“ License

The MIT License (MIT). Please see License File for more information.

๐Ÿ™ Credits