Safe retries
Retry a payment without creating a second charge.
Before a money-moving request, generate one unique Idempotency-Key and store it with your payment attempt. If you do not receive a response, send the same request again with the same key.
The rule
- Same key and same request: returns the original result or continues the original operation.
- Same key and different request: is rejected. A key belongs to one exact operation.
- New key: means a new operation and can create another charge.
const paymentAttemptId = crypto.randomUUID(); // create once
async function authorize(body) {
return fetch("https://api.kepapay.co/api/v1/terminal/transactions/authorize", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KEPA_DEVICE_TOKEN}`,
"Idempotency-Key": paymentAttemptId,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
}
// If the network fails, call authorize again with the same body and key.When to retry
- Retry network failures and 5xx responses with the same key and unchanged body.
- Do not retry validation, authentication, or ownership errors unchanged.
- Do not automatically retry an issuer decline. Ask for another payment method.
- After a successful response, store
payment.idand stop retrying.
Terminal timeouts
If a terminal loses the authorization response, first retry with the same key or query recovery status using that key. Follow the returned recoveryAction. Never generate a new key just because the original result is uncertain.
Which operations require a key?
The endpoint reference marks Idempotency-Key as required or optional for each operation. Do not assume every POST accepts it. Terminal authorization and pre-authorization capture require it; use it on payment and checkout creation whenever the endpoint offers it.