Documentação da plataforma
Para quem vende e para quem integra: o produto sem código e a API, cada tópico em sua página.
API de cartão
Cobre qualquer valor direto do seu servidor, sem cadastrar produto na 3B. Em real, cartão e PIX pela Pagar.me; nas outras moedas, pelo checkout da Whop. Taxas, reserva e repasse continuam os da sua conta.
Antes de começar
- 1Gere a sua chave. No painel, em Integrações → API de cartão, clique em Gerar chave. Ela começa com
3bsk_live_e aparece uma vez só: copie na hora. Perdeu? Gere outra, e a anterior para de funcionar. - 2Use a chave só no servidor. Ela autoriza cobranças em nome da sua loja. Nunca coloque na página, no app ou no repositório. Toda chamada leva o cabeçalho
Authorization: Bearer 3bsk_live_....
brl vai pela Pagar.me (cartão e PIX), as outras 15 moedas vão pela Whop. Consulte routes no GET ?config=1 para ver a rota da sua conta./api-charges?config=1Chave pública da Pagar.me, rota por moeda e limites.curl https://api.pag3b.com/v1/api-charges?config=1 \
-H "Authorization: Bearer $SUA_CHAVE_3B"
# resposta
{
"pagarmePublicKey": "pk_...", // para tokenizar o cartão na página
"routes": { "brl": "pagarme", "usd": "whop", "eur": "whop", ... },
"pagarmePaymentMethods": ["credit_card", "pix"],
"minAmount": 500, // centavos
"maxAmount": 1000000
}Cartão em real (Pagar.me)
São dois passos. 1. Na sua página, o navegador transforma o cartão em um cardToken direto na Pagar.me, com a chave pública. 2. Seu servidor chama a 3B com o token e o valor. O número do cartão nunca passa pelo seu servidor nem pelo nosso, e é isso que mantém você fora do escopo PCI.
<!-- Na SUA página: o cartão vai direto do navegador para a Pagar.me.
Nem o seu servidor nem a 3B recebem o número do cartão. -->
<script>
const PAGARME_PUBLIC_KEY = 'pk_...' // vem do GET ?config=1
async function tokenizarCartao({ numero, nome, mes, ano, cvv }) {
const r = await fetch(
'https://api.pagar.me/core/v5/tokens?appId=' + PAGARME_PUBLIC_KEY,
{
method: 'POST',
// Só Content-Type. Não mande Authorization aqui.
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'card',
card: {
number: numero.replace(/\D/g, ''),
holder_name: nome,
exp_month: Number(mes),
exp_year: Number(ano),
cvv,
},
}),
},
)
const dados = await r.json()
if (!r.ok || !dados.id) throw new Error('Cartão inválido')
return dados.id // "token_..." (vale 60 segundos)
}
</script>/api-chargesCobra o cartão tokenizado.curl -X POST https://api.pag3b.com/v1/api-charges \
-H "Authorization: Bearer $SUA_CHAVE_3B" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-123" \
-d '{
"amount": 4990,
"currency": "brl",
"description": "Plano Premium",
"reference": "pedido-123",
"paymentMethod": "credit_card",
"cardToken": "token_...",
"installments": 1,
"customer": {
"name": "Maria Silva",
"email": "maria@email.com",
"document": "12345678909",
"phone": "11987654321"
},
"billingAddress": {
"street": "Avenida Paulista",
"number": "1000",
"neighborhood": "Bela Vista",
"postalCode": "01310-100",
"city": "São Paulo",
"state": "SP"
}
}'
# resposta (200 aprovado, 402 recusado)
{
"id": "1e0bc2b4-...", // id da cobrança na 3B
"provider": "pagarme",
"status": "paid", // paid | failed | pending
"amount": 4990,
"currency": "brl",
"reference": "pedido-123",
"sellerAmount": 3942, // o que fica com você (estimado)
"platformFee": 549, // taxa da 3B
"reserve": 499, // reserva (liberada em 90 dias)
"declineReason": null // motivo, quando recusado
}billingAddress é obrigatório no cartão (sem ele a Pagar.me recusa todas as cobranças). installments vai de 1 a 12. Mandar o número do cartão no corpo é recusado.PIX em real (Pagar.me)
Mande paymentMethod: "pix" com o CPF ou CNPJ e o celular com DDD do comprador (os dois são exigidos pela Pagar.me). A resposta traz o copia e cola e a imagem do QR. O PIX vence em 1 hora.
/api-chargesGera um PIX.curl -X POST https://api.pag3b.com/v1/api-charges \
-H "Authorization: Bearer $SUA_CHAVE_3B" \
-H "Content-Type: application/json" \
-d '{
"amount": 4990,
"currency": "brl",
"description": "Plano Premium",
"reference": "pedido-124",
"paymentMethod": "pix",
"customer": {
"name": "Maria Silva",
"email": "maria@email.com",
"document": "12345678909",
"phone": "11987654321"
}
}'
# resposta
{
"id": "5b1c...",
"provider": "pagarme",
"status": "pending",
"pix": {
"qrCode": "00020101021226...", // copia e cola
"qrCodeUrl": "https://api.pagar.me/.../qrcode",
"expiresAt": "2026-09-23T00:06:48.000Z" // 1 hora
}
}Outras moedas (Whop)
Em dólar, euro e nas demais moedas a cobrança sai pela Whop, que não aceita cartão tokenizado por API: o comprador paga no checkout dela. A API cria a cobrança com o seu valor e devolve o planId e um link. Você manda o comprador para o link, ou embute o checkout na sua página. Cartão, Apple Pay, Google Pay e os métodos locais aparecem sozinhos.
/api-chargesCria a cobrança na Whop.curl -X POST https://api.pag3b.com/v1/api-charges \
-H "Authorization: Bearer $SUA_CHAVE_3B" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-125" \
-d '{
"amount": 2990,
"currency": "usd",
"description": "Premium Plan",
"reference": "pedido-125",
"successUrl": "https://seusite.com/obrigado?pedido=pedido-125"
}'
# resposta
{
"id": "plan_ypUwc51E4CGMi",
"provider": "whop",
"status": "awaiting_payment",
"amount": 2990,
"currency": "usd",
"successUrl": "https://seusite.com/obrigado?pedido=pedido-125",
"checkout": {
"planId": "plan_ypUwc51E4CGMi",
"url": "https://whop.com/checkout/plan_ypUwc51E4CGMi?..."
}
}<!-- Checkout embutido na SUA página, com o planId que a API devolveu (Whop Elements) -->
<script src="https://cdn.whop.com/elements/amber/elements.js" data-whop-elements></script>
<div id="checkout"></div>
<script type="module">
const checkout = window.WhopElements().checkout.create({
plan: "plan_ypUwc51E4CGMi",
returnUrl: "https://seusite.com/obrigado",
});
checkout.create("checkout", { buyerEmail: "maria@email.com" }).mount("#checkout");
</script>// npm install @whop/elements @whop/elements-react
import { loadWhop } from "@whop/elements";
import { WhopElements, Checkout, CheckoutElement } from "@whop/elements-react";
const whop = loadWhop();
export function Pagamento({ planId }: { planId: string }) {
return (
<WhopElements elements={whop} locale="pt">
<Checkout plan={planId} returnUrl="https://seusite.com/obrigado">
<CheckoutElement buyerEmail="maria@email.com" />
</Checkout>
</WhopElements>
);
}js.whop.com/static/checkout/loader.js (e o @whop/checkout) parou de funcionar em 21/10/2026, por decisão da Whop. Quem embute o checkout troca pelo código acima (Whop Elements), com o mesmo planId. O link checkout.url segue funcionando sem mudança.cardToken, billingAddress nem paymentMethod: quem coleta é o checkout da Whop. A cobrança fica awaiting_payment até o comprador pagar; aí nasce o pedido, com o mesmo reference. Crie uma cobrança por compra.successUrl (URL https completa) na criação e use o checkout.url que a resposta devolve: paga a compra, o comprador sai da Whop e cai nessa página. Sem o campo, ele fica na tela de confirmação da Whop. No checkout embutido, quem faz isso é o returnUrl: a página recebe ?payment=pay_...&status=succeeded (ou failed, canceled), então confira o status. ⚠️ Chegar na página de retorno não prova o pagamento: libere o acesso pelo webhook ou consultando o status.Consultar o status
Por id (o da 3B, ou o plan_ da Whop) ou pela sua reference. Status possíveis: pending, awaiting_payment (Whop, ainda não pago), paid, failed, expired (PIX vencido), refunded.
/api-charges?id= | ?reference=Status de uma cobrança.curl "https://api.pag3b.com/v1/api-charges?id=1e0bc2b4-..." -H "Authorization: Bearer $SUA_CHAVE_3B"
curl "https://api.pag3b.com/v1/api-charges?id=plan_ypUwc51E4CGMi" -H "Authorization: Bearer $SUA_CHAVE_3B"
curl "https://api.pag3b.com/v1/api-charges?reference=pedido-123" -H "Authorization: Bearer $SUA_CHAVE_3B"Aviso de venda paga
status: "paid" na resposta do cartão é o que a adquirente respondeu na hora. A venda é confirmada segundos depois, pelo aviso da adquirente para a 3B. Para liberar o acesso sem ficar consultando, ligue o webhook em Integrações: ele chega assinado, com api_charge: true e o seu reference dentro do pedido. Veja como conferir a assinatura em Webhooks e eventos. Na cobrança pela API a 3B não envia e-mail de acesso ao comprador: a entrega é sua.
Idempotência e limites
Mande o cabeçalho Idempotency-Key com um valor único por compra (o id do seu pedido serve). Se a chamada for repetida com a mesma chave, a 3B devolve a mesma cobrança com idempotentReplay: true e não cobra de novo, inclusive quando a primeira foi recusada: para tentar outro cartão, use outra chave. Limites: de 5,00 a 10.000,00 por cobrança e 60 cobranças por minuto.
Erros
unauthorizedChave ausente, errada ou trocada.api_not_enabledA API foi bloqueada para a sua conta.seller_not_approvedO cadastro da conta ainda não foi aprovado.amount_out_of_rangeValor fora do limite (em centavos).currency_not_supportedMoeda que a 3B não vende.billing_address_requiredCartão sem endereço de cobrança completo.document_requiredCobrança em real sem o CPF ou CNPJ do comprador (PIX e cartão).phone_requiredSem o celular do comprador (obrigatório no PIX e no cartão).charge_failedA processadora ou o banco recusou. Veja declineReason.route_not_readyA sua conta ainda não está pronta nessa adquirente.amount_too_lowO valor não cobre as taxas.rate_limitedMais de 60 cobranças por minuto.
