Skip to content
Documentation
Get started

Webhooks and errors

Retry without creating another payment

Save the payment request before sending it. If you lose the response, send it again with the same paymentReference: Timbro returns the same payment and its current status.

import { createTimbroPayments, type CreatePaymentCommand } from "@timbro/payments";
const timbro = createTimbroPayments({ apiKey: process.env.TIMBRO_PAYMENTS_SECRET_KEY! });
export async function recoverPayment(savedRequest: CreatePaymentCommand) {
return timbro.payments.create(savedRequest);
}

The SDK creates the idempotency key and makes up to two automatic retries for transient failures. If those attempts run out, keep the request to recover it later.

An ERP can derive the reference from the order and its revision with paymentReferenceForSource in TypeScript or payment_reference_for_source in Python. The same order revision always yields the same reference.

  • The reference is retained within the same merchant and mode, Test or Live.
  • Changing the amount, items, tax, selected merchant account, or other request data returns a conflict (409).
  • If you sent expiresAfterSeconds, send it again unchanged. It is part of the request: a different value, or leaving it out after sending it, returns a conflict (409).
  • Changing the merchant configuration does not change a payment that has already been accepted.
  • An expired or canceled payment stays the same when you repeat its reference.

Direct HTTP accepts the same body. Idempotency-Key is optional when creating payments and refunds; if you send it, keep that key when retrying too. Other operations, such as registering a webhook, require it. Derive that key from a record your system keeps, such as the order or the order line, and never generate a new key for each attempt.

An unknown outcome may eventually be approved. Confirm what happened to the payment before starting another collection.