Quickstart
CoverPay is one checkout for Klarna, Affirm, Afterpay and Zip, smart-routed for each order, with CoverPay's own pay-in-4 filling in when no provider approves. It works like Plaid Link: your server creates a link token, your page or app opens Link with it, and your server exchanges the public token Link hands back.
Why a link token
The amount, order and customer live on the link token, created with your secret key. Nothing about the payment comes from the browser or the app, so it can't be changed there.
How it fits together
- 1Your server creates a link tokenPOST
/v1/link/token/createwith your secret key and the order amount from your own catalog. - 2Your page or app opens LinkWeb:
CoverPayLink.create({ token }).open(). React:useCoverPayLink. iOS:CoverPayLink.open(linkToken:). - 3The shopper picks a planCoverPay shows the offers it routed, the shopper approves with the provider, and Link calls onSuccess with a public token.
- 4Your server exchanges the public tokenPOST
/v1/link/public_token/exchangereturns the payment. Your webhook is the source of truth for whether it's paid.
1. Get your keys
In the dashboard, create a test key (cp_test_…). Keep it on your server. Test keys work only in sandbox; live keys (cp_live_…) only in production.
2. Create a link token (server)
Node
const res = await fetch('https://api.coverpayme.com/v1/link/token/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.COVERPAY_SECRET_KEY },
body: JSON.stringify({
amount: 12000, // cents, from YOUR catalog or cart, never from the client
currency: 'USD',
merchantName: 'My Store',
orderId: 'order_123', // your id; it comes back on the exchange and in webhooks
customerId: 'user_456',
customerEmail: 'buyer@example.com',
}),
});
const { link_token, expiration } = await res.json(); // link_token: "lt_test_…"3. Open Link (client)
Web
import { CoverPayLink } from '@coverpay/sdk';
const callbacks = {
onSuccess: (publicToken, metadata) => {
// POST publicToken to your server (step 4). metadata.provider: "klarna" | "affirm" | "afterpay" | "zip" | "coverpay"
},
onExit: (error, metadata) => {
// closed, cancelled (error null) or failed (error.code, error.message)
},
};
// Providers take over the whole page and then CoverPay sends the shopper back here: call once on load.
CoverPayLink.handleRedirect(callbacks);
const link = CoverPayLink.create({ token: linkToken, ...callbacks });
document.querySelector('#pay-later').addEventListener('click', () => link.open());React
import { useCoverPayLink } from '@coverpay/react';
const { open, ready } = useCoverPayLink({ token: linkToken, onSuccess, onExit }); // handles the redirect back too
return <button disabled={!ready} onClick={() => open()}>Pay later</button>;iOS (Swift)
CoverPayLink.open(linkToken: linkToken, from: self) { result in
switch result {
case .success(let payment): sendToServer(payment.publicToken) // exchange on your server
case .failure(.userCancelled): break
case .failure(let error): show(error)
}
}4. Exchange the public token (server)
Node
const res = await fetch('https://api.coverpayme.com/v1/link/public_token/exchange', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.COVERPAY_SECRET_KEY },
body: JSON.stringify({ public_token: publicToken }),
});
const payment = await res.json();
// { payment_id, status: "captured", provider: "zip", amount: 12000, currency: "USD", order_id: "order_123", plan? }| Field | Meaning |
|---|---|
payment_id | CoverPay payment id; it is also in your webhooks. |
status | captured or authorized: the shopper's plan went through. |
order_id | Your order id from the link token. Check it matches the order you are completing. |
plan | Only for provider: "coverpay": the 4-payment schedule and your payout. |
Exchanging again is safe
If your server loses the answer (timeout, crash), exchange the same public token again: you get the same payment back, and no money moves. Other businesses can't exchange your tokens. Public tokens expire after 30 minutes.
5. Listen for webhooks
Register an endpoint for session.captured and session.authorized. When one arrives, read the payment back with your key and mark the order paid. That also covers shoppers who close their browser before your page hears back. See Webhooks.
Next
- Sandbox testing: test cards, forcing declines, CoverPay plans.
- Web, React and iOS SDK references.
