Pular para o conteúdo principal

PDV — Pagamento via QR impresso + PIN

Rota regional (wallet-api, /v1/events/{eventId}/...), pra participante sem o app: o caixa já emitiu a credencial (ver Caixa → credencial QR impressa com PIN); o PDV lê o QR, informa o valor e pede o PIN pro participante digitar.

EndpointO que faz
POST /v1/events/{eventId}/pdv/paymentsDebita a wallet do participante pelo valor informado, credita a conta EVENT_REVENUE do evento, tudo na mesma transação.
curl -X POST http://127.0.0.1:8787/v1/events/{eventId}/pdv/payments \
-H "Authorization: Bearer <accessToken do PDV>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: <uuid gerado pelo cliente>" \
-d '{
"qrPayload": "wallet://credential?v=1&event=<eventId>&credential=<token do QR>",
"pin": "482913",
"amountMinor": 2500
}'
Resposta
{
"walletId": "018f26d7-...",
"eventId": "018f26d7-...",
"availableAmountMinor": 16750,
"replayed": false
}

O que o endpoint verifica, nessa ordem:

  1. O QR é deste evento? O qrPayload carrega o próprio eventId dentro dele — se não bater com o evento da URL, a resposta é 404 CREDENTIAL_NOT_FOUND, igual a um QR desconhecido (nunca revela que o token existe, só que é de outro evento).
  2. A credencial está ativa, não expirou e não está bloqueada? Senão, 409 CREDENTIAL_NOT_ACTIVE / 409 CREDENTIAL_EXPIRED / 403 CREDENTIAL_LOCKED.
  3. O PIN confere? Se não, 403 INVALID_PIN — e essa tentativa fica registrada na credencial. 5 tentativas erradas seguidas bloqueiam a credencial por 15 minutos (403 CREDENTIAL_LOCKED); o participante precisa esperar ou o caixa reemitir uma credencial nova.
  4. Tem saldo suficiente? Senão, 409 INSUFFICIENT_BALANCE.

A wallet fica travada durante toda a verificação + débito — se dois PDVs tentarem cobrar a mesma wallet ao mesmo tempo (ou uma recarga e uma cobrança coincidirem), uma espera a outra terminar; nunca rodam em paralelo.

Exige o header Idempotency-Key, com o mesmo comportamento do recarga do caixa: repetir a mesma chave devolve o mesmo resultado sem cobrar duas vezes (replayed: true na resposta, pra deixar claro que não foi cobrado de novo), e uma segunda chamada com a mesma chave enquanto a primeira ainda está em andamento recebe 409 IDEMPOTENCY_KEY_IN_PROGRESS. Reusar a mesma chave com um valor ou QR diferente vira 409 IDEMPOTENCY_KEY_BODY_MISMATCH em vez de cobrar (ou devolver) o valor errado — gere uma chave nova a cada cobrança.