Integração
API HTTP
Base, autenticação, envelopes e as rotas — pra quem não usa o SDK.
O SDK é um cliente fino sobre uma API REST. Se você não está em Node — ou está
depurando com curl — é isto que você precisa.
Base
| Ambiente | API | Checkout hospedado |
|---|---|---|
Sandbox (sk_test_) | https://api-sandbox.beinfi.com | https://app-sandbox.beinfi.com |
Produção (sk_live_) | https://api.beinfi.com | https://app.beinfi.com |
O prefixo da chave decide o ambiente. Uma sk_test_ enviada pra produção não
falha com "chave errada" — o recurso simplesmente não existe lá (404).
Autenticação
curl https://api-sandbox.beinfi.com/metering/products \
-H "Authorization: Bearer sk_test_…"Só Authorization: Bearer. Não existe X-Api-Key.
As rotas públicas de checkout (/public/v1/* e /pay/{slug}/*) não levam
chave: são abertas por definição, porque rodam no navegador do pagador.
Provisionamento pelo agente
POST /public/v1/claimables é público. Aceita ref, accountName e email
opcionais. Retorna apiKeySecret, publishableKey, tenantSlug, productId,
claimUrl e expiresAt. O nome prepara a conta; o email é contato não verificado.
Com a atualização de email de claim, o endereço recebe um aviso assíncrono com
link e prazo, limitado a um enfileiramento por endereço a cada 24 horas.
Um 201 confirma a criação, não a entrega. Sempre guarde a claimUrl.
Veja cadastro pelo agente para perguntas, chaves e finalização. Se a resposta desse POST se perder, não repita automaticamente: ele pode já ter criado a conta.
Idempotency-Key
Mutações autenticadas exigem o header. O provisionamento público de claim acima é uma exceção:
-H "Idempotency-Key: $(uuidgen)"Sem ele: 400 idempotency_key_required. Reusar a mesma chave com corpo diferente:
409 idempotency_key_reused.
Envelopes de resposta
Algumas rotas devolvem o recurso embrulhado. Criar produto devolve dois:
{ "product": { "id": "0d83d66e-…", "key": "x1", … },
"version": { "id": "…", "version": 1, "status": "draft" } }Listagens vêm sob a chave do plural ({"products":[…]}, {"links":[…]}).
Confira o corpo antes de assumir que o objeto está na raiz — é o erro mais comum
de quem sai do SDK.
Envelopes de erro
São dois, e a diferença importa se você faz parsing:
// handlers — a maioria esmagadora
{ "message": "…", "error_code": "validation_failed", "tracer_id": "befee651…",
"errors": [ { "field": "eventId", "description": "is required" } ] }
// middleware (idempotência, rate limit)
{ "error": { "code": "rate_limited", "message": "…", "request_id": "e0484f60…" } }errors[] é onde mora o motivo de um 422 — é o campo que diz o que corrigir.
Guarde o tracer_id/request_id: é o que o suporte procura.
Rotas
{id} são UUIDs, exceto onde indicado. Esta seção é gerada do contrato OpenAPI,
então acompanha a API.
Catálogo e clientes
| Método | Rota | |
|---|---|---|
GET · POST | /metering/customers | List tenant customers |
GET | /metering/customers/{customerID} | Get tenant customer detail or legacy enrollment by ID |
GET · POST | /metering/customers/{customerID}/credit | Get a customer's credit balance and ledger entries |
POST | /metering/customers/{customerID}/credit/consume | Consume (deduct) credit from a customer |
GET · POST | /metering/customers/{customerID}/rate-cards | List a customer's rate cards |
DELETE | /metering/customers/{customerID}/rate-cards/{rateCardID} | Delete a rate card |
GET | /metering/customers/{customerID}/state | Single-read customer state (enrollment, credit, subscriptions, usage) |
GET | /metering/customers/{customerID}/wallet | Get meter wallet balances for an enrollment |
POST | /metering/customers/{customerID}/wallet/credit | Credit a meter balance |
POST | /metering/customers/{customerID}/wallet/debit | Debit a meter balance |
POST | /metering/events | Ingest a single usage event |
POST | /metering/events/batch | Ingest a batch of usage events (all-or-nothing) |
GET | /metering/overview | Tenant KPI summary for the dashboard overview |
GET · POST | /metering/products | List products |
GET · PATCH | /metering/products/{productID} | Get a product |
GET · POST | /metering/products/{productID}/customers | List product enrollments |
GET | /metering/products/{productID}/customers/{enrollmentID} | Get a product enrollment by enrollment ID |
GET · PUT · DELETE | /metering/products/{productID}/deliverable | Get a product's deliverable metadata |
POST | /metering/products/{productID}/deliverable/presign | Presign an R2 upload URL for a file deliverable |
GET · POST | /metering/products/{productID}/meters | List meters of a product |
PATCH | /metering/products/{productID}/meters/{meterID} | Update a meter's display name / unit / aggregation |
GET · POST | /metering/products/{productID}/payment-links | List a product's payment links |
DELETE | /metering/products/{productID}/payment-links/{linkID} | Revoke a payment link |
GET · POST | /metering/products/{productID}/versions | List versions of a product |
PUT | /metering/products/{productID}/versions/{versionID}/commitment | Set a committed minimum on a version |
GET · POST | /metering/products/{productID}/versions/{versionID}/prices | List prices on a version |
POST | /metering/products/{productID}/versions/{versionID}/publish | Publish a draft version (makes pricing immutable) |
GET | /metering/usage | Get usage totals for a customer |
Cobrança
| Método | Rota | |
|---|---|---|
GET · POST | /billing/coupons | List the tenant's coupons |
GET · PATCH · DELETE | /billing/coupons/{couponID} | Get a coupon |
GET | /billing/customers/{customerID}/invoices | List a customer's invoices |
GET | /billing/customers/{customerID}/payment-methods | List a payer's stored payment methods |
DELETE | /billing/customers/{customerID}/payment-methods/{instrumentID} | Remove a stored payment method |
POST | /billing/customers/{customerID}/payment-methods/{instrumentID}/default | Make a stored payment method the payer's default |
GET | /billing/customers/{customerID}/subscriptions | List a customer's subscriptions |
GET · POST | /billing/invoices | List all invoices for the tenant |
GET | /billing/invoices/{invoiceID} | Get an invoice |
POST | /billing/invoices/{invoiceID}/charge | Charge an open invoice via the PSP |
GET | /billing/invoices/{invoiceID}/payments | List payments against an invoice |
GET | /billing/invoices/{invoiceID}/deliverable | List the buyer download grants an invoice's payments produced |
POST | /billing/invoices/{invoiceID}/send | Finalize and send an invoice |
POST | /billing/invoices/{invoiceID}/uncollectible | Mark an invoice uncollectible |
POST | /billing/invoices/{invoiceID}/void | Void an invoice |
POST | /billing/invoices/from-usage | Generate an invoice from an enrollment's accrued usage (on demand) |
GET | /billing/payments | List all payments for the tenant |
GET | /billing/payments/{paymentID} | Get one payment |
POST | /billing/payments/{paymentID}/refund | Refund a payment (full or partial) — o que acontece com o acesso |
GET | /billing/payments/{paymentID}/refunds | List the refunds recorded against a payment |
POST | /billing/products/{productID}/invoices | Purchase a product — enroll the customer and open a finalized invoice |
POST | /billing/products/{productID}/subscriptions | Create a subscription for a customer |
GET · PUT | /billing/settings | Get the tenant's collection settings |
GET | /billing/subscriptions | List all subscriptions for the tenant |
GET · PATCH | /billing/subscriptions/{subscriptionID} | Get a subscription |
GET · POST | /billing/subscriptions/{subscriptionID}/alerts | List usage alerts on a subscription |
DELETE | /billing/subscriptions/{subscriptionID}/alerts/{alertID} | Delete a usage alert |
POST | /billing/subscriptions/{subscriptionID}/invoices | Generate an invoice for the subscription's current ended period |
GET | /billing/subscriptions/{subscriptionID}/periods | List billing periods of a subscription |
Conta
| Método | Rota | |
|---|---|---|
GET · POST | /account/api-keys | List API keys |
DELETE | /account/api-keys/{keyID} | Revoke an API key |
GET · POST | /account/notification-subscriptions | List notification subscriptions |
PATCH · DELETE | /account/notification-subscriptions/{subscriptionID} | Activate or deactivate a notification subscription |
GET | /account/notifications/deliveries | List notification delivery audit records |
GET · PATCH | /account/tenant | Get the authenticated tenant |
GET · POST | /account/webhooks | List webhook endpoints |
GET · PATCH · DELETE | /account/webhooks/{endpointID} | Get a webhook endpoint |
POST | /account/webhooks/{endpointID}/rotate-secret | Rotate a webhook endpoint's signing secret |
GET | /account/webhooks/deliveries | List webhook delivery audit records |
Público — sem chave
| Método | Rota | |
|---|---|---|
GET | /pay/{slug}/download/{token} | Redeem a tokenized digital-product download (unauthenticated) |
GET | /pay/{slug}/invoices/{invoiceID} | Public hosted-checkout invoice read (unauthenticated) |
POST | /pay/{slug}/invoices/{invoiceID}/charge | Initiate payment on a public checkout invoice (unauthenticated) |
POST | /pay/{slug}/invoices/{invoiceID}/coupon | Apply a coupon to a public checkout invoice (unauthenticated) |
GET | /pay/{slug}/links/{token} | Resolve a payment link for display (unauthenticated) |
POST | /pay/{slug}/links/{token}/checkout | Materialize an invoice from a payment link (unauthenticated, legacy) |
POST | /pay/{slug}/links/{token}/sessions | Open (or reuse) a checkout session for a payment link (unauthenticated) |
GET | /pay/{slug}/links/{token}/sessions/{sessionID} | Read a checkout session (unauthenticated) |
POST | /pay/{slug}/links/{token}/sessions/{sessionID}/charge | Materialize the invoice and charge a checkout session (unauthenticated) |
POST | /public/v1/claimables | Provision a claimable tenant (instant creds, claim later; no auth) |
GET | /public/v1/claimables/{claimableID} | Public claimable-tenant status (no secrets) |
Operação — sessão e webhooks de entrada
| Método | Rota | |
|---|---|---|
POST | /auth/claimables/{claimableID}/claim | Claim a provisional tenant to the signed-in user |
POST | /auth/cli/token | Exchange dashboard session for CLI API key |
POST | /auth/session/bootstrap | Provision tenant on first dashboard signup |
POST | /auth/session/onboarding/complete | Mark tenant onboarding complete |
POST | /auth/session/sync | Sync dashboard session with backend membership |
POST | /webhook/provider/payments/webhook | Inbound PSP webhook (authenticated by the gateway signature) |
Uma venda inteira, só com curl
API=https://api-sandbox.beinfi.com
C=$(curl -s -X POST $API/public/v1/claimables \
-H 'Content-Type: application/json' -d '{}')
K=$(echo $C | jq -r .apiKeySecret); SLUG=$(echo $C | jq -r .tenantSlug)
IDEM() { echo "Idempotency-Key: $(uuidgen)"; }
P=$(curl -s -X POST $API/metering/products -H "Authorization: Bearer $K" \
-H 'Content-Type: application/json' -H "$(IDEM)" \
-d '{"key":"guia","name":"Guia","type":"item","pricingModel":"one_time",
"currency":"BRL","basePrice":"49.90"}')
PID=$(echo $P | jq -r .product.id); VID=$(echo $P | jq -r .version.id)
curl -s -X POST $API/metering/products/$PID/versions/$VID/publish \
-H "Authorization: Bearer $K" -H "$(IDEM)"
INV=$(curl -s -X POST $API/billing/products/$PID/invoices \
-H "Authorization: Bearer $K" -H 'Content-Type: application/json' -H "$(IDEM)" \
-d '{"customer":{"externalId":"u1","email":"[email protected]","taxId":"52998224725"}}' | jq -r .id)
curl -s -X POST $API/pay/$SLUG/invoices/$INV/charge \
-H 'Content-Type: application/json' -H "$(IDEM)" -d '{"method":"pix"}' | jq .pixPayloadO `slug` vem do provisionamento
tenantSlug, no mesmo JSON que devolveu a chave.