Payments
/v1/payments cria e gerencia pagamentos de qualquer método (pix, credit_card,
debit_card, boleto) através de um único corpo — method decide o resto. Pra uma resposta
já formatada especificamente pra PIX (com qrCode/copyPaste) ou boleto (com
barcode/digitableLine), veja as páginas PIX e Boleto —
internamente é o mesmo pagamento, só a projeção da resposta muda.
Criar um pagamento
curl -X POST https://api.tamino.com.br/v1/payments \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042" \
-d '{
"amountInCents": 5000,
"method": "credit_card",
"cardToken": "tok_...",
"externalId": "pedido-12345"
}'
const payment = await gateway.payments.create(
{ amountInCents: 5000, method: 'credit_card', cardToken: 'tok_...', externalId: 'pedido-12345' },
{ idempotencyKey: 'order-1042' },
);
{
"id": "9f34270f-04c9-4fd5-90ad-9e4179cdb230",
"object": "payment",
"externalId": "pedido-12345",
"status": "paid",
"method": "credit_card",
"amountInCents": 5000,
"currency": "BRL",
"merchantId": "merchant_...",
"customerId": null,
"description": null,
"metadata": null,
"createdAt": "2026-08-25T19:44:24.674Z",
"updatedAt": "2026-08-25T19:44:24.797Z",
"card": { "status": "captured", "last4": "1234", "cardBrand": "..." }
}
Seu id do pedido (externalId) e timeout
Mande em externalId o id do pedido no seu sistema (até 64 caracteres: letras, números, .,
_, : e -). Ele volta em todas as respostas da cobrança (criação e consulta; null se não
enviado) e em todos os webhooks dela, e é único por merchant: repetir o POST com o mesmo
externalId devolve a cobrança que já existe — mesmo id e, pra PIX/boleto, o mesmo QR Code ou o mesmo boleto — sem criar outra. O mesmo externalId
com outro valor ou outro método responde 409.
Exceção: se a tentativa anterior falhou no provider e nenhum QR Code/boleto chegou a ser emitido, reenviar com
o mesmo externalId tenta de novo na mesma cobrança (mesmo id) e devolve o QR Code/boleto novo.
Se o pedido der timeout ou erro de rede, você não recebe o nosso id, mas não perde a cobrança:
- consulte pelo seu id:
GET /v1/payments/external/{externalId}(404= a cobrança não foi criada); - ou simplesmente reenvie o mesmo pedido com o mesmo
externalId— nunca nasce uma segunda cobrança.
Com uma API key do tenant (não presa a um merchant), passe ?merchantId= na consulta quando o
mesmo externalId existir em mais de um merchant (senão a resposta é 400).
curl https://api.tamino.com.br/v1/payments/external/pedido-12345 \
-H "Authorization: Bearer sk_test_..."
Autorizar sem capturar
Passe capture: false pra reservar o valor no cartão sem cobrar de verdade — útil pra
confirmar estoque/fraude antes de capturar de fato:
const authorized = await gateway.payments.create({
amountInCents: 5000,
method: 'credit_card',
cardToken: 'tok_...',
capture: false,
});
// authorized.status === 'authorized'
const captured = await gateway.payments.capture(authorized.id);
// ou, pra desistir sem cobrar:
await gateway.payments.cancel(authorized.id);
Uma autorização não capturada nunca posta nada no ledger — o dinheiro só "sai" de verdade na captura.
Consultar
const payment = await gateway.payments.get('pay_123');
Status possíveis
status | Significado |
|---|---|
created | Sessão criada, pagamento ainda não submetido. |
processing | Submissão em andamento. |
authorized | Cartão autorizado, não capturado ainda. |
paid | Aprovado — dinheiro reservado/movido. |
failed | Recusado ou erro. |
pending_payment | PIX/boleto emitido, aguardando pagamento assíncrono. |
canceled | Autorização cancelada antes de capturar. |
refunded | Estornado (ver nota abaixo). |
refunded aqui é conceitual — o campo status da resposta reflete o status da sessão de
checkout (que permanece paid), não do ledger. Pra saber se um pagamento foi estornado,
veja metadata.refundedAt (quando) e metadata.refundedAmountInCents (quanto) na consulta,
ou trate o webhook payment.refunded — enviado pro estorno pela API e pelo Backoffice.
Estornar
await gateway.payments.refund('pay_123');
Estorno é sempre total nesta entrega — refund parcial não está implementado
(amountInCents opcional no corpo é ignorado se enviado). Só funciona em pagamentos paid.
Split
/v1/payments não tem um campo de split direto no corpo — split é uma regra do merchant
(quem recebe o quê de cada venda), configurada uma vez e aplicada automaticamente em toda
cobrança que casar com ela. Ver Splits.