Documentation Index
Fetch the complete documentation index at: https://docs.paymint.dev/llms.txt
Use this file to discover all available pages before exploring further.
@paymint/react
React hooks for Paymint billing.
Installation
npm install @paymint/react
Note: For Next.js apps, use @paymint/nextjs instead - it includes everything from this package plus server utilities.
Quick Start
1. Set up Provider
import { PaymintProvider } from '@paymint/react';
function App() {
return (
<PaymintProvider
apiRoute="/api/billing" // Your backend API route
customerEmail="user@example.com" // Current user's email
onCheckoutComplete={(txnId) => {
// Handle successful checkout
window.location.href = `/success?txn=${txnId}`;
}}
>
<YourApp />
</PaymintProvider>
);
}
2. Use Hooks
import { useBilling, useCheckout } from '@paymint/react';
function PricingPage() {
const { products, subscription, loading, hasActiveSubscription } = useBilling();
const { openCheckout, ready } = useCheckout();
if (loading) return <div>Loading...</div>;
if (hasActiveSubscription) {
return <div>Current plan: {subscription.productName}</div>;
}
return (
<div>
{products.map(product => (
<div key={product.id}>
<h2>{product.name}</h2>
{product.prices.map(price => (
<button
key={price.id}
onClick={() => openCheckout(price.id)}
disabled={!ready}
>
${price.unitPrice.amount / 100}/{price.billingCycle.interval}
</button>
))}
</div>
))}
</div>
);
}
Hooks
useBilling()
Combined billing data (products + subscription).
const {
products, // Product[]
subscription, // Subscription | null
loading, // boolean
error, // Error | null
refresh, // () => Promise<void>
hasActiveSubscription, // boolean
isOnTrial, // boolean
} = useBilling();
useProducts()
Available products only.
const {
products, // Product[]
loading, // boolean
error, // Error | null
refresh, // () => Promise<void>
} = useProducts();
useSubscription()
Subscription management.
const {
subscription, // Subscription | null
loading, // boolean
hasActiveSubscription, // boolean
isOnTrial, // boolean
isPaused, // boolean
isCanceling, // boolean
cancel, // (options?) => Promise<void>
pause, // (options?) => Promise<void>
resume, // () => Promise<void>
isMutating, // boolean
} = useSubscription();
// Cancel at end of billing period
await cancel({ effectiveFrom: 'next_billing_period' });
// Pause subscription
await pause({ effectiveFrom: 'next_billing_period' });
// Resume paused subscription
await resume();
useCheckout()
Paddle checkout integration.
const {
ready, // boolean - checkout is ready
loading, // boolean - initializing
openCheckout, // (priceId | options) => void
closeCheckout, // () => void
error, // Error | null
} = useCheckout();
// Simple
openCheckout('pri_xxx');
// With options
openCheckout({
items: [{ priceId: 'pri_xxx', quantity: 1 }],
discountCode: 'SAVE20',
settings: {
theme: 'dark',
successUrl: '/checkout/success',
},
});
Provider Props
<PaymintProvider
apiRoute="/api/billing" // Required: your backend route
customerEmail="user@example.com" // Customer email
autoLoadProducts={true} // Auto-fetch products (default: true)
autoLoadSubscription={true} // Auto-fetch subscription (default: true)
onCheckoutComplete={(txnId) => {}} // Checkout success callback
onCheckoutClose={() => {}} // Checkout closed callback
>
Post-Checkout Success Handling
Option 1: onCheckoutComplete Callback
<PaymintProvider
apiRoute="/api/billing"
customerEmail={email}
onCheckoutComplete={(transactionId) => {
// Redirect to success page
window.location.href = `/checkout/success?txn=${transactionId}`;
}}
>
Option 2: Paddle’s successUrl
openCheckout({
items: [{ priceId: 'pri_xxx' }],
settings: {
successUrl: '/checkout/success', // Paddle redirects here
},
});
Note: Subscriptions are created via webhooks. There may be a 1-5 second delay between payment and subscription appearing in the database.
Backend Required
This package requires a backend API that proxies to Paymint. The provider calls:
GET {apiRoute}/products → List products
GET {apiRoute}/subscriptions → Get subscriptions
POST {apiRoute}/initialize → Initialize checkout
POST {apiRoute}/cancel/{id} → Cancel subscription
POST {apiRoute}/pause/{id} → Pause subscription
POST {apiRoute}/resume/{id} → Resume subscription
Use @paymint/server or @paymint/nextjs to create these endpoints.
Security
Backend Developer Responsibilities
When creating your backend API route, ensure:
1. Get Email from Auth Session (CRITICAL)
// ✅ CORRECT - Email from authenticated session
const email = session.user.email; // From your auth system
// ❌ WRONG - Email from request body
const { email } = req.body; // Attacker can impersonate any user!
2. Keep API Key Server-Side
// ✅ CORRECT
const paymint = new PaymintServer({
apiKey: process.env.PAYMINT_API_KEY, // Server-side only
});
// ❌ WRONG
apiKey: process.env.NEXT_PUBLIC_API_KEY, // Exposed to client!
What Paymint Handles
- API key encryption
- Subscription ownership verification
- Paddle API security
- Webhook signature verification
What Your Backend Must Handle
- Authenticate users before billing operations
- Get email from auth session (not request body)
- Keep API key server-side only
License
MIT