AstroDocsQuero acesso antecipado

Checkout transparente

Venda dentro do seu app com o checkout embutido, o componente de pagamento ou a API headless.

Disponibilidade: o checkout transparente está em preparação para o lançamento. O endpoint público do SDK ainda não está disponível; esta página é uma prévia técnica e não deve ser usada em produção enquanto este aviso estiver visível.

No checkout hospedado, o Astro devolve o link do checkout publicado e o comprador paga lá. No checkout transparente, a compra acontece dentro do seu app: você integra os componentes ou a API de pagamentos do Astro no seu frontend, e o usuário nunca troca de página.

Existem três formas de integrar. As três usam a mesma sessão criada pelo seu servidor:

Forma Como fica Quando usar
Checkout embutido O checkout completo (resumo, cupom, dados e pagamento) dentro de um bloco do seu app. Integração mais rápida.
Componente de pagamento Só as formas de pagamento. O resumo e o botão “Assinar” são seus. Você já tem uma tela de plano e quer só o pagamento.
Headless Nenhum componente do Astro: o seu frontend chama a API da sessão. Controle total do layout.

Nas duas primeiras, o Astro desenha o pagamento num quadro seguro (iframe) dentro da sua página. Os dados do cartão vão direto para o gateway e nunca passam pelo seu app nem pelo Astro.

1. Autorize o domínio do seu app

Em Desenvolvedores → Domínios do app, informe o endereço exato do seu app, por exemplo https://app.suaempresa.com. Só esses domínios podem exibir o checkout embutido e chamar a API da sessão pelo navegador. Para testar na sua máquina, http://localhost:5173 também é aceito.

2. Crie a sessão no seu servidor

Com uma chave de API com o escopo checkout_sessions.write, crie a sessão quando o usuário clicar em assinar. A chave nunca pode ir para o navegador.

curl -X POST https://api.seudominio.com/developer/v1/checkout-sessions \
  -H "x-api-key: $ASTRO_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "checkout": "meu-plano",
    "items": [{ "priceId": "pri_...", "quantity": 1 }],
    "uiMode": "embedded",
    "externalReference": "id-do-usuario-no-seu-app",
    "customer": { "name": "Maria Souza", "email": "[email protected]" },
    "returnUrl": "https://app.suaempresa.com/assinatura/retorno"
  }'
Campo Para que serve
uiMode embedded para o checkout embutido e o componente de pagamento; custom para headless. hosted (padrão) devolve o link do checkout hospedado.
externalReference O id do usuário no seu app. Volta em todos os webhooks.
customer Opcional. Com ele, o checkout não pede nome e e-mail de novo.
returnUrl Opcional. Para onde o comprador volta quando o pagamento continua fora da página (PayPal). Precisa estar num domínio autorizado.

A resposta traz o clientSecret, que o seu frontend usa para operar só esta sessão:

{
  "data": {
    "id": "chs_...",
    "uiMode": "embedded",
    "clientSecret": "chs_..._secret_...",
    "expiresAt": "2026-11-05T15:30:00.000Z"
  }
}

Entregue o clientSecret ao frontend do usuário logado e não o registre em logs. Ele vale enquanto a sessão estiver aberta.

3a. Checkout embutido

<div id="pagamento"></div>
<!-- Substitua quando o painel do Astro fornecer a URL pública do SDK. -->
<script src="{{ASTRO_SDK_URL}}/v1/astro.js"></script>
<script>
  const checkout = Astro().checkout({ clientSecret });
  checkout
    .on("success", (payment) => mostrarObrigado(payment.orderId))
    .on("pending", () => mostrarAguardandoPix())
    .on("retry", () => criarNovaSessaoEMontarDeNovo())
    .mount("#pagamento");
</script>

O bloco ajusta a altura sozinho. Em React:

import { AstroCheckout } from "@astro/js/react";

<AstroCheckout clientSecret={clientSecret} onSuccess={() => router.push("/obrigado")} />;

3b. Componente de pagamento

Mostra só as formas de pagamento. O botão de finalizar é o do seu app:

const payment = Astro().payment({ clientSecret });
payment.mount("#pagamento");

botaoAssinar.addEventListener("click", async () => {
  const outcome = await payment.confirm();
  if (!outcome.ok) return mostrarErro(outcome.message); // ex.: dados do cartão incompletos
  if (outcome.status === "approved") return mostrarObrigado(outcome.orderId);
  // 'pending': Pix ou boleto emitido, aparece no próprio componente
});

3c. Headless

Sem componente: o seu frontend chama a API da sessão com o clientSecret. Use uiMode: "custom" na criação.

const session = Astro().session(clientSecret);
const { manifest } = await session.checkout(); // formas de pagamento disponíveis
await session.selectPaymentMethod("pay_pix");
await session.confirm();
const result = await session.waitForResult();
mostrarPix(result.payment.artifacts.pix.copyPaste, result.payment.artifacts.pix.qrCodeBase64);

Sem o SDK, as mesmas rotas aceitam Authorization: Bearer <clientSecret> em /public/v1/checkout-sessions/:id (/checkout, /customer, /select-payment-method, /apply-coupon, /confirm, /result).

Cartão no headless: a forma de pagamento com clientIntegration: "card_tokenization" traz cardTokenization.publicKey. Gere o token com o script do gateway no seu frontend (no Mercado Pago, o Card Payment Brick com essa chave) e envie em session.confirm({ card: { token, installments, paymentMethodId, issuerId } }). Os dados do cartão nunca passam pelo Astro. Se o seu app não pode carregar scripts de gateways, use o componente de pagamento.

Eventos

Evento Quando
ready O checkout carregou.
change O comprador escolheu outra forma de pagamento.
success Pagamento aprovado.
pending Pix ou boleto emitido, aguardando o pagamento.
failed Pagamento recusado ou expirado.
retry O comprador pediu para tentar de novo: crie outra sessão no servidor e monte de novo.
redirect O pagamento continua no site do gateway (PayPal). O SDK leva a janela do seu app até lá; chame event.preventDefault() para cuidar disso você mesmo.
error Falha de configuração (domínio não autorizado, sessão expirada).

Libere o acesso pelo webhook. Os eventos do navegador servem para a interface. Quem libera o plano é o webhook payment.approved no seu servidor, com o externalReference. Veja Webhooks.

Aparência

Por padrão, o componente usa o tema do checkout publicado. Para combinar com o seu app:

Astro().checkout({
  clientSecret,
  appearance: {
    variables: {
      colorPrimary: "#6048ee",
      colorBackground: "#ffffff",
      colorText: "#16161d",
      borderRadius: "10px",
      fontFamily: "Inter, sans-serif",
    },
  },
});

Para trocar depois de montado, use checkout.update({ appearance }).

Se o seu app tem CSP

Libere o Astro na política de segurança do seu app:

script-src {{ASTRO_SDK_ORIGIN}}
frame-src {{ASTRO_SDK_ORIGIN}}
connect-src {{ASTRO_SDK_ORIGIN}}   (só no headless)

Erros comuns

Código O que fazer
EMBED_ORIGIN_REQUIRED Autorize o domínio do app antes de criar sessões embedded ou custom.
EMBED_ORIGIN_NOT_ALLOWED A página que chamou não está em Domínios do app.
CHECKOUT_SESSION_SECRET_REQUIRED Envie o clientSecret desta sessão no Authorization: Bearer.
RETURN_URL_NOT_ALLOWED O returnUrl precisa estar num domínio autorizado.
CARD_TOKEN_REQUIRED No headless com cartão tokenizado, envie o card no confirm.
esc

Acesso rápido

↑↓ navegar↵ abriresc fechar