Cobranças
Criar
curl -X POST https://api-crpay.deskhotel.com.br/v1/payments \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": 131640,
"payment_method": "card",
"reference": "RES-99871",
"card": {
"number": "4532015112830366",
"holder_name": "FULANO DE TAL",
"expiration_month": 12,
"expiration_year": 2028,
"security_code": "737",
"brand": "visa"
}
}'
{
"id": "pay_01KYFSX27TJEHQEF18TSH8YFQD",
"status": "captured",
"amount": 131640,
"currency": "BRL",
"payment_method": "card",
"installments": 1,
"reference": "RES-99871",
"card": { "brand": "visa", "bin": "453201", "last4": "0366" },
"acquirer": {
"name": "cielo",
"payment_id": "0f4e...",
"tid": "1006993069...",
"nsu": "674532",
"authorization_code": "123456"
},
"error": null,
"metadata": null,
"created_at": "2026-07-23T18:09:55.116Z",
"updated_at": "2026-07-23T18:09:56.086Z"
}
Valores
amount é inteiro em centavos. R$ 1.316,40 se envia como 131640.
Decimal, string, zero e negativo são recusados com 400 invalid_amount.
Referência
reference é o seu identificador — número do pedido, da reserva, do contrato.
É por ele que a conciliação localiza a transação na adquirente, e é único por conta:
a mesma reference não vira duas cobranças.
Cartão
O número completo e o código de segurança não são armazenados. A resposta e todas as consultas devolvem apenas os seis primeiros dígitos, os quatro últimos e a bandeira.
brand é opcional — se omitido, é deduzido do número.
Idempotência
O header Idempotency-Key é obrigatório em toda operação que movimenta valores.
Gere um identificador único por operação — um UUID serve — e guarde-o junto do seu registro antes de chamar a API. Em caso de timeout ou falha de rede, repita a requisição com a mesma chave: se a cobrança já tiver sido criada, a resposta original é devolvida sem cobrar de novo.
Gerar uma chave nova para a retentativa anula a proteção e é o caminho direto para a cobrança duplicada.
Reutilizar a mesma chave para uma requisição diferente devolve 409 idempotency_key_reuse. A chave é por operação, não por objeto de negócio: não use a
mesma para cobrar e depois para estornar.
Pré-autorização
Envie capture: false para reservar o valor sem efetivá-lo:
curl -X POST https://api-crpay.deskhotel.com.br/v1/payments \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "amount": 50000, "payment_method": "card", "capture": false, "card": { … } }'
A cobrança fica em authorized. Para efetivar:
curl -X POST https://api-crpay.deskhotel.com.br/v1/payments/$ID/capture \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)"
Informe amount no corpo para capturar menos que o autorizado.
Cancelar e estornar
curl -X POST https://api-crpay.deskhotel.com.br/v1/payments/$ID/cancel \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "amount": 30000, "reason": "Cancelamento de uma diária" }'
A operação depende do estado da cobrança:
| Estado | Operação | Resultado |
|---|---|---|
authorized |
Cancelamento — desfaz antes de o valor sair | canceled |
captured |
Estorno — devolve o valor | refunded ou partially_refunded |
Omitir amount estorna o saldo restante.
Estornos parciais são somados: pedir mais que o saldo devolve 400 refund_amount_exceeds_payment. Não é possível devolver mais que o valor da cobrança,
mesmo em várias chamadas.
Consultar
curl https://api-crpay.deskhotel.com.br/v1/payments/$ID \
-H "Authorization: Bearer $TOKEN"
Listagem, da mais recente para a mais antiga, com filtros opcionais:
curl "https://api-crpay.deskhotel.com.br/v1/payments?reference=RES-99871" \
-H "Authorization: Bearer $TOKEN"
curl "https://api-crpay.deskhotel.com.br/v1/payments?status=refused&limit=50" \
-H "Authorization: Bearer $TOKEN"
A paginação é por cursor. Use o next_cursor da resposta como parâmetro cursor da
chamada seguinte; null indica a última página.
Histórico do ciclo de vida:
curl https://api-crpay.deskhotel.com.br/v1/payments/$ID/events \
-H "Authorization: Bearer $TOKEN"
Estados
| Estado | Significado |
|---|---|
authorized |
Valor reservado no cartão, não capturado |
captured |
Valor efetivado |
refused |
A adquirente recusou |
canceled |
Autorização desfeita antes da captura |
refunded |
Valor devolvido integralmente |
partially_refunded |
Parte do valor devolvida |
unknown |
Resultado não confirmado — ver abaixo |
O estado unknown
Se a adquirente não responder a tempo, o crpay não adivinha. A requisição foi enviada e a resposta não chegou: não há como saber se a cobrança foi processada.
Nesse caso a resposta é 502 acquirer_unknown_state, com o payment_id da cobrança, e
ela fica em unknown.
Não repita com uma chave nova. A conciliação consulta a adquirente e resolve o
estado automaticamente — para captured ou refused, conforme o que de fato aconteceu.
Consulte a cobrança pelo payment_id até o estado mudar.
Repetir com chave nova nesse momento é justamente o que cobraria o cliente duas vezes.
Recusas
Cartão recusado devolve 402 com o motivo normalizado:
{
"error": {
"type": "card_error",
"code": "insufficient_funds",
"message": "Sem saldo disponível.",
"request_id": "req_01KYF...",
"payment_id": "pay_01KYF..."
}
}
O code é estável e independente da adquirente — insufficient_funds, invalid_cvv,
expired_card, card_blocked, entre outros. Programe contra ele.
Repetir a mesma requisição após uma recusa não muda o resultado. Ver Erros para a lista completa e a política de retentativa.