Skip to content

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.
}