Your first payment
The merchant server creates a Payment with minor-unit amount, sale reference, and fiscal intent. Keep the secret key on the server:
import { createTimbroPayments } from "@timbro/payments";
const secretKey = process.env.TIMBRO_PAYMENTS_SECRET_KEY;if (!secretKey) throw new Error("Missing TIMBRO_PAYMENTS_SECRET_KEY");const timbro = createTimbroPayments({ secretKey });const payment = await timbro.payments.create({ idempotencyKey: "create-order-123", saleReference: "order-123", amount: { currency: "DOP", minorUnits: 125_000 }, description: "Maintenance service", fiscalDocument: null,});Give the buyer nextAction.url without rebuilding the form. The eight canonical Payment states are requires_customer_action, processing, partially_paid, verifying, succeeded, declined, canceled, and expired. verifying is an uncertain, non-terminal result: retrieve the same Payment and do not charge again. declined is a valid creation response, not an HTTP error to retry automatically.
Payment authorization, fiscal issuance, PDF availability, and email delivery are observable, separate lifecycles. A succeeded payment can coexist with a FiscalDocument that is processing, rejected, or operator_required.
After Checkout returns, retain the reference and retrieve it from the server:
const current = await timbro.payments.retrieve(payment.id);if (current.status === "verifying") { // Persist the payment and schedule retrieval; never create a second payment.}