Introducing PayKit: One API for Every Payment Provider
Every payment provider has its own SDK, its own types, its own webhook format, and its own quirks. If your app supports more than one — say Stripe for the US and Razorpay for India — you end up maintaining two completely separate integrations. Different charge flows, different refund APIs, different webhook payloads. Your "payment layer" becomes a sprawling mess of provider-specific branches.
PayKit fixes this. It gives you a single, type-safe API that works identically across providers. Write your charge-creation, webhook, and checkout code once. Swap providers by changing one import.
The problem
Here's what multi-provider payment code typically looks like without an abstraction layer:
Every new provider doubles the surface area. Every webhook handler needs provider-specific parsing. Your tests need mocks for each SDK. It doesn't scale.
The PayKit approach
PayKit sits between your application and the provider SDKs. It uses the adapter pattern — each provider gets an adapter that maps its native API to PayKit's unified interface.
Your App → PayKit Core → Stripe Adapter → Stripe API
→ Razorpay Adapter → Razorpay API
→ PayPal Adapter → PayPal API
The same charge code works regardless of which adapter you plug in:
Switch to Razorpay? Change one line:
Unified types
Every adapter maps provider responses into shared TypeScript interfaces. The most important one is UnifiedCharge:
The _raw field is there for advanced use cases. If you need something PayKit doesn't normalise, cast _raw to the provider's native type and access it directly.
Webhook normalisation
Different providers send different event names. Stripe fires payment_intent.succeeded. Razorpay fires payment.captured. PayKit maps them into a single set of event types:
| PayKit Event | Stripe | Razorpay |
|---|---|---|
payment.succeeded | payment_intent.succeeded | payment.captured |
payment.failed | payment_intent.payment_failed | payment.failed |
refund.created | charge.refunded | refund.processed |
Your webhook handler is always the same shape:
Frontend support
PayKit ships with React components and a headless vanilla JS SDK for collecting payments in the browser:
Server adapters and client adapters are separate entry points, so your bundler tree-shakes them independently. Your secret key never ends up in the client bundle.
What ships today
@squaredr/paykit— Core SDK with unified types, adapter system, and subpath exports for all adapters@squaredr/paykit/stripe— Stripe adapter (charges, refunds, customers, subscriptions, webhooks)@squaredr/paykit/razorpay— Razorpay adapter (charges, refunds, customers, subscriptions, UPI, webhooks)@squaredr/paykit-react— React components and hooks@squaredr/paykit-js— Vanilla JS/TS frontend SDK
All packages are MIT-licensed and published on npm. Install and start accepting payments:
What's next
PayPal is next, followed by PhonePe, Cashfree, Square, Adyen, and more — one or two new providers every week. The goal is 25 provider adapters within 11 weeks.
PayKit Pro (coming soon) will extend the free adapters with refund management, payouts, subscription lifecycle, and analytics dashboards. It will be available as a one-time purchase — no recurring fees.
Get started
Give it a try and let us know what you think. Open an issue if you hit anything, or star the repo if you find it useful.