Core Concepts
A look at the ideas that shape PayKit's design — the adapter pattern, unified types, server/client separation, provider routing, webhook normalisation, and the open-core licensing model.
The Adapter Pattern
At its core, PayKit is a thin orchestration layer that delegates every provider-specific call to an adapter. Your application talks to PayKit; PayKit talks to the adapter; the adapter talks to the provider SDK.
This gives you three concrete benefits:
- Write once — your charge-creation, webhook, and checkout code is identical regardless of provider.
- Swap providers — change a single adapter import and the rest of your codebase stays untouched.
- Test with mocks — inject a mock adapter in your test suite to verify business logic without hitting any external API.
Unified Types
Every adapter maps provider responses into a shared set of TypeScript interfaces. The most important one is UnifiedCharge:
The _raw field is an escape hatch. If you need something provider-specific that PayKit does not normalise, you can cast _raw to the provider's native type and access it directly. This keeps the unified interface clean while still giving you full access when you need it.
Server vs Client Code
PayKit separates server-side and client-side adapters into different entry points. This is important for two reasons: security and bundle size.
Server-side adapters
Server adapters hold your secret key and must never be imported in browser code. They handle charge creation, refunds, and webhook verification.
Client-side adapters
Client adapters contain only the browser-safe code needed to confirm payments and render checkout UIs. They use your publishable key.
Because these are separate entry points, your bundler can tree-shake them independently. The server adapter and its dependencies will never end up in your client bundle, and vice-versa. This keeps your frontend lean and your secrets safe.
Provider Routing
If you accept payments in multiple currencies or regions, you can use PaymentRouter to automatically select the best adapter for each transaction.
Each route can also include region and condition properties for more advanced matching. Routes are evaluated in order; the first match wins. If nothing matches, the default adapter handles the charge.
Webhook Normalisation
Different providers send different event names and payload shapes. PayKit maps them into a single set of event types so your handler code does not need provider-specific branches.
| PayKit Event | Stripe Event | Razorpay Event |
|---|---|---|
payment.succeeded | payment_intent.succeeded | payment.captured |
payment.failed | payment_intent.payment_failed | payment.failed |
refund.created | charge.refunded | refund.processed |
Your webhook handler always receives the same shape regardless of which provider fired the event:
Open Core Model
PayKit follows an open-core licensing model. The free tier covers everything you need to start accepting payments:
- Charge creation and confirmation
- Webhook verification and normalisation
- All provider adapters (Stripe, Razorpay, and more)
- React checkout components
PayKit Pro extends the free adapters with advanced features for teams that need more:
- Refund management
- Payouts
- Subscription lifecycle
- Pre-built analytics dashboards
Pro will be available as a one-time purchase — no recurring fees. It is coming soon.