Pagamentos com cartão
Aceite Visa, Mastercard, American Express, Elo, Hipercard e as outras grandes bandeiras por uma página de pagamento hospedada pela I4Tpay — nenhum dado de cartão passa pelos seus servidores, e o 3D Secure é tratado automaticamente.
#O fluxo, de relance
1. POST /v1/payments ──────▶ a I4Tpay devolve transactionId + status WAITING_PAYMENT
2. GET /v1/payments/{id} ───▶ em ~1 s, o cardRedirectUrl vem preenchido
3. Redirecione o cliente (ou abra num iframe) para o cardRedirectUrl
4. O cliente digita os dados do cartão e conclui o desafio 3DS na página segura da I4Tpay
5. O cliente volta para o seu returnUrl (com sucesso ou com falha)
6. O webhook payment.completed (ou payment.failed) confirma o resultado — confie no webhook, não no redirectPor que um redirect? Ele mantém os dados do portador do cartão totalmente fora da sua infraestrutura. A sua aplicação — backend ou frontend — nunca vê PAN, CVV nem validade. O processador da I4Tpay cuida do 3DS, da tokenização e da análise antifraude do nosso lado.
#1. Criar a cobrança
Endpoint POST /v1/payments
curl -X POST https://i4tpay.beta.zentry.cloud/v1/payments \
-H "apikey: $I4TPAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 8990,
"currency": "EUR",
"paymentMethods": ["CREDIT_CARD"],
"customerName": "João Costa",
"customerEmail": "joao@example.com",
"metadata": {
"orderId": "ORD-9821",
"returnUrl": "https://shop.example.com/orders/9821/return"
},
"idempotencyKey": "ORD-9821"
}'| Campo | Observação |
|---|---|
amount | Menor unidade (centavos). 8990 = € 89,90. |
currency | BRL, EUR ou USD (outras moedas sob pedido). |
paymentMethods | ["CREDIT_CARD"] |
metadata.returnUrl | Para onde mandar o cliente quando ele terminar (com sucesso ou com falha). |
customerEmail | Muito recomendado — usado no comprovante, nos sinais de fraude e como prova na contestação de chargeback. |
Resposta 201 Created
{
"id": "b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
"status": "WAITING_PAYMENT",
"amount": 8990,
"currency": "EUR",
"paymentMethods": ["CREDIT_CARD"],
"createdAt": "2026-04-25T15:50:11.000Z"
}#2. Redirecionar o cliente
Consulte a transação quando o cardRedirectUrl estiver preenchido (normalmente em menos de 1 s):
curl https://i4tpay.beta.zentry.cloud/v1/payments/b2c3d4e5-f6a7-4890-9bcd-ef0123456789 \
-H "apikey: $I4TPAY_API_KEY"{
"id": "b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
"status": "WAITING_PAYMENT",
"amount": 8990,
"currency": "EUR",
"cardRedirectUrl": "https://checkout.i4tpay.beta.zentry.cloud/c/b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
"createdAt": "2026-04-25T15:50:11.000Z"
}Mande o cliente para o cardRedirectUrl:
<a href="{{ cardRedirectUrl }}">Pagar com cartão</a>Ou faça um 302 Found no servidor:
res.redirect(303, transaction.cardRedirectUrl);Quando o cliente conclui o fluxo (ou desiste), ele volta para o metadata.returnUrl que você informou — com ?transactionId=...&status=... no final. Não confie nesses parâmetros de query. Eles são só informativos — espere o webhook antes de liberar o pedido.
#3. Confirmar pelo webhook
{
"event": "payment.completed",
"data": {
"transactionId": "b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
"amount": 8990,
"status": "APPROVED",
"previousStatus": "PROCESSING",
"paidWith": "CREDIT_CARD",
"providerFee": 280,
"platformFee": 90,
"netAmount": 8620,
"occurredAt": "2026-04-25T15:52:34.000Z"
}
}No cartão, o status de sucesso é APPROVED (não PAID). Os dois eventos chegam como payment.completed, então um handler só cobre os dois.
Recusas de cartão chegam como payment.failed, com data.status ∈ REFUSED, EXPIRED, CANCELLED. Os motivos de recusa mais comuns (quando o emissor informa) vêm repetidos em data.declineReason.
#Ciclo de vida
WAITING_PAYMENT ──▶ PROCESSING ──▶ APPROVED ✓ libere o pedido
──▶ REFUSED o emissor recusou
──▶ CANCELLED o cliente desistiu
──▶ EXPIRED o link de redirect venceu (24h)Depois da liquidação (D+1 a D+30, conforme a bandeira e o seu contrato), você também pode ver:
APPROVED ──▶ CHARGEBACK o emissor abriu um chargeback
APPROVED ──▶ DISPUTE o portador do cartão abriu uma disputa
APPROVED ──▶ REFUNDED você (ou a I4Tpay) fez um reembolsoCada um dispara um webhook, para você sincronizar o estado do pedido.
#Cartões de teste
No sandbox, a página de redirect aceita estes números determinísticos (qualquer validade futura, qualquer CVV):
| Número | Resultado |
|---|---|
4111 1111 1111 1111 | Sempre APPROVED |
4000 0000 0000 0002 | Sempre REFUSED — recusa genérica |
4000 0000 0000 0069 | Sempre REFUSED — cartão vencido |
4000 0000 0000 9995 | Sempre REFUSED — saldo insuficiente |
4000 0000 0000 3220 | Dispara o desafio 3DS e depois APPROVED |
Veja a lista completa em Sandbox.
#Perguntas frequentes
P: Dá para manter o cliente no meu domínio? R: Na fase 2 vamos lançar um widget incorporável (iframe + tokenizador) que mantém a sua marca e continua deixando os dados do portador do cartão fora da sua infraestrutura. Por enquanto: redirect hospedado.
P: Vocês aceitam cartão salvo? R: Sim, mas isso exige que o seu lado tenha a própria certificação de conformidade de segurança de dados de cartão. Escreva para suporte@i4tpay.beta.zentry.cloud para habilitar a Vault API.
P: Qual versão do 3DS é usada? R: 3DS 2.x, com fluxo sem fricção quando o emissor permite. A Autenticação Forte do Cliente (SCA) é obrigatória em EUR — isso é imposto no servidor.
P: E reembolso?
R: Tem — POST /v1/payments/{id}/refund, total ou parcial. Reembolso de cartão liquida pela Stripe. Veja a Referência da API.
P: Meu cliente foi cobrado, mas o webhook nunca chegou.
R: Confira GET /v1/webhooks/deliveries — provavelmente tentamos e o seu endpoint respondeu algo fora de 2xx. Fazemos até 10 retentativas. Depois disso, fale com o suporte para reenviar.