Checkout
Create payment links, collect Pix, and track orders through the Hodle API.
Checkout turns a product into a hosted Pix payment link. The seller manages products and settlement settings with an API key. The payer-facing endpoints are public so the hosted page—or your own checkout UI—can read the product, create an order, and poll payment status.
The checkout reuses Hodle's existing deposit rail. Price, settlement asset, network, and destination address are always loaded from the seller's product and account; payer input cannot override them.
Authentication and availability
Seller endpoints require your production API key:
Authorization: Bearer hodle_live_...The account must have Checkout enabled and at least one settlement rail. Public endpoints do not require an API key. They are rate limited by IP and accept only the documented fields.
Availability follows the Checkout flag and the settlement rails enabled for the account in the environment addressed by the request.
Seller endpoints
GET /api/checkout/products
Lists products owned by the account behind the API key, newest first.
curl --request GET \
--url https://api.hodle.com.br/api/checkout/products \
--header "Authorization: Bearer $HODLE_API_KEY"{
"success": true,
"data": {
"products": [
{
"id": "68bb089d3696d243ba022bc1",
"slug": "plano-premium-k7m2p4",
"name": "Plano Premium",
"description": "Acesso por 30 dias",
"imageUrl": null,
"priceCents": 8990,
"stock": null,
"sold": 12,
"views": 84,
"asset": "BRLA",
"network": "polygon",
"askEmail": true,
"askTaxId": true,
"askNote": false,
"status": "ACTIVE",
"createdAt": "2026-09-05T13:00:00.000Z",
"updatedAt": "2026-09-05T13:00:00.000Z"
}
]
}
}POST /api/checkout/products
Publishes one product. The settlement asset and network come from the current Checkout settings and cannot be passed in this request.
curl --request POST \
--url https://api.hodle.com.br/api/checkout/products \
--header "Authorization: Bearer $HODLE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"name": "Plano Premium",
"description": "Acesso por 30 dias",
"priceCents": 8990,
"stock": null,
"askTaxId": true,
"askNote": false
}'const response = await fetch('https://api.hodle.com.br/api/checkout/products', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.HODLE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Plano Premium',
description: 'Acesso por 30 dias',
priceCents: 8990,
stock: null,
askTaxId: true,
askNote: false,
}),
})
const { data } = await response.json()import os, requests
response = requests.post(
"https://api.hodle.com.br/api/checkout/products",
headers={"Authorization": f"Bearer {os.environ['HODLE_API_KEY']}"},
json={
"name": "Plano Premium",
"description": "Acesso por 30 dias",
"priceCents": 8990,
"stock": None,
"askTaxId": True,
"askNote": False,
},
)
product = response.json()["data"]["product"]| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Product name, up to 120 characters. |
description | string | no | Description, up to 240 characters. |
imageBase64 | data URI | no | PNG, JPEG, or WEBP image as a base64 data URI. |
priceCents | integer | yes | Unit price in BRL cents. Minimum 100. |
stock | integer / null | no | Total sellable units. null or omission means unlimited stock. |
askTaxId | boolean | no | Require a valid CPF/CNPJ before creating Pix. Defaults to true. |
askNote | boolean | no | Allow a payer note of up to 140 characters. Defaults to false. |
Returns 201 with data.product in the same shape as the list endpoint.
PATCH /api/checkout/products/:productId
Updates an owned product. Send at least one field:
curl --request PATCH \
--url https://api.hodle.com.br/api/checkout/products/68bb089d3696d243ba022bc1 \
--header "Authorization: Bearer $HODLE_API_KEY" \
--header "Content-Type: application/json" \
--data '{"priceCents": 9490, "status": "PAUSED"}'| Field | Type | Values |
|---|---|---|
priceCents | integer | BRL cents, from 100 to 100000000. |
stock | integer / null | Non-negative, or null for unlimited. |
status | string | DRAFT, ACTIVE, or PAUSED. |
A product owned by another API account answers 404, exactly like a missing
product.
GET /api/checkout/settings
Returns the effective settlement configuration and which assets the account is currently allowed to select.
{
"success": true,
"data": {
"settings": {
"displayName": "Hodle Store",
"supportEmail": "[email protected]",
"asset": "USDC",
"network": "polygon",
"availableAssets": ["BRLA", "USDT", "USDC", "BRS"]
}
}
}PUT /api/checkout/settings
curl --request PUT \
--url https://api.hodle.com.br/api/checkout/settings \
--header "Authorization: Bearer $HODLE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"displayName": "Hodle Store",
"supportEmail": "[email protected]",
"asset": "USDC"
}'asset must be present in availableAssets. The server selects the matching
network; clients do not pass one. The response contains the saved effective
settings.
Payer endpoints
GET /api/public/checkout/products/:slug
Reads the payer-safe view of an active payment link.
curl --request GET \
--url https://api.hodle.com.br/api/public/checkout/products/plano-premium-k7m2p4{
"success": true,
"data": {
"product": {
"slug": "plano-premium-k7m2p4",
"name": "Plano Premium",
"description": "Acesso por 30 dias",
"imageUrl": null,
"priceCents": 8990,
"available": null,
"soldOut": false,
"askTaxId": true,
"askNote": false,
"sellerName": "Hodle Store",
"sellerSupportEmail": "[email protected]"
}
}
}Missing, paused, disabled, and inactive-seller links all return the same 404
response. The public response deliberately omits seller IDs, wallets,
settlement assets, networks, and provider details.
POST /api/public/checkout/orders
Creates a Pix charge for the product and quantity. The endpoint accepts only the fields below; extra fields—including price, asset, network, seller, and destination—make the request fail validation.
curl --request POST \
--url https://api.hodle.com.br/api/public/checkout/orders \
--header "Content-Type: application/json" \
--data '{
"slug": "plano-premium-k7m2p4",
"quantity": 1,
"payerEmail": "[email protected]",
"payerTaxId": "52998224725",
"payerNote": "Pedido 781"
}'const response = await fetch(
'https://api.hodle.com.br/api/public/checkout/orders',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
slug: 'plano-premium-k7m2p4',
quantity: 1,
payerEmail: '[email protected]',
payerTaxId: '52998224725',
payerNote: 'Pedido 781',
}),
},
)
const order = (await response.json()).data.orderimport requests
response = requests.post(
"https://api.hodle.com.br/api/public/checkout/orders",
json={
"slug": "plano-premium-k7m2p4",
"quantity": 1,
"payerEmail": "[email protected]",
"payerTaxId": "52998224725",
"payerNote": "Pedido 781",
},
)
order = response.json()["data"]["order"]| Field | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Product slug from the public product endpoint. |
quantity | integer | yes | From 1 to 99, subject to available stock. |
payerEmail | string | yes | E-mail recorded on the order. |
payerTaxId | string | by product | Valid CPF/CNPJ when askTaxId is true. |
payerNote | string | no | Optional note, up to 140 characters. |
The call returns 201 after the Pix charge is created:
{
"success": true,
"data": {
"order": {
"trackId": "f28bce4e-2f86-413e-a669-8ad74ae45a91",
"status": "PENDING",
"brCode": "00020126580014br.gov.bcb.pix...",
"quantity": 1,
"totalCents": 8990,
"payerEmail": "[email protected]",
"expiresAt": "2026-09-05T14:15:00.000Z",
"paidAt": null
}
}
}GET /api/public/checkout/orders/:trackId
Poll this endpoint until the order reaches a terminal state. Reading status also synchronizes it from the underlying charge and settles counted stock once.
curl --request GET \
--url https://api.hodle.com.br/api/public/checkout/orders/f28bce4e-2f86-413e-a669-8ad74ae45a91| Status | Meaning |
|---|---|
PENDING | Pix is waiting for payment. |
PAID | Payment completed and stock was settled. |
FAILED | Charge failed. |
EXPIRED | The 15-minute Pix payment window expired. |
The response has the same data.order shape returned by order creation.
Errors
| Status | Meaning |
|---|---|
400 | Invalid JSON, undocumented fields, validation error, or unavailable asset. |
401 | Missing or invalid API key on a seller endpoint. |
403 | Checkout is disabled or the seller has no available settlement rail. |
404 | Product, Checkout link, order, or account was not found in the caller scope. |
409 | Product is paused or sold out. |
429 | API-key or public-IP rate limit exceeded. |
502 | Pix charge could not be created. Upstream/provider details are never sent. |
Hosted page
You can use these endpoints from your own UI, or send the payer to Hodle's hosted page:
https://checkout.hodle.com.br/pay/:slugThe hosted page and the REST API share the same products, orders, stock, and payment state.