Hotelaria (reservas)
Informe a reserva na cobrança e no link: campos, pré-requisitos de permissão e o que muda no recebimento.
Se você vende hospedagem, pode informar a reserva na cobrança: check-in, check-out, número da reserva e canal de venda. Com isso a venda deixa de ser uma cobrança anônima e passa a carregar a estadia que ela paga.
Antes de integrar: dois pré-requisitos
O objeto reservation só é aceito quando as duas condições abaixo valem. Elas são configuradas pela plataforma, não pela API — peça ao seu contato comercial antes de começar.
- O token tem a permissão. Enviar
reservationexigecharges:createna chave usada (epayment_links:createpara links de pagamento). Sem a permissão a requisição volta403 insufficient_permissions, antes de qualquer validação da reserva. - O estabelecimento está habilitado para hotelaria. Cada seller é habilitado individualmente. Com o módulo desligado, a requisição volta
422 reservation_not_supportede nenhuma cobrança é criada.
Enquanto os dois não estiverem prontos, envie a cobrança sem o objeto reservation: ela funciona normalmente. Você pode integrar o resto do fluxo e ligar a reserva depois, sem mudar mais nada.
O que a reserva muda no seu recebimento
Dependendo da condição comercial contratada pelo estabelecimento, o dinheiro de uma venda com reserva pode ser liberado em função da data da estadia, e não da data do pagamento — por exemplo, um dia após o check-in.
Duas garantias que valem sempre, independentemente da condição contratada:
- A reserva nunca antecipa o recebimento. Ela só pode adiar. Uma reserva com check-in próximo recebe exatamente no prazo normal do plano.
- Cobrança sem
reservationnão é afetada. Diária avulsa, consumo, restaurante: tudo segue o prazo normal, mesmo num estabelecimento habilitado para hotelaria.
A data efetiva de cada recebível continua sendo a que a API de recebíveis e o painel já mostram — você não precisa calcular nada.
Campos
check_inecheck_out— obrigatórios os dois, no formatoAAAA-MM-DD(data, sem hora).check_outtem que ser igual ou posterior aocheck_in; iguais significam day use.code— o número da reserva no seu PMS ou na OTA. Não precisa ser único: depósito e saldo da mesma reserva são duas cobranças com o mesmo código, e é assim que elas se reencontram.channel— de onde veio a venda. O catálogo é da sua plataforma; um código desconhecido é recusado e a resposta lista os válidos.rate_type,guarantee_nights,guest_name— opcionais e informativos. Ver "O que a plataforma NÃO faz" abaixo.
Cobrança com reserva
curl -X POST $API_BASE_URL/charges \ -H "Authorization: Bearer sk_live_xxx" \ -H "Idempotency-Key: reserva_BK-4471902_deposito" \ -H "Content-Type: application/json" \ -d '{ "amount": 125000, "payment_method": "CREDIT_CARD", "installments": 1, "card_token": "tok_xxx", "buyer": { "name": "Ada Lovelace", "email": "ada@example.com", "phone": "5511999990000", "document": "12345678909", "address": { "line_1": "Av. Paulista, 1000", "zip_code": "01310-100", "city": "Sao Paulo", "state": "SP", "country": "BR" } }, "reservation": { "check_in": "2026-11-20", "check_out": "2026-11-23", "code": "BK-4471902", "channel": "BOOKING", "rate_type": "non_refundable", "guarantee_nights": 2, "guest_name": "Ada Lovelace" } }'Resposta
A cobrança devolve a reserva de volta, com nights calculado. Uma cobrança sem reserva não ganha a chave reservation — a resposta continua idêntica à de sempre.
{ "object": "charge", "id": "ch_xxx", "status": "paid", "amount_cents": 125000, "currency": "BRL", "payment_method": "credit_card", "installments": 1, "reservation": { "id": "resv_xxx", "object": "reservation", "check_in": "2026-11-20", "check_out": "2026-11-23", "nights": 3, "code": "BK-4471902", "channel": "BOOKING", "status": "confirmed", "rate_type": "non_refundable", "guarantee_nights": 2, "guest_name": "Ada Lovelace" }, "request_id": "req_xxx"}Link de pagamento com reserva
Se a sua central de reservas cobra por link, o mesmo objeto vale em POST /payment-links. A reserva vira o produto: a página de pagamento e o comprovante mostram a estadia e o número da reserva no lugar de um nome genérico.
curl -X POST $API_BASE_URL/payment-links \ -H "Authorization: Bearer sk_live_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Reserva BK-4471902 — Suite Master", "amount_cents": 125000, "payment_methods": ["CREDIT_CARD", "PIX"], "max_installments": 3, "reservation": { "check_in": "2026-11-20", "check_out": "2026-11-23", "code": "BK-4471902", "channel": "CENTRAL_RESERVAS" } }'Quando o link é pago, a reserva é copiada para a cobrança gerada. A validação acontece na criação do link: mudanças de catálogo depois disso nunca derrubam o checkout de um hóspede.
Quando a reserva muda
Remarcação, cancelamento ou no-show: informe pela API e a plataforma reprograma o que ainda não foi liberado.
curl -X PATCH $API_BASE_URL/charges/ch_xxx/reservation \ -H "Authorization: Bearer sk_live_xxx" \ -H "Content-Type: application/json" \ -d '{ "check_in": "2026-12-05", "check_out": "2026-12-08" }'{ "object": "reservation_update", "charge_id": "ch_xxx", "reservation_id": "resv_xxx", "rescheduled_receivables": 2, "already_released_receivables": 1, "request_id": "req_xxx"}already_released_receivables conta os recebíveis que já tinham sido liberados e por isso não foram tocados: dinheiro já disponível para o estabelecimento não volta atrás. Se esse número vier maior que zero, a informação chegou depois da liberação — e é isso que a resposta está te dizendo.
Envie só o que mudou. Os campos ausentes ficam como estão.
O que a plataforma NÃO faz
Status da reserva é informação, não dinheiro
Enviar status: "canceled" ou "no_show" não estorna nada e não antecipa nenhuma liberação. rate_type e guarantee_nights também não disparam nada sozinhos.
A política de tarifa é sua: se a reserva cancelada tem que devolver dinheiro (todo ou em parte), faça o estorno pelo fluxo normal — POST /charges/{id}/refund, total ou parcial. A plataforma não decide por você quanto devolver.
Erros
reservation_not_supported (422) — o estabelecimento não está habilitado para hotelaria. Nenhuma cobrança é criada.
{ "error": { "type": "validation_error", "code": "reservation_not_supported", "message": "This seller is not enabled for hospitality reservations.", "param": "reservation" }, "request_id": "req_xxx"}unknown_reservation_channel (422) — canal fora do catálogo, ou desativado. Os códigos válidos vêm em details.valid_channels.
{ "error": { "type": "validation_error", "code": "unknown_reservation_channel", "message": "Unknown reservation channel for this white label.", "param": "reservation.channel", "details": { "valid_channels": [ "BOOKING", "DECOLAR", "EXPEDIA", "CENTRAL_RESERVAS", "IA", "MOTOR_RESERVAS" ] } }, "request_id": "req_xxx"}reservation_horizon_exceeded (422) — check-in longe demais no futuro. Quase sempre é o ano trocado no PMS. O limite vem em details.max_horizon_days.
invalid_request (422) — data que não existe no calendário, check_out antes do check_in, ou campo desconhecido dentro de reservation.
Onde a reserva aparece depois
- No detalhe da transação, no painel — número, estadia, canal e situação.
- Na busca de transações: procure pelo número da reserva, não só pelo id da cobrança.
- No recebível, com a explicação da data de liberação quando ela vem da reserva.