SDK-SPEC-TYPESCRIPT — TypeScript/Node.js SDK Specification¶
Status: Draft
Owner: Platform Engineering
Package: @simpaisa/sdk
Runtime: Node.js 18+ / Bun 1.x
Last Updated: 2026-04-03
1. Overview¶
Official TypeScript SDK for the Simpaisa Payment Gateway. Provides typed access to Pay-Ins, Pay-Outs, Remittances, and Cards across PK, BD, NP, and IQ corridors. Powers 270M+ annual transactions at $1B+ volume. Published to npm as @simpaisa/sdk.
2. Package Structure¶
@simpaisa/sdk/
├── src/
│ ├── index.ts # Re-exports all public modules
│ ├── client.ts # SimPaisaClient class
│ ├── config.ts # Configuration types and defaults
│ ├── payin/
│ │ ├── index.ts # PayIn module (initiate, verify, status, list)
│ │ └── types.ts # PayIn request/response types
│ ├── payout/
│ │ ├── index.ts # PayOut module (initiate, status, batch, cancel)
│ │ └── types.ts
│ ├── remittance/
│ │ ├── index.ts # Remittance module (quote, initiate, status, beneficiaries)
│ │ └── types.ts
│ ├── cards/
│ │ ├── index.ts # Cards module (pay, capture, void, refund, tokenise)
│ │ └── types.ts
│ ├── webhooks/
│ │ ├── index.ts # WebhookVerifier class
│ │ └── types.ts
│ ├── auth/
│ │ ├── rsa-auth-provider.ts # RSAAuthProvider — loads PEM, signs requests
│ │ └── types.ts
│ ├── errors/
│ │ └── index.ts # SimPaisaError hierarchy
│ ├── retry/
│ │ └── index.ts # RetryPolicy with exponential backoff
│ ├── idempotency/
│ │ └── index.ts # IdempotencyKeyGenerator (UUID v7)
│ └── generated/
│ └── models.ts # Auto-generated from OpenAPI spec
├── package.json
├── tsconfig.json
└── vitest.config.ts
3. Exported Modules¶
The top-level export SHALL provide:
SimPaisaClient— main entry point; constructs sub-clientsPayIn— pay-in operationsPayOut— pay-out operationsRemittance— remittance operationsCards— card payment operationsWebhookVerifier— HMAC-SHA256 webhook signature verificationRSAAuthProvider— RSA request signingIdempotencyKeyGenerator— generates idempotent request keysSimPaisaError,AuthenticationError,ValidationError,RateLimitError,TimeoutError
4. Authentication — RSAAuthProvider¶
- Load merchant private key from PEM file path or string
- Sign each outbound request body with RSA-SHA256
- Attach signature in
X-Simpaisa-Signatureheader - Attach merchant ID in
X-Simpaisa-Merchant-Idheader - Key rotation: accept array of keys, sign with latest, verify with any
const auth = new RSAAuthProvider({
merchantId: 'MCH-001',
privateKeyPath: './keys/merchant.pem',
});
5. IdempotencyKeyGenerator¶
- Generate UUID v7 (time-ordered) keys by default
- Accept custom generator function via constructor
- Automatically attach
Idempotency-Keyheader on mutating requests (POST/PUT/PATCH)
6. WebhookVerifier¶
- Verify
X-Simpaisa-Webhook-Signatureheader using HMAC-SHA256 - Accept webhook secret via constructor
verify(payload: string | Buffer, signature: string): boolean- Reject replays: validate
X-Simpaisa-Webhook-Timestampwithin configurable tolerance (default 300s) - Throw
WebhookVerificationErroron failure
7. RetryPolicy¶
- Exponential backoff with jitter (base 200ms, max 30s)
- Configurable max retries (default 3)
- Retry on: 429 (rate limit), 502, 503, 504, network errors
- Never retry: 400, 401, 403, 404, 409, 422
- Respect
Retry-Afterheader when present - Expose
onRetrycallback for observability
8. Error Handling¶
SimPaisaError (base)
├── AuthenticationError — 401/403 responses
├── ValidationError — 400/422 with field-level details
├── RateLimitError — 429 with retryAfter
├── TimeoutError — request/connection timeout
├── IdempotencyError — conflicting idempotency key
├── NetworkError — connection/DNS failures
└── WebhookVerificationError — signature mismatch
All errors include: code, message, statusCode, requestId, retryable.
9. Type Definitions¶
- Auto-generated from the canonical OpenAPI 3.1 specification using
openapi-typescript - Generated types placed in
src/generated/models.ts - Re-exported with SDK-friendly aliases (e.g.,
PayInRequest,PayOutResponse) - CI pipeline regenerates on OpenAPI spec changes
10. Configuration¶
const client = new SimPaisaClient({
environment: 'sandbox', // 'sandbox' | 'production'
merchantId: 'MCH-001',
privateKeyPath: './keys/merchant.pem',
timeout: 30_000, // ms, default 30s
retries: 3, // default 3
idempotencyKeyGenerator: customGenerator, // optional
logger: customLogger, // optional, pino-compatible
});
11. Example Usage¶
import { SimPaisaClient } from '@simpaisa/sdk';
const client = new SimPaisaClient({
environment: 'sandbox',
merchantId: 'MCH-001',
privateKeyPath: './keys/merchant.pem',
});
// Pay-In
const payIn = await client.payIn.initiate({
amount: 5000,
currency: 'PKR',
channel: 'EASYPAISA',
customerMsisdn: '03001234567',
callbackUrl: 'https://merchant.com/webhook',
});
// Pay-Out
const payOut = await client.payOut.initiate({
amount: 10000,
currency: 'BDT',
beneficiaryAccount: '1234567890',
beneficiaryBank: 'BRAC',
});
// Webhook verification
import { WebhookVerifier } from '@simpaisa/sdk';
const verifier = new WebhookVerifier({ secret: process.env.WEBHOOK_SECRET });
const isValid = verifier.verify(rawBody, signatureHeader);
12. Build and Publish¶
- Bundler: tsup (ESM + CJS dual output)
- Test runner: Vitest
- Linting: Biome
- CI: Bitbucket Pipelines — lint → test → build → publish
- Publish: npm with provenance (
--provenanceflag) - Versioning: Semantic versioning; breaking changes in major only
- Minimum bundle: tree-shakeable; zero runtime dependencies beyond
node:crypto
13. Compatibility¶
- Node.js 18, 20, 22 (LTS releases)
- Bun 1.x
- TypeScript 5.0+
- ESM and CommonJS consumers
- Must not pull in browser-specific APIs
14. 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 simulated failures
15. Documentation¶
- TSDoc comments on all exported types and functions
- Auto-generated API reference via TypeDoc
- README with quickstart, authentication setup, and corridor-specific examples
- CHANGELOG following Keep a Changelog format