Carteiras no seu checkout
Apple Pay e Google Pay dentro da sua tela de pagamento, sem registrar domínio, emitir certificado nem tratar o token da carteira.
Apple Pay e Google Pay na sua tela de pagamento, sem você registrar domínio na Apple, submeter nada ao Google, emitir certificado ou tirar print de folha de pagamento.
O que torna isso possível é um detalhe das duas carteiras: elas validam a sessão contra o host que a pede. Os botões rodam num componente nosso, servido de um domínio que já está verificado nas duas, então quem a Apple e o Google veem somos nós. Você diz onde quer os botões.
O fluxo em três passos
- Seu backend cria a intenção de pagamento.
- Sua página monta os botões naquela intenção.
- O desfecho chega por callback (para mover a tela) e por webhook (para mover o pedido).
1. A intenção, no seu backend
A intenção crava valor e estabelecimento antes de a folha abrir. Ela existe porque o navegador não pode decidir o valor: a folha mostraria um número e a cobrança cobraria outro, e isso aconteceria no nosso domínio, sob a nossa identidade de comerciante.
curl -X POST "https://bunne.com.br/api/v1/payment-intents" \ -H "Authorization: Bearer $SK" \ -H "Idempotency-Key: pedido-48219" \ -H "Content-Type: application/json" \ -d '{ "amount_cents": 10000, "metadata": { "pedido": "48219" } }'# -> { "id": "pi_...", "expires_at": "..." }# O "id" e o handle. Nao ha nada para o comprador abrir: ele paga na sua tela.Use a sua sk_, sempre no servidor. Ela é de uso único e expira sozinha: crie uma quando a etapa de pagamento renderizar, e não se preocupe com as que o comprador abandonar.
Não existe campo de parcelas. A grade que o comprador vê é herdada do que o estabelecimento configurou, do que a adquirente aceita e do próprio valor — nenhuma parcela é oferecida abaixo de R$ 5,00, então uma venda de R$ 12,00 abre no máximo 2x.
2. Os botões, na sua página
<div id="carteiras"></div><script src="https://bunne.com.br/sdk/v1/checkout.js"></script><script> const client = CheckoutSDK.create({ baseUrl: "https://bunne.com.br", apiKey: "pk_live_...", // publica: pode ficar no HTML }); client.mountWallets("#carteiras", { handle: "pi_...", // o id que seu backend criou // Quem coleta CPF/CNPJ e pais. Passe false se o SEU checkout ja pede, e // entao mande o dado por update(): nenhum campo nosso aparece dentro do // seu layout, nem quando falta. collectIdentity: false, document: "12345678909", country: "BR", onPaid: ({ charge }) => { // Avance a TELA. Nao marque o pedido como pago aqui: ver o passo 3. mostrarObrigado(charge); }, onFallback: () => { // O comprador recusou a carteira. Mostre o SEU formulario de cartao. abrirFormularioDeCartao(); }, onFailed: ({ reason }) => { // "document_required": o comprador tocou no botao e o documento nao chegou. // Com collectIdentity: false quem pede e o SEU campo — nada e desenhado // aqui dentro. Aponte o seu, e depois chame update({ document }). if (reason === "document_required") return apontarCampoDeCpf(); mostrarErro(reason); }, });</script>A pk_ é pública e não cobra, não lê e não tokeniza — por isso pode ficar no HTML. O componente desenha país, documento, parcelas e os botões: a parcela é escolhida antes da carteira, porque é ela que define o valor que a folha vai mostrar.
Uma exigência do navegador que vale saber antes de debugar: a permissão que libera carteira em componente de outra origem é delegada um nível por vez. Se o seu checkout roda dentro de um iframe — motor de reservas faz muito isso —, todo ancestral precisa repassá-la, e isso o nosso código não consegue fazer de dentro.
3. O desfecho
onPaid serve para avançar a tela. Quem marca o pedido como pago é o webhook: ele chega no seu servidor, não depende do navegador do comprador continuar aberto, e não pode ser forjado por quem mexer no front.
POST https://seu-backend.com.br/webhooks/pagamentos{ "type": "charge.paid", "data": { "id": "ch_...", "amount": 10000, "payment_method": "CREDIT_CARD", "metadata": { "pedido": "48219" } }}O metadata que você enviou na intenção viaja até a cobrança — é por ele que você sabe qual pedido fechou.
onFallback dispara quando o comprador recusa a carteira e quer pagar de outro jeito. O componente não oferece formulário de cartão de propósito: o seu checkout já tem o dele, e é para ele que esse aviso serve.
Se os botões não aparecerem
O componente só desenha em páginas cuja origem está autorizada, e isso é configurado no seu cadastro, não por você. Se o espaço ficar vazio, fale com o time da Bunne com a URL onde você está embutindo.
Ele também não desenha quando a intenção já foi usada ou expirou — o que é o esperado, porque cada intenção paga uma vez.
Precisa do fluxo completo de cartão? Veja Fluxo completo. Se o que você quer é não ter tela de pagamento nenhuma, o link de pagamento já resolve sozinho.