Inline Checkout SDK
Embed a payment modal directly on your website. No backend required — the SDK handles session creation, payment collection, and status polling using your public API key.
Installation
Script tag (recommended)
<script src="https://js.zevpaycheckout.com/v1/inline.js"></script>npm
npm install @zevpay/inlineQuick start
<button id="pay-btn">Pay ₦5,000</button>
<script src="https://js.zevpaycheckout.com/v1/inline.js"></script>
<script>
document.getElementById('pay-btn').addEventListener('click', function() {
var checkout = new ZevPay.ZevPayCheckout();
checkout.checkout({
apiKey: 'pk_test_your_public_key',
email: 'customer@example.com',
amount: 500000, // ₦5,000 in kobo
currency: 'NGN',
reference: 'order_12345', // optional
firstName: 'John', // optional
lastName: 'Doe', // optional
onSuccess: function(reference) {
console.log('Payment successful:', reference);
// Verify payment on your server
},
onClose: function() {
console.log('Checkout closed');
},
});
});
</script>Configuration
checkout(options)
| Parameter | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Your public API key (pk_test_... or pk_live_...) |
email | string | Yes | Customer's email address |
amount | integer | Yes | Amount in kobo (e.g., 500000 = ₦5,000) |
currency | string | No | Currency code. Default: "NGN" |
reference | string | No | Your unique transaction reference. Auto-generated if not provided |
firstName | string | No | Customer's first name — stored as customer_name in the session |
lastName | string | No | Customer's last name — combined with firstName and displayed in dashboard |
metadata | object | No | Custom data attached to the transaction |
paymentMethods | string | string[] | No | Payment methods to enable. Default: all methods |
onInitialize | function | No | Called when session is created |
onSuccess | function | No | Called when payment is confirmed |
onError | function | No | Called when an error occurs |
onFailure | function | No | Called when payment fails |
onExpired | function | No | Called when session expires |
onClose | function | No | Called when modal is closed |
Payment methods
Control which payment methods are shown:
// All methods (default)
paymentMethods: 'all'
// Specific methods
paymentMethods: ['bank', 'payid']
// Single method (auto-selects, skips method picker)
paymentMethods: ['bank']| Method | Description |
|---|---|
'bank' | Bank transfer via virtual account |
'payid' | ZevPay ID (P2P transfer) |
'card' | Card payment (coming soon) |
Auto-selection
When only one payment method is enabled (except payid), the SDK automatically selects it and skips the method picker screen.
Metadata
Attach custom data to the transaction. This data is returned in webhooks and the verify endpoint:
checkout.checkout({
// ...
metadata: {
orderId: 'order_12345',
customerId: 'cust_789',
cartItems: ['item_a', 'item_b'],
},
});Callbacks
onInitialize()
Called when the checkout session has been created and the modal is ready.
onInitialize: function() {
console.log('Checkout ready');
}onSuccess(reference)
Called when payment is confirmed. The reference is the ZevPay transaction reference.
onSuccess: function(reference) {
console.log('Paid! Reference:', reference);
// IMPORTANT: Verify payment on your server
fetch('/api/verify-payment', {
method: 'POST',
body: JSON.stringify({ reference }),
});
}Always verify
Never trust the client-side callback alone. Always verify the payment on your server using the Verify Session endpoint.
onError(error)
Called when an error occurs (validation, network, API errors).
onError: function(error) {
console.error('Checkout error:', error.message);
// error.code is available for programmatic handling
}Error codes:
| Code | Description |
|---|---|
MISSING_FIELD | Required field not provided |
INVALID_INPUT | Invalid parameter value |
INVALID_CREDENTIALS | Invalid API key |
FORBIDDEN | Origin not allowed |
EXPIRED_SESSION | Session has expired |
SERVICE_UNAVAILABLE | API is temporarily unavailable |
TOO_MANY_REQUESTS | Rate limit exceeded |
onFailure(error)
Called when the payment itself fails (after method selection).
onFailure: function(error) {
console.error('Payment failed:', error?.message);
}onExpired()
Called when the session expires (30-minute timeout).
onExpired: function() {
alert('Session expired. Please try again.');
}onClose()
Called when the user closes the checkout modal.
onClose: function() {
console.log('User closed checkout');
}Full example
<!DOCTYPE html>
<html>
<head>
<title>ZevPay Inline Checkout Example</title>
</head>
<body>
<h1>Order Summary</h1>
<p>Total: ₦5,000.00</p>
<button id="pay-btn">Pay Now</button>
<script src="https://js.zevpaycheckout.com/v1/inline.js"></script>
<script>
document.getElementById('pay-btn').addEventListener('click', function() {
var checkout = new ZevPay.ZevPayCheckout();
checkout.checkout({
apiKey: 'pk_test_your_public_key',
email: 'customer@example.com',
amount: 500000,
currency: 'NGN',
reference: 'order_' + Date.now(),
firstName: 'John',
lastName: 'Doe',
metadata: {
orderId: '12345',
product: 'Premium Plan',
},
paymentMethods: ['bank', 'payid'],
onInitialize: function() {
console.log('Checkout initialized');
},
onSuccess: function(reference) {
alert('Payment successful! Reference: ' + reference);
// Verify on your server
window.location.href = '/order/success?ref=' + reference;
},
onError: function(error) {
console.error('Error:', error.message);
},
onFailure: function(error) {
alert('Payment failed. Please try again.');
},
onExpired: function() {
alert('Session expired. Please try again.');
},
onClose: function() {
console.log('Checkout closed');
},
});
});
</script>
</body>
</html>How it works
- User clicks your pay button
- SDK creates a checkout session via the API using your public key — no backend server needed
- Modal renders with available payment methods
- User selects a method and sees payment details (e.g., bank account number)
- User completes the transfer externally
- SDK polls for confirmation every 5 seconds
- Once confirmed,
onSuccessfires with the transaction reference - Modal auto-closes after 3 seconds
Domain whitelisting
The inline SDK sends your public key from the browser. To prevent unauthorized websites from using your key, configure allowed domains on your API key in the Dashboard.
When allowedDomains is configured, the API validates the origin of each request:
- Exact match:
mystore.com— only allows requests frommystore.com - Wildcard:
*.mystore.com— allowsshop.mystore.com,mystore.com, etc.
See Domain Whitelisting for full details.
Production recommendation
Always configure allowedDomains on your live public keys to prevent unauthorized usage.
Validation
The SDK validates inputs before making any API calls:
| Rule | Error |
|---|---|
apiKey is required | MissingRequiredField |
email is required | MissingRequiredField |
amount is required | MissingRequiredField |
amount must be ≥ 10,000 kobo (₦100) | InvalidInput |
currency must be "NGN" if provided | InvalidInput |
Resources
- API Reference — Full endpoint documentation
- Standard Checkout — Redirect-based alternative
- Webhook Events — All event types
- npm — Package registry