pk-pay
v0.4.0
Published
Unified TypeScript SDK for Pakistani payments — JazzCash, EasyPaisa, and Stripe in one API
Maintainers
Readme
pk-pay
Unified TypeScript SDK for Pakistani payments — JazzCash, EasyPaisa, and Stripe in one API.
One install. One API shape. Built for flexibility, security, and developer productivity.
📑 Table of Contents
- Features
- Installation
- Quick Start
- Dynamic Plugin Architecture
- Environment Support
- Middleware Helpers
- Documentation Index
- Security Features
- Contributing
- License
⚡ Features
- ✅ Unified API — Create payments and verify webhooks for multiple providers with one shape.
- ✅ Plugin-Based — Register any custom provider via the registry.
- ✅ Stripe Multi-Currency — Full support for 135+ currencies (USD, SAR, EUR, etc.).
- ✅ Framework Friendly — Pre-built middleware for Express, Fastify, and Next.js.
- ✅ Type Safe — First-class TypeScript support with deep Zod validation.
✅ Verification status
Every adapter implements its gateway's published specification and is covered by unit tests, including signature generation and rejection of tampered webhooks.
None have been exercised against live merchant credentials. JazzCash and EasyPaisa both require Pakistani merchant onboarding, and Stripe does not operate in Pakistan. Treat the adapters as spec-complete rather than production-proven, and run your own sandbox transaction before going live.
| Provider | Written against | Live-verified |
|---|---|---|
| JazzCash | HTTP POST v2.0 (sandbox docs) | Not yet |
| EasyPaisa | Merchant Integration Guide — Legacy HMAC + REST RSA | Not yet |
| Stripe | API 2026-08-26.dahlia | Not yet |
🚀 Quick Start
See it work before you install it: Payment Signing Lab → Watch a request get signed, then tamper with a callback and see verification reject it. Real HMAC-SHA256, no keys, no gateway contacted.
Already have credentials? The Interactive Playground tests the SDK against your own API keys.
🛠️ Installation
npm install pk-pay
# For Stripe support (optional):
npm install stripe🚀 Quick Start
1. Configure
import { configure } from 'pk-pay';
configure({
environment: 'sandbox', // 'production', 'staging', or any custom string
maxRetries: 3,
jazzcash: {
merchantId: '...',
password: '...',
integritySalt: '...',
},
easypaisa: {
method: 'rest', // or 'legacy'
storeId: '...',
username: '...',
password: '...',
privateKey: '...',
},
stripe: {
secretKey: '...',
webhookSecret: '...', // optional
},
});2. Create Payment
import { createPayment } from 'pk-pay';
const payment = await createPayment({
provider: 'jazzcash',
amount: 250000, // always the smallest unit — 250000 paisa = Rs 2,500.00
currency: 'PKR',
description: 'Pro Plan',
returnUrl: 'https://yourapp.com/payment/callback',
customerPhone: '03001234567',
});
// Securely redirect:
if (payment.redirectForm) {
res.send(payment.redirectForm); // For JazzCash/EasyPaisa POST forms
} else {
res.redirect(payment.redirectUrl!); // For Stripe/Custom GET redirects
}🛠️ Middleware Helpers
pk-pay provides ready-to-use handlers for popular frameworks to handle webhooks effortlessly.
Express
import { createWebhookMiddleware } from 'pk-pay';
app.post('/webhook/jazzcash', createWebhookMiddleware('jazzcash'));Fastify
import { pkPayWebhookPlugin } from 'pk-pay';
fastify.register(pkPayWebhookPlugin, { provider: 'easypaisa' });Next.js (App Router)
import { createNextWebhookHandler } from 'pk-pay/middleware/nextjs';
export const POST = createNextWebhookHandler('stripe');📖 Documentation Index
For detailed guides, architecture, and security practices, see the nested documentation:
📱 Provider Setup Guide
Detailed configuration for JazzCash (v2.0), EasyPaisa (Legacy/REST RSA), and Stripe (Dahlia).
🏗️ Architecture & Code Standards
Deep dive into the Adapter Pattern, Timing-Safe Sanitization, and Security Hardening.
🛠️ Middleware Helpers
Quick integration for Express, Fastify, and Next.js.
🧩 Plugins & Custom Providers
pk-pay is built on a dynamic registry. You can add support for any payment gateway without modifying the core library:
import { registerProvider, configure, createPayment } from 'pk-pay';
// 1. Implement your own provider adapter
class MyBankAdapter {
constructor(private config: any) {}
async createPayment(req) { /* logic */ }
async verifyWebhook(payload, sig) { /* logic */ }
}
// 2. Register it
registerProvider('my_bank', MyBankAdapter);
// 3. Configure it
configure({
my_bank: { apiKey: 'secret-key' }
});
// 4. Use it!
await createPayment({ provider: 'my_bank', ... });🛡️ Security Features
- ✅ Timing-Safe — All HMAC/RSA verifications are timing-attack resistant.
- ✅ Auto-Sanitized — Raw provider responses automatically redact sensitive keys.
- ✅ Dynamic Redaction — Extend redaction via
DEFAULT_SENSITIVE_KEYS. - ✅ Version Pinned — Defaulting to the latest 2024/2025 API standards.
🤝 Contributing
See CONTRIBUTING.md.
📄 License
MIT © Junaid Shahzad
