PHPackages                             timeax/paykit-sdk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. timeax/paykit-sdk

ActiveLibrary[PSR &amp; Standards](/categories/psr-standards)

timeax/paykit-sdk
=================

PayKit Gateway SDK (contracts + typed payloads) for integrating multiple payment providers through strict contracts and DTO payloads.

v0.1.0(6mo ago)044MITPHPPHP ^8.1

Since Jan 1Pushed 3w agoCompare

[ Source](https://github.com/timeax/payment-gateway-sdk)[ Packagist](https://packagist.org/packages/timeax/paykit-sdk)[ RSS](/packages/timeax-paykit-sdk/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (3)Versions (11)Used By (0)

📦 PayKit Gateway SDK (Contracts + Payloads)
===========================================

[](#-paykit-gateway-sdk-contracts--payloads)

[![PHP Version](https://camo.githubusercontent.com/962aced9b09d89716dbebf186ff899754a096ff1068b6b7988675c2d9fab9331/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e322d626c75652e737667)](https://packagist.org/packages/timeax/paykit-sdk)[![License](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](LICENSE)[![Build Status](https://camo.githubusercontent.com/3ab4882a1b7d64e5eb5168ad0b0b9cdfd53f59f114ee5f727958504214a5789c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d70617373696e672d627269676874677265656e2e737667)](tests/)[![Static Analysis](https://camo.githubusercontent.com/2a0e1131a0721d24c28ddf2126d1afedcf7cd66a0e0d016a308df8b80d8eae42/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068707374616e2d6c6576656c25323030253230636c65616e2d627269676874677265656e2e737667)](phpstan.neon)

A **business-agnostic, enterprise-grade Financial Infrastructure Protocol Engine** that enables host PHP applications to integrate multiple payment and banking providers (Stripe, Adyen, Paystack, Flutterwave, Airwallex, Marqeta) through strict contracts and strongly-typed payloads.

---

🎯 What We Ship
--------------

[](#-what-we-ship)

- **Strict Contracts (interfaces):** 39 granular PHP interfaces defining payment, refund, payout, bulk transfer, virtual account, double-entry ledger, balance snapshot, virtual card issuing, and webhook deduplication capabilities.
- **Typed Payloads (DTOs):** Immutable PHP 8.2+ request, response, and event objects (zero untyped arrays for core domain operations).
- **Elqora Interaction Protocol Integration:** Standardized frontend-host UI flow descriptions via [`elqora/interactions`](https://github.com/elqora/interactions).
- **Manager &amp; Capability Engine:** DB-first driver registry and manifest resolution system for high-performance runtime filtering.
- **Abstract Driver Bases:** Safe defaults, reusable configuration helpers, and schema validation tools.

---

❌ What We Do NOT Ship
---------------------

[](#-what-we-do-not-ship)

- Checkout/cart/invoice semantics (the SDK is strictly decoupled from host business domains).
- Host database schemas or migrations (hosts persist manifests and capabilities however they choose).
- Vendor-specific HTTP clients inside `src/` (drivers implement contracts using Guzzle, Symfony HTTP, or custom SDKs).

> **Source of Truth:** Only `src/` is the SDK public API surface.

---

0) Installation &amp; Requirements
----------------------------------

[](#0-installation--requirements)

### PHP Version

[](#php-version)

Requires **PHP 8.2+** with `ext-json` and `ext-mbstring`.

### Composer

[](#composer)

```
composer require timeax/paykit-sdk
```

### Namespace / Autoloading

[](#namespace--autoloading)

This SDK is PSR-4 autoloaded under the `PayKit\` namespace:

```
"autoload": {
  "psr-4": {
    "PayKit\\": "src/"
  }
}
```

---

0.1) Laravel Integration (Service Provider Binding)
---------------------------------------------------

[](#01-laravel-integration-service-provider-binding)

PayKit is framework-agnostic. In Laravel host applications, bind `GatewayManager` as a singleton in your `AppServiceProvider`:

```
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use PayKit\Manager\DriverResolver;
use PayKit\Manager\GatewayManager;
use PayKit\Manager\GatewayRegistry;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(GatewayRegistry::class, fn () => new GatewayRegistry());

        $this->app->singleton(DriverResolver::class, fn ($app) =>
            new DriverResolver($app->make(GatewayRegistry::class))
        );

        $this->app->singleton(GatewayManager::class, fn ($app) =>
            new GatewayManager($app->make(DriverResolver::class))
        );
    }
}
```

---

1) Core Architectural Principles
--------------------------------

[](#1-core-architectural-principles)

### 1. Model-First (Host DB is Source of Truth)

[](#1-model-first-host-db-is-source-of-truth)

Drivers discover support matrices (currencies, countries, capability flags) **only during manifest synchronization**, never at checkout runtime. Checkout filtering occurs in local database space without triggering high-latency third-party HTTP calls.

### 2. Host-Controlled Business Logic

[](#2-host-controlled-business-logic)

Drivers communicate with payment vendors and report canonical statuses. The host application decides what "succeeded" means (e.g., crediting a user wallet, fulfilling an order, or releasing a digital asset).

### 3. Capability-by-Contract

[](#3-capability-by-contract)

New capabilities are introduced as discrete, isolated PHP interfaces in `src/Contracts/`. Feature support is verified via standard PHP runtime introspection (`$driver instanceof PaymentGatewayBulkPayoutsContract`).

### 4. Strict Typed Payloads &amp; Idempotency

[](#4-strict-typed-payloads--idempotency)

Core domain methods accept strongly-typed DTOs with explicit `IdempotencyKey` value objects and `GatewayFailure` error payloads.

---

2) Code Examples by Financial Domain
------------------------------------

[](#2-code-examples-by-financial-domain)

---

### 2.1 Core Payments &amp; Elqora Interactions

[](#21-core-payments--elqora-interactions)

Initiate a payment and receive a canonical status along with an **Elqora Interaction** (`Redirect`, `Instructions`, `QrCode`, `Component`, `Mount`, `Script`):

```
use PayKit\Pay;
use PayKit\Payload\Common\Amount;
use PayKit\Payload\Common\Currency;
use PayKit\Payload\Common\Money;
use PayKit\Payload\Common\Reference;
use PayKit\Payload\Requests\PaymentInitiateRequest;

// Resolve driver singleton or via manager
$driver = Pay::via('stripe', $configBag);

$request = new PaymentInitiateRequest(
    reference: new Reference('order_9901'),
    money: new Money(Amount::from(5000), new Currency('USD')),
    customerEmail: 'customer@example.com',
    customerName: 'Jane Doe'
);

$result = $driver->initiatePayment($request);

if ($result->status->value === 'pending' && $result->interaction !== null) {
    // Interaction automatically serializes to canonical flat wire format for frontend execution
    $wirePayload = $result->interaction->toArray();
    /*
    [
        'type' => 'redirect',
        'url' => 'https://checkout.stripe.com/pay/cs_test_123',
        'target' => '_self'
    ]
    */
}
```

---

### 2.2 Outward Payouts, Sources &amp; Typed Destinations

[](#22-outward-payouts-sources--typed-destinations)

Route single payouts to bank accounts, mobile money wallets, cards, crypto addresses, or beneficiaries:

```
use PayKit\Payload\Common\BankAccountDestination;
use PayKit\Payload\Common\IdempotencyKey;
use PayKit\Payload\Common\Money;
use PayKit\Payload\Common\PayoutDestination;
use PayKit\Payload\Common\PayoutSource;
use PayKit\Payload\Common\PayoutSourceType;
use PayKit\Payload\Common\Reference;
use PayKit\Payload\Requests\PayoutRequest;

// 1. Create a strongly-typed destination payload
$bankDestination = new PayoutDestination(
    payload: new BankAccountDestination(
        accountNumber: '0123456789',
        accountName: 'John Doe',
        bankCode: '058',
        routingNumber: '123456',
        providerData: ['nibss_code' => '000013']
    )
);

// 2. Define explicit payout source (Virtual Account, Provider Balance, or Balance Account)
$source = new PayoutSource(
    type: PayoutSourceType::virtual_account,
    sourceId: 'va_987654'
);

// 3. Initiate Payout with explicit IdempotencyKey
$payoutRequest = new PayoutRequest(
    reference: new Reference('payout_7711'),
    money: Money::from(25000, 'NGN'),
    destination: $bankDestination,
    source: $source,
    idempotencyKey: new IdempotencyKey('idemp_po_7711'),
    narration: 'Monthly vendor settlement'
);

$payoutResult = $driver->initiatePayout($payoutRequest);

echo $payoutResult->status->value; // "processing" | "succeeded" | "requires_action"
echo $payoutResult->netAmount?->toArray()['amount']; // Net settled funds
```

---

### 2.3 Bulk Payouts &amp; Batch Transfers

[](#23-bulk-payouts--batch-transfers)

Submit thousands of itemized payouts in a single batch with item-level status tracking:

```
use PayKit\Payload\Common\BulkPayoutItem;
use PayKit\Payload\Common\MobileMoneyDestination;
use PayKit\Payload\Common\Money;
use PayKit\Payload\Common\PayoutDestination;
use PayKit\Payload\Common\Reference;
use PayKit\Payload\Requests\BulkPayoutRequest;

$item1 = new BulkPayoutItem(
    itemId: 'item_01',
    money: Money::from(1500, 'GHS'),
    destination: (new PayoutDestination(
        payload: new MobileMoneyDestination(phoneNumber: '+233241234567', operator: 'mtn')
    ))->payload
);

$bulkRequest = new BulkPayoutRequest(
    reference: new Reference('batch_2026_07'),
    items: [$item1],
    title: 'Payroll Batch'
);

$bulkResult = $driver->initiateBulkPayout($bulkRequest);

echo $bulkResult->totalCount;   // Total items in batch
echo $bulkResult->successCount; // Successfully processed items
```

---

### 2.4 Account Resolution &amp; Destination Validation

[](#24-account-resolution--destination-validation)

Verify bank account numbers, IBANs, or mobile money names before payout execution:

```
use PayKit\Payload\Common\BankAccountDestination;
use PayKit\Payload\Requests\PayoutDestinationResolveRequest;

$resolveRequest = new PayoutDestinationResolveRequest(
    destination: new BankAccountDestination(
        accountNumber: '0123456789',
        bankCode: '058'
    )
);

$resolution = $driver->resolvePayoutDestination($resolveRequest);

if ($resolution->resolved) {
    echo $resolution->accountName; // "Verified Account Name"
}
```

---

### 2.5 Virtual Accounts &amp; Compliance Identity (KYC / KYB)

[](#25-virtual-accounts--compliance-identity-kyc--kyb)

Provision dedicated collection accounts or single-use payment vIBANs with structured compliance identifiers:

```
use PayKit\Payload\Common\Country;
use PayKit\Payload\Common\CustomerIdentity;
use PayKit\Payload\Common\IdentityIdentifier;
use PayKit\Payload\Common\Reference;
use PayKit\Payload\Common\VirtualAccountPurpose;
use PayKit\Payload\Common\VirtualAccountUsage;
use PayKit\Payload\Requests\VirtualAccountCreateRequest;

$customer = new CustomerIdentity(
    providerCustomerId: 'cus_8899',
    name: 'Alice Smith',
    email: 'alice@example.com',
    phone: '+2348012345678',
    identifiers: [
        new IdentityIdentifier(type: 'bvn', value: '22113344556', country: new Country('NG')),
        new IdentityIdentifier(type: 'nin', value: '11223344556', country: new Country('NG')),
    ]
);

$vaRequest = new VirtualAccountCreateRequest(
    reference: new Reference('va_req_100'),
    ownerKey: 'usr_4455',
    purpose: VirtualAccountPurpose::collection,
    usage: VirtualAccountUsage::reusable,
    customer: $customer
);

$provisionResult = $driver->createVirtualAccount($vaRequest);
echo $provisionResult->status->value; // "active" | "pending"
```

---

### 2.6 Balances, Double-Entry Ledgers &amp; Internal Transfers

[](#26-balances-double-entry-ledgers--internal-transfers)

Inspect balance snapshots, query double-entry accounting transactions, or move funds internally:

```
use PayKit\Payload\Requests\LedgerQuery;
use PayKit\Payload\Requests\TransferRequest;

// 1. Get Balance Snapshot
$balance = $driver->getBalance('bal_account_01');
echo $balance->balances->available->toArray()['amount']; // Cleared funds

// 2. Query Accounting Ledger Page
$ledgerPage = $driver->getLedger(new LedgerQuery(accountId: 'bal_account_01', limit: 20));

foreach ($ledgerPage->items as $transaction) {
    echo $transaction->direction->value; // "credit" | "debit"
    echo $transaction->type->value;      // "payment", "payout", "fee", "transfer"
    echo $transaction->bookedAt;         // Booking ISO timestamp
}

// 3. Internal Account Movement (No outward banking fees)
$transferResult = $driver->transfer(new TransferRequest(
    reference: new Reference('xfer_3322'),
    sourceAccountId: 'bal_01',
    destinationAccountId: 'bal_02',
    money: Money::from(500, 'USD')
));
```

---

### 2.7 Modular Virtual Cards &amp; Spending Controls

[](#27-modular-virtual-cards--spending-controls)

Provision virtual cards, update velocity/MCC controls, process JIT webhook authorizations, or request PCI-isolated card reveal sessions:

```
use PayKit\Payload\Common\CardControls;
use PayKit\Payload\Common\Currency;
use PayKit\Payload\Common\Money;
use PayKit\Payload\Common\Reference;
use PayKit\Payload\Requests\VirtualCardControlsRequest;
use PayKit\Payload\Requests\VirtualCardCreateRequest;

// 1. Issue Virtual Card
$card = $driver->createCard(new VirtualCardCreateRequest(
    reference: new Reference('card_req_01'),
    cardholderName: 'Alice Smith',
    currency: new Currency('USD'),
    controls: new CardControls(
        perTransactionLimit: Money::from(10000, 'USD'),
        dailyLimit: Money::from(50000, 'USD'),
        allowedMccs: ['5732', '5812']
    )
));

// 2. Freeze Card
$frozenCard = $driver->freezeCard($card->id);

// 3. Request PCI-isolated Reveal Token for PAN/CVV display
$revealSession = $driver->createCardRevealSession($card->id);
echo $revealSession->ephemeralToken; // Token used by frontend iframe
```

---

### 2.8 Webhook Event Deduplication

[](#28-webhook-event-deduplication)

Prevent duplicate business execution from third-party webhook retries using the framework-agnostic `WebhookDeduplicator`:

```
use PayKit\Support\ArrayEventLockStore;
use PayKit\Support\WebhookDeduplicator;

$deduplicator = new WebhookDeduplicator(new ArrayEventLockStore()); // Or host PSR-16 cache

$result = $deduplicator->executeOnce(
    driverKey: 'stripe',
    eventId: 'evt_3M2e512eZvKYlo2C0',
    callback: function () use ($orderId) {
        // Business logic runs exactly once
        Order::fulfill($orderId);
        return true;
    },
    ttlSeconds: 86400 // Lock for 24 hours
);
```

---

3) Canonical `src/` Layout Sitemap
----------------------------------

[](#3-canonical-src-layout-sitemap)

```
src/
  index.php
  Pay.php

  Contracts/
    # --- base / discovery ---
    PaymentGatewayDriverContract.php
    PaymentGatewayManifestProviderContract.php
    PaymentGatewayAvailabilityContract.php
    PaymentGatewayRequirementsContract.php
    ProvidesGatewayConfigContract.php
    ProvidesGatewayErrorLogContract.php
    ProvidesGatewayInfoContract.php
    EvaluatesGatewayVisibilityContract.php

    # --- core payments & webhooks ---
    PaymentGatewayPaymentsContract.php
    PaymentGatewayPaymentStatusMapperContract.php
    PaymentGatewayVerificationContract.php
    PaymentGatewayWebhooksContract.php

    # --- saved methods & tokenization ---
    PaymentGatewaySavedMethodsContract.php
    PaymentGatewayCardTokenizationContract.php

    # --- refunds & disputes ---
    PaymentGatewayRefundsContract.php
    PaymentGatewayDisputesContract.php

    # --- virtual accounts & watchers ---
    PaymentGatewayVirtualAccountsContract.php
    PaymentGatewayVirtualAccountWebhookWatcherContract.php
    PaymentGatewayVirtualAccountPollingWatcherContract.php
    PaymentGatewayVirtualAccountReconcileContract.php
    PaymentGatewayInboundTransferApprovalContract.php

    # --- payouts & bulk transfers ---
    PaymentGatewayPayoutsContract.php
    PaymentGatewayBulkPayoutsContract.php
    PaymentGatewayPayoutDestinationResolverContract.php
    PaymentGatewayPayoutMethodsContract.php
    PaymentGatewayBeneficiariesContract.php

    # --- balances, ledger & transfers ---
    PaymentGatewayBalancesContract.php
    PaymentGatewayLedgerContract.php
    PaymentGatewayTransfersContract.php

    # --- virtual cards issuing suite ---
    PaymentGatewayCardIssuingContract.php
    PaymentGatewayCardManagementContract.php
    PaymentGatewayCardControlsContract.php
    PaymentGatewayCardTransactionsContract.php
    PaymentGatewayCardAuthorizationWatcherContract.php
    PaymentGatewayCardSensitiveDetailsContract.php

    # --- reconciliation & diagnostics ---
    PaymentGatewayReconcileContract.php
    PaymentGatewayDiagnosticsContract.php
    PaymentGatewayScriptsContract.php
    PaymentGatewayUiContract.php
    PaymentGatewayFrontendConfigContract.php

  Payload/
    Common/
      # primitives & enums
      Money.php
      Amount.php
      Currency.php
      Country.php
      Reference.php
      ProviderRef.php
      Metadata.php
      IdempotencyKey.php
      GatewayFailure.php
      CanonicalPaymentStatus.php
      CanonicalPayoutStatus.php
      CanonicalRefundStatus.php
      VirtualAccountPurpose.php
      VirtualAccountUsage.php
      VirtualAccountStatus.php
      BeneficiaryStatus.php
      VirtualCardStatus.php
      AccountTransactionDirection.php
      AccountTransactionType.php
      PayoutSourceType.php
      InboundTransferDecision.php

      # compliance & identity
      CustomerIdentity.php
      IdentityIdentifier.php

      # payout destinations
      PayoutDestinationPayload.php
      PayoutDestination.php
      BankAccountDestination.php
      MobileMoneyDestination.php
      WalletDestination.php
      CardDestination.php
      CryptoDestination.php
      BeneficiaryDestination.php
      ProviderBalanceDestination.php
      PayoutSource.php
      BulkPayoutItem.php

      # balances, ledger & cards
      BalanceAmount.php
      BalanceAccount.php
      AccountTransaction.php
      VirtualCardRecord.php
      CardControls.php
      Beneficiary.php
      SavedMethod.php
      CardSummary.php
      CardBrand.php
      CardFingerprint.php

      # manifest & capabilities
      GatewayManifest.php
      GatewayFeatureSet.php
      GatewaySupportMatrix.php
      SupportedCurrency.php
      SupportedCountry.php
      GatewayRequirements.php

    Requests/
      PaymentInitiateRequest.php
      PaymentVerifyRequest.php
      PayoutRequest.php
      PayoutVerifyRequest.php
      BulkPayoutRequest.php
      BulkPayoutVerifyRequest.php
      PayoutDestinationResolveRequest.php
      VirtualAccountCreateRequest.php
      VirtualAccountGetRequest.php
      ListVirtualAccountsRequest.php
      InboundTransferDecisionRequest.php
      LedgerQuery.php
      TransferRequest.php
      VirtualCardCreateRequest.php
      VirtualCardGetRequest.php
      ListVirtualCardsRequest.php
      VirtualCardStatusUpdateRequest.php
      VirtualCardControlsRequest.php
      BeneficiaryCreateRequest.php
      BeneficiaryUpdateRequest.php
      RefundRequest.php
      RefundVerifyRequest.php
      DisputeQuery.php

    Responses/
      PaymentInitiateResult.php
      PaymentVerifyResult.php
      PayoutResult.php
      PayoutStatusResult.php
      BulkPayoutResult.php
      PayoutDestinationResolveResult.php
      VirtualAccountProvisionResult.php
      VirtualAccountRecord.php
      VirtualAccountList.php
      InboundTransferDecisionResult.php
      LedgerPage.php
      TransferResult.php
      CardRevealSessionResult.php
      BeneficiaryCreateResult.php
      BeneficiaryUpdateResult.php
      BeneficiaryList.php

  Support/
    WebhookDeduplicator.php
    EventLockStoreInterface.php
    ArrayEventLockStore.php

```

---

4) Driver Implementation Guide
------------------------------

[](#4-driver-implementation-guide)

To create a new PayKit driver (e.g. `PayKitStripeDriver`):

1. Extend `AbstractPaymentGatewayDriver` (or implement `PaymentGatewayDriverContract`).
2. Implement capability interfaces for features your provider supports:

```
use PayKit\Contracts\PaymentGatewayCardIssuingContract;
use PayKit\Contracts\PaymentGatewayManifestProviderContract;
use PayKit\Contracts\PaymentGatewayPayDriverContract;
use PayKit\Contracts\PaymentGatewayPayoutsContract;
use PayKit\Drivers\AbstractPaymentGatewayDriver;

final class StripeDriver extends AbstractPaymentGatewayDriver implements
    PaymentGatewayPayDriverContract,
    PaymentGatewayPayoutsContract,
    PaymentGatewayCardIssuingContract,
    PaymentGatewayManifestProviderContract
{
    public function driverKey(): string
    {
        return 'stripe';
    }

    // Implement contract methods accepting DTOs and returning response DTOs
}
```

3. Register your driver with `Pay`:

```
Pay::register('stripe', StripeDriver::class);
```

---

📄 License
---------

[](#-license)

The PayKit Gateway SDK is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance82

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

10

Last Release

203d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/105345335?v=4)[David Okpako](/maintainers/timeax)[@timeax](https://github.com/timeax)

---

Top Contributors

[![timeax](https://avatars.githubusercontent.com/u/105345335?v=4)](https://github.com/timeax "timeax (45 commits)")

---

Tags

contractssdkpaymentsdtopayment gateway

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/timeax-paykit-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/timeax-paykit-sdk/health.svg)](https://phpackages.com/packages/timeax-paykit-sdk)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
