Skip to content

SDK-SPEC-PHP — PHP SDK Specification

Status: Draft Owner: Platform Engineering Package: simpaisa/sdk Runtime: PHP 8.1+ Last Updated: 2026-04-03


1. Overview

Official PHP SDK for the Simpaisa Payment Gateway. Provides typed access to Pay-Ins, Pay-Outs, Remittances, and Cards across PK, BD, NP, and IQ corridors. Handles 270M+ annual transactions at $1B+ volume. Published to Packagist as simpaisa/sdk.

2. Composer Configuration

{
    "name": "simpaisa/sdk",
    "require": {
        "php": "^8.1",
        "guzzlehttp/guzzle": "^7.0",
        "psr/http-client": "^1.0"
    }
}

3. Namespace Structure

simpaisa/sdk/
├── src/
│   ├── SimPaisaClient.php          # Main client entry point
│   ├── Config.php                  # Configuration value object
│   ├── PayIn/
│   │   ├── PayInClient.php         # initiate, verify, status, list
│   │   ├── PayInRequest.php
│   │   └── PayInResponse.php
│   ├── PayOut/
│   │   ├── PayOutClient.php        # initiate, status, batch, cancel
│   │   ├── PayOutRequest.php
│   │   └── PayOutResponse.php
│   ├── Remittance/
│   │   ├── RemittanceClient.php    # quote, initiate, status, beneficiaries
│   │   ├── RemittanceRequest.php
│   │   └── RemittanceResponse.php
│   ├── Cards/
│   │   ├── CardsClient.php         # pay, capture, void, refund, tokenise
│   │   ├── CardPaymentRequest.php
│   │   └── CardPaymentResponse.php
│   ├── Webhook/
│   │   ├── WebhookVerifier.php     # HMAC-SHA256 verification
│   │   └── WebhookEvent.php
│   ├── Auth/
│   │   ├── RSAAuthProvider.php     # RSA-SHA256 request signing
│   │   └── AuthProviderInterface.php
│   ├── Exception/
│   │   ├── SimPaisaException.php   # Base exception
│   │   ├── AuthenticationException.php
│   │   ├── ValidationException.php
│   │   ├── RateLimitException.php
│   │   └── WebhookVerificationException.php
│   ├── Retry/
│   │   └── RetryPolicy.php        # Exponential backoff
│   ├── Idempotency/
│   │   └── IdempotencyKeyGenerator.php  # UUID v7
│   └── Generated/
│       └── Models/                 # OpenAPI-generated models
├── tests/
├── composer.json
└── phpstan.neon

Namespace root: Simpaisa\

4. Authentication — RSAAuthProvider

  • Load merchant private key from PEM file via openssl_pkey_get_private()
  • Sign request body with RSA-SHA256 via openssl_sign()
  • Attach X-Simpaisa-Signature and X-Simpaisa-Merchant-Id headers
  • Requires ext-openssl
  • Support key rotation via array of key paths
$auth = new RSAAuthProvider(
    merchantId: 'MCH-001',
    privateKeyPath: './keys/merchant.pem',
);

5. WebhookVerifier

  • Verify X-Simpaisa-Webhook-Signature using HMAC-SHA256 via hash_hmac()
  • verify(string $payload, string $signature): bool
  • Timing-safe comparison via hash_equals()
  • Replay protection: validate timestamp header within tolerance (default 300s)
  • Throw WebhookVerificationException on failure

6. RetryPolicy

  • Exponential backoff with jitter (base 200ms, max 30s)
  • Configurable max retries (default 3)
  • Retry on: 429, 502, 503, 504, connection errors
  • Never retry: 400, 401, 403, 404, 409, 422
  • Respect Retry-After header
  • onRetry callback for observability

7. Error Handling

SimPaisaException (base, extends \RuntimeException)
├── AuthenticationException     — 401/403 responses
├── ValidationException         — 400/422 with field-level details
├── RateLimitException          — 429 with retryAfter
├── TimeoutException            — request/connection timeout
├── IdempotencyException        — conflicting idempotency key
├── NetworkException            — connection/DNS failures
└── WebhookVerificationException — signature mismatch

All exceptions include: getErrorCode(), getStatusCode(), getRequestId(), isRetryable().

8. PSR-18 Compatibility

  • SDK SHALL implement PSR-18 (HTTP Client) interface
  • Default: Guzzle 7.x as transport
  • Merchants MAY inject any PSR-18 compatible client
  • PSR-7 (HTTP Message) for request/response objects
  • PSR-17 (HTTP Factories) for message creation
$client = new SimPaisaClient(
    config: $config,
    httpClient: $customPsr18Client,
);

9. Laravel Service Provider

  • SimPaisaServiceProvider auto-discovered via extra.laravel.providers
  • Publishes config: php artisan vendor:publish --tag=simpaisa-config
  • Config file: config/simpaisa.php
  • Facade: Simpaisa::payIn()->initiate(...)
  • Binds SimPaisaClient as singleton in container
  • Reads credentials from .env: SIMPAISA_MERCHANT_ID, SIMPAISA_PRIVATE_KEY_PATH, SIMPAISA_ENVIRONMENT
// config/simpaisa.php
return [
    'environment' => env('SIMPAISA_ENVIRONMENT', 'sandbox'),
    'merchant_id' => env('SIMPAISA_MERCHANT_ID'),
    'private_key_path' => env('SIMPAISA_PRIVATE_KEY_PATH'),
    'timeout' => 30,
    'retries' => 3,
];

10. Configuration

$client = new SimPaisaClient(
    config: new Config(
        environment: 'sandbox',          // 'sandbox' | 'production'
        merchantId: 'MCH-001',
        privateKeyPath: './keys/merchant.pem',
        timeout: 30,                     // seconds, default 30
        retries: 3,                      // default 3
    ),
);

11. Example Usage

use Simpaisa\SimPaisaClient;
use Simpaisa\Config;

$client = new SimPaisaClient(
    config: new Config(
        environment: 'sandbox',
        merchantId: 'MCH-001',
        privateKeyPath: './keys/merchant.pem',
    ),
);

// Pay-In
$payIn = $client->payIn()->initiate(
    amount: 5000,
    currency: 'PKR',
    channel: 'EASYPAISA',
    customerMsisdn: '03001234567',
    callbackUrl: 'https://merchant.com/webhook',
);

// Webhook
$verifier = new \Simpaisa\Webhook\WebhookVerifier(secret: 'whsec_...');
$valid = $verifier->verify($rawBody, $signatureHeader);

12. Build and Publish

  • Test runner: PHPUnit 10+
  • Static analysis: PHPStan level 9
  • Linting: PHP-CS-Fixer (PSR-12)
  • CI: Bitbucket Pipelines — lint → analyse → test → publish
  • Publish: Packagist (auto-updated via webhook)
  • Versioning: Semantic versioning
  • PHP compatibility: Tested on 8.1, 8.2, 8.3, 8.4

13. Testing Requirements

  • Unit tests for every public method (>90% coverage)
  • Integration tests against sandbox environment
  • Contract tests validating against OpenAPI spec
  • Webhook verification round-trip tests
  • Retry behaviour tests with mock handlers
  • Laravel service provider integration tests

14. Documentation

  • PHPDoc on all public classes and methods
  • README with quickstart, Laravel integration, and corridor-specific examples
  • CHANGELOG following Keep a Changelog format