Products
Create and manage reusable hosted checkout products your customers pay with stablecoins or PIX.
A product is a reusable, sellable catalog item. Each product has a hosted page at https://dolafy.com/checkout/<slug> where your customer completes payment. You settle in stablecoin; your customer pays with a stablecoin or with PIX.
Create one product per catalog item, then either:
- send buyers to
product.checkoutUrl, appending your own attribution (for example?userID=user_42&txn_id=txn_1048), or - create a PIX charge with
POST /v1/checkout/sessionsfor a transparent checkout.
Do not create a product per buyer, order, or payment attempt. All checkout endpoints are scoped to the organization behind your API key.
The product object
{
"id": "6a713a92-350a-4cc6-a996-1e55e97d3a36",
"externalProductId": "pro-plan",
"slug": "c-8f41a2d9",
"name": "Pro Plan",
"description": "Monthly access to the Pro plan.",
"amount": "29.00",
"currency": "USD",
"status": "active",
"checkoutUrl": "https://dolafy.com/checkout/c-8f41a2d9",
"imageUrl": "https://example.com/pro-plan.png",
"redirectUrlSuccess": "https://example.com/checkout/success",
"redirectUrlCancel": "https://example.com/checkout/cancel",
"paymentMethods": [
{ "type": "crypto", "chain": "base", "currency": "USD", "settlementCurrency": "USDC" }
],
"createdAt": "2026-07-04T12:00:00.000Z",
"updatedAt": "2026-07-04T12:00:00.000Z"
}
externalProductIdis your own optional identifier, unique within your organization. It can identify a product when creating a checkout session and can be found through the list search. Product GET, PATCH, and DELETE paths use the Dolafyid.slug, settlement destination, tracking pixels, and internal metadata are not writable through this API.
List products
GET /v1/checkout/products
x-api-key: dlfy_live_...
| Parameter | Default | Description |
|---|---|---|
status | active | active, archived, or all. |
q | — | Searches name, Dolafy id, slug, and externalProductId (≤ 200 chars). |
limit | 50 | 1–100. |
offset | 0 | Zero or greater. |
Returns { "products": [ ... ], "pagination": { "limit", "offset", "hasMore" } }, newest first.
Omitting status returns active products only. Archived products appear only when explicitly
requesting status=archived or status=all.
Get a product
GET /v1/checkout/products/:productId
x-api-key: dlfy_live_...
Returns one active or archived product in the { "product": ... } shape. Unknown or cross-organization ids return 404 product_not_found.
Use the exact product.id returned by product creation or the product list. The hosted-page slug
and externalProductId are not accepted in this path.
Create a product
A product is one of two types, chosen by paymentMethods:
- a stablecoin product — USD-denominated, paid in USDC/USDT on Base/Solana (shown below), or
- a PIX product — BRL-denominated, paid with PIX (see Create a PIX product).
If paymentMethods is omitted, the product follows your organization’s default checkout settings.
POST /v1/checkout/products
x-api-key: dlfy_live_...
Idempotency-Key: catalog:pro-plan:v1
content-type: application/json
Idempotency-Key is required (8–200 letters, numbers, dots, underscores, colons, or hyphens). The example below creates a stablecoin product.
Request
{
"externalProductId": "pro-plan",
"name": "Pro Plan",
"description": "Monthly access to the Pro plan.",
"amount": "29.00",
"imageUrl": "https://example.com/pro-plan.png",
"redirectUrlSuccess": "https://example.com/checkout/success",
"redirectUrlCancel": "https://example.com/checkout/cancel",
"paymentMethods": {
"networks": ["base"],
"tokens": ["usdc"]
}
}
Validation:
nameis 3–120 characters;description≤ 500; URLs must be HTTP/HTTPS;amountmust be positive.externalProductIduses the same identifier characters, ≤ 200, and must be unique in your organization.- An explicit stablecoin override must keep Base and USDC enabled, otherwise
400 base_requiredor400 usdc_required. Unknown networks/tokens return400 unsupported_checkout_networkor400 unsupported_checkout_token.
Returns 201 Created (including an identical idempotent replay) with the { "product": ... } shape.
- Reusing an idempotency key with a different body returns
409 idempotency_key_conflict. - An
externalProductIdcollision returns409 external_product_id_conflict.
Create a PIX product
A PIX product is created with the same POST /v1/checkout/products endpoint. There are only two differences from a stablecoin product:
- Set
paymentMethodsto exactly{ "pix": true }. amountis the price in BRL (Brazilian reais), not USD.
That’s it — don’t send networks or tokens. Here is a full request and response:
POST /v1/checkout/products
x-api-key: dlfy_live_...
Idempotency-Key: catalog:curso-pro:v1
content-type: application/json
{
"externalProductId": "curso-pro",
"name": "Curso Pro",
"description": "Acesso ao Curso Pro.",
"amount": "49.90",
"redirectUrlSuccess": "https://example.com/checkout/success",
"paymentMethods": { "pix": true }
}
Response — note currency is BRL and paymentMethods has a single bank/pix entry (compare with the crypto entry a stablecoin product returns):
{
"product": {
"id": "8b2c9f14-6d3a-4e77-9a21-5c0e1f7b2d40",
"externalProductId": "curso-pro",
"slug": "c-1a2b3c4d",
"name": "Curso Pro",
"description": "Acesso ao Curso Pro.",
"amount": "49.90",
"currency": "BRL",
"status": "active",
"checkoutUrl": "https://dolafy.com/checkout/c-1a2b3c4d",
"imageUrl": null,
"redirectUrlSuccess": "https://example.com/checkout/success",
"redirectUrlCancel": null,
"paymentMethods": [
{ "type": "bank", "currency": "BRL", "rails": ["pix"], "label": "BRL Pix" }
],
"createdAt": "2026-07-22T12:00:00.000Z",
"updatedAt": "2026-07-22T12:00:00.000Z"
}
}
Rules for PIX products:
pixcannot be combined withnetworks,tokens, orinheritOrganizationSettings— invalid combinations return400 invalid_payment_methods.- Your organization must have a live PIX route and an active BRL account, otherwise creation returns
503 checkout_pix_not_available. - Buyers pay this product with PIX only. To generate a payable PIX QR code / Copia e Cola for a specific order, create a session from this product.
Edit a product
PATCH /v1/checkout/products/:productId
content-type: application/json
PATCH is partial — omitted fields keep their values; an empty body returns 400 invalid_body. Editable fields: externalProductId (string or null), name, amount, description, imageUrl, redirectUrlSuccess, redirectUrlCancel, status (active or archived), and paymentMethods.
{
"name": "Pro Plan Annual",
"amount": "290.00",
"status": "active"
}
Returns 200 OK with the { "product": ... } shape. To move a product between PIX and stablecoins, see Switching a product between rails.
Archive a product
DELETE /v1/checkout/products/:productId
Idempotently soft-archives a product — nothing is deleted. An archived product disappears from the default list and stops accepting new hosted charges and new API sessions, but existing charges and previously created session URLs remain readable and payable until their normal expiry. Restore with PATCH { "status": "active" }. Returns 200 OK with the product shape and status: "archived".
Hosted checkout URL parameters
When you send buyers to product.checkoutUrl, you can prefill context and carry attribution:
userID(oruserId,user_id) — shown as a read-only Order reference and persisted as the chargeexternalId.userEmail(oremail) — prefills the buyer email field.- Any other query parameter is passthrough attribution: included in charge metadata and appended to your success redirect after payment.
https://dolafy.com/checkout/gold-access?userID=player_123&userEmail=buyer@example.com&campaign=launch
Discounts are not available on hosted product URLs — a query parameter cannot lower the price. To charge a one-off discounted amount, create a session with discountPercent.
Advanced
Switching a product between rails
paymentMethods is editable with PATCH:
- Use
paymentMethods.inheritOrganizationSettings: trueto clear a stablecoin override and follow your organization’s default checkout settings. - Convert a PIX product back to stablecoins by sending
networks/tokens, or by inheriting organization settings; its currency returns to USD. - Switching rails changes the currency label but does not convert the numeric price — a
49.90BRL product becomes a49.90USD product. Includeamountin the same PATCH when the new rail needs a different price.
{
"amount": "29.00",
"paymentMethods": { "inheritOrganizationSettings": true }
}
Next: create a transparent PIX charge with Sessions, read results with Transactions, or get notified via Webhooks.