Checkout transparente com Stripe Elements
Num checkout transparente, o formulário do cartão fica na sua página: sem redirecionar para uma página hospedada, sem painel. O seu cliente digita o cartão em campos renderizados pelo Stripe; a Pilot Status credita a carteira ou salva o cartão. Use-o para abastecer um workspace — por exemplo, o workspace de cada cliente final quando você revende — de dentro do seu próprio produto. Os endpoints estão descritos em Carteira e cartão pela API. Este guia mostra como as peças se encaixam.Como funciona
- O seu servidor pede um intent à Pilot Status, com a API key.
- A sua página carrega o Stripe.js com a
publishableKeyda resposta, monta o Payment Element com oclientSecrete confirma com o Stripe. - O seu servidor chama o
sync, que lê o resultado no Stripe e credita a carteira (ou salva o cartão) na hora.
publishableKey e os intents são nossos.
1. Seu servidor: crie o intent
Exponha uma rota no seu backend que chame a Pilot Status. Com uma chave de conta, acrescentex-workspace-id para abastecer um workspace específico.
server.js (Node 18+)
Idempotency-Key: gere um id por tentativa de checkout no navegador e reaproveite-o nas novas tentativas. Uma nova tentativa em até 24 horas recebe o mesmo intent de volta, em vez de um segundo pedido.503 PAYMENTS_NOT_CONFIGURED: pagamentos com cartão estão indisponíveis do nosso lado. Mostre outra opção — em workspaces em BRL, o Pix.
2. Sua página: monte o Payment Element e confirme
checkout.html
3. Seu servidor: sync e reação
Osync responde com o resultado na hora:
orderStatus: "COMPLETED"— a carteira já tem o dinheiro.creditedétruena chamada que creditou, ebalanceé o novo saldo.orderStatus: "PENDING"— o Stripe ainda não confirmou. Não faça nada: quando o Stripe confirmar, nós creditamos a carteira por conta própria.orderStatus: "FAILED"— o pagamento foi cancelado. Comece uma nova tentativa com uma novaIdempotency-Key.
sync, seja pelo nosso próprio aviso do Stripe. Para saber disso do seu lado sem consultar em loop, inscreva um webhook do workspace em wallet.topup_paid: ele dispara uma vez por recarga creditada, seja Pix ou cartão.
Erro no navegador, mas cobrou
Ostripe.confirmPayment pode voltar com um erro de rede mesmo quando a Stripe já cobrou o cartão — a conexão caiu depois da cobrança e antes de a resposta chegar ao navegador. Isso aconteceu em produção em 29/10/2026.
Nunca mostre “pagamento recusado” só por esse erro. Para um error do tipo api_connection_error (ou qualquer erro que não seja recusa do cartão), confira com o servidor antes de dizer qualquer coisa ao cliente:
- Consulte o
POST /v1/billing/payment-intents/{paymentIntentId}/sync— ou oGET /v1/billing/topups/{orderId}, com oorderIddo passo 1 — a cada 2–3 segundos, por cerca de 30 segundos. - Pare assim que o
syncresponderorderStatus: "COMPLETED"(ou a recarga responderstatus: "paid"): o pagamento foi aprovado. - Se ainda estiver pendente depois de ~30 s, diga ao cliente que o pagamento está sendo confirmado, não que falhou. Só mostre falha quando o
syncresponderorderStatus: "FAILED"(ou a recarga,status: "failed").
Salvar um cartão sem cobrar
O fluxo é o mesmo com um setup intent:- Servidor:
POST /v1/billing/card/setup-intentsem corpo →clientSecret,setupIntentId,publishableKey. - Página:
stripe.elements({ clientSecret }), monte"payment", depoisstripe.confirmSetup({ elements, redirect: "if_required" }). - Servidor:
POST /v1/billing/card/setup-intent/{setupIntentId}/sync→saved: truee ocard(bandeira, 4 últimos dígitos, validade).
Testes
Use os cartões de teste do Stripe só num ambiente cujapublishableKey comece com pk_test_. Em produção (pk_live_), todo pagamento confirmado é uma cobrança real.