Checkout
Create PIX charges from your backend and redirect the buyer to a hosted payment page with your brand.
How it works#
Checkout creates a hosted charge. Your backend sends items or a direct amount, receives a url, and redirects the buyer to the Triad Pay page. The page collects payer details, issues the PIX, and displays a QR Code and copy-and-paste code.
- 1
Create
Your backend creates the checkout with POST /api/checkout.
- 2
Redirect
The buyer opens the hosted URL returned by the API.
- 3
Pay
The page collects name and CPF, issues the PIX, and waits for confirmation.
- 4
Confirm
Your system tracks the status and releases the order only when it is paid.
Creating and listing checkouts requires authentication. Routes used by the hosted page are public by design: the checkout UUID in the URL is the unguessable credential.
Quick start#
Create checkout
curl -X POST https://main.triadpay.app/api/checkout \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"name": "Black t-shirt",
"unitPriceBrl": 120,
"quantity": 1
}
],
"shipping": 8,
"description": "Order #9581",
"expiresInMinutes": 60
}'{
"data": {
"id": "1de0f7c3-9a2b-4f6e-8c1d-2b3a4c5d6e7f",
"code": "CHG-9F3A2C1B",
"url": "https://www.triadpay.app/checkout/1de0f7c3-9a2b-4f6e-8c1d-2b3a4c5d6e7f",
"amountBrl": 128,
"shippingBrl": 8,
"description": "Order #9581",
"items": [
{
"name": "Black t-shirt",
"quantity": 1,
"unitPriceBrl": 120
}
],
"status": "pending",
"expiresAt": "2026-08-03T19:40:00.000Z",
"createdAt": "2026-08-03T18:40:00.000Z"
}
}Authentication#
Company operations use Authorization: Bearer. In the current backend, this token is the Privy access token of an admin provisioned with the admin or superadmin role.
Authorization: Bearer <access_token>
Never use this token in the browser. Create checkouts only from your server and expose only the hosted URL to the buyer.
Create checkout#
Use POST /api/checkout. Send items to display an order summary, or amount for charges without items. The minimum checkout total is R$ 10.00.
itemsarray - conditional1 to 50 items. Required when amount is not sent.
items[].namestringItem name, from 1 to 120 characters.
items[].unitPriceBrlnumberUnit price in BRL, from 0.01 to 1,000,000.
items[].quantityintegerInteger quantity, from 1 to 999.
amountnumber - conditionalDirect amount in BRL. Required when items is not sent.
shippingnumber - optionalShipping added to the total. Omit it to remove the shipping line; 0 means free shipping.
descriptionstring - optionalShort description, up to 140 characters.
expiresInMinutesinteger - optionalExpiration between 5 and 1440 minutes. The default comes from checkout settings.
{
"amount": 250,
"description": "July consulting"
}Track status#
After redirecting the buyer, track the charge with GET /api/checkout/{id}/status. Poll every few seconds while the checkout is active and stop when it reaches a terminal state.
{
"data": {
"status": "paid",
"paidAt": "2026-08-03T18:48:12.000Z",
"expiresAt": "2026-08-03T19:40:00.000Z"
}
}pendingThe charge exists and is still waiting for payment. It may be before or after PIX issuance.
ActivepaidPayment confirmed. Release the order.
TerminalexpiredThe payment window expired without payment. An unpaid checkout may issue a new PIX.
TerminalcanceledThe charge was canceled or failed at the provider.
TerminalThe hosted page issues PIX with POST /api/checkout/{id}/pay. On the first call, send payer details.
{
"payer": {
"name": "Ana Pereira",
"document": "12345678909",
"email": "ana@example.com",
"phone": "+5511999999999"
}
}{
"data": {
"code": "CHG-9F3A2C1B",
"pixCode": "00020101021226880014br.gov.bcb.pix...",
"status": "pending",
"expiresAt": "2026-08-03T19:40:00.000Z"
}
}Branding and return#
Logo, colors, text, required payer fields, and return URLs live in the company's checkout settings. Use GET /api/company/checkout-settings to read them and PUT /api/company/checkout-settings to update them.
{
"primaryColor": "#00B471",
"secondaryColor": "#0A0B0F",
"logoUrl": "https://cdn.example.com/logo.png",
"displayName": "Example Store",
"successUrl": "https://store.example.com/success",
"cancelUrl": "https://store.example.com/cart",
"expirationMinutes": 60,
"requiredFields": ["name", "document", "email"],
"checkoutText": "Secure payment via Triad Pay.",
"language": "en",
"showTriadBranding": true
}primaryColorhexPrimary color for the hosted page.
secondaryColorhexSecondary color for the hosted page.
logoUrlstring | nullHTTPS URL or image data URL for the store brand.
successUrlurl | nullDestination to return to the store after confirmed payment.
cancelUrlurl | nullCancellation or abandonment destination when applicable.
requiredFieldsarrayAdditional fields required from the payer: name, document, email, or phone.
Do not release orders only because the buyer was redirected to successUrl. Redirects are user experience; payment confirmation must come from the paid status.
Errors#
Errors return message and code. Validations may also return issues with the field path.
{
"message": "Validation error",
"code": "VALIDATION_ERROR",
"issues": [
{
"path": "items.0.quantity",
"message": "Too small: expected number to be >=1"
}
]
}VALIDATION_ERROR400Body, query, or params failed validation.
AMOUNT_TOO_LOW400Total below the R$ 10.00 minimum.
EMAIL_REQUIRED / PHONE_REQUIRED400A field required in settings was not sent in /pay.
PAYER_REQUIRED400Attempt to regenerate PIX without a saved payer.
CHECKOUT_PAID409Checkout has already been paid.
For API fundamentals, see the Introduction.