AbsolutePayDocs

Accept payments

Create a hosted checkout your customer pays, then confirm settlement — SDK or curl.

To collect a payment you create a checkout link. AbsolutePay returns a hosted checkout URL, your customer opens it and pays in crypto (they pick the asset and network on the page), and the funds settle to your workspace. You learn it settled via a webhook (and can poll as a fallback).

The flow: create checkout → send customer to checkoutUrl → they pay → payment.succeeded webhook → you fulfill.

Before you start: you need an API key with the invoices:write scope (Authentication). Build against an ap_test_ key or the sandbox first — same request shapes, no real funds. To show the fee before you create the order, use the fee preview.

Create a checkout

Returns a token and a hosted checkoutUrl to send the customer to; they pick the asset on the page. Your reference is your own order id — keep it unique per order; it's how you correlate the payment later.

const checkout = await ap.checkouts.create({
  reference: "order-1024",                        // your order id (keep it unique)
  amount: { amount: "49.99", currency: "USDT" },  // decimal string, ≤ 6 dp
});
console.log(checkout.token, checkout.checkoutUrl);
checkout = ap.checkouts.create(
    reference="order-1024",                          # your order id (keep it unique)
    amount={"amount": "49.99", "currency": "USDT"},  # decimal string, ≤ 6 dp
)
print(checkout["token"], checkout["checkoutUrl"])
checkout, err := ap.Checkouts.Create(ctx, absolutepay.CheckoutParams{
	Reference: "order-1024",                                      // your order id (keep it unique)
	Amount:    absolutepay.Money{Amount: "49.99", Currency: "USDT"}, // decimal string, ≤ 6 dp
})
if err != nil {
	log.Fatal(err)
}
fmt.Println(checkout.Token, checkout.CheckoutURL)
BODY='{"reference":"order-1024","amount":{"amount":"49.99","currency":"USDT"}}'
curl https://api.absolutepay.io/v1/checkouts \
  -H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
  $(sign POST /v1/checkouts "$BODY") -d "$BODY"
{ "token": "chk_…", "kind": "checkout", "status": "OPEN", "checkoutUrl": "https://pay.absolutepay.io/pay/chk_…" }

Send the customer to checkoutUrl and keep the token — it's how you poll status later. Amounts are decimal strings ("49.99"), positive, ≤ 6 fraction digits. The full parameter and response tables live on POST /v1/checkouts in the API reference.

Confirm the payment

Don't treat an order as paid until it reaches a terminal paid state. Use both signals:

  1. Webhooks (primary) — a payment.succeeded event fires on settlement. See Webhooks.
  2. Polling (fallback) — read the checkout back by its token if you miss a webhook:
const checkout = await ap.checkouts.get("chk_…");
if (checkout.status === "PAID") { /* fulfill the order */ }
checkout = ap.checkouts.get("chk_…")
if checkout["status"] == "PAID":
    pass  # fulfill the order
checkout, err := ap.Checkouts.Get(ctx, "chk_…")
if err != nil {
	log.Fatal(err)
}
if checkout.Status == "PAID" {
	// fulfill the order
}
curl "https://api.absolutepay.io/v1/checkouts/chk_…" \
  -H "Authorization: Bearer $APP_TOKEN" $(sign GET "/v1/checkouts/chk_…" "")

Statuses

status is the settlement state: OPENPAID. Unpaid links expire on their own; you don't need to close them. Always fulfill on the webhook, then treat ap.checkouts.get as backup.

Idempotency

The reference is your idempotency/reconciliation handle: generate it once per order and reuse it on retry so you correlate the settlement back to the right order.

Gotchas

  • Amounts are decimal strings ("49.99"), positive, ≤ 6 fraction digits — never floats.
  • Settlement is final. Once a payment settles there's no chargeback path in crypto; returning funds means creating a refund, which is a new outbound transaction.
  • Sandbox links don't settle by themselves — you trigger settlement ("Simulate payment" in the dashboard), which fires the same payment.succeeded webhook as production.

Next

On this page