Checkout
Crie links de checkout personalizados para converter vendas.
Visão Geral
A API de Checkout permite criar links de pagamento personalizados. Seus clientes podem acessar o link e completar a compra de forma segura.
Endpoints
| Método | Endpoint | Auth | Descrição |
|---|---|---|---|
POST | /api/sdk/checkout/create-link | 🔒 SDK | Criar link de checkout |
GET | /api/sdk/checkout/:token | 🌐 Público | Buscar sessão |
POST | /api/sdk/checkout/:token/complete | 🌐 Público | Finalizar checkout |
Apenas create-link requer autenticação via API Keys. Os endpoints com :token são públicos — o token funciona como autenticação.
Criar Link de Checkout
POST /api/sdk/checkout/create-linkBody
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
productIds | string[] | ❌* | IDs dos produtos da loja |
items | array | ❌* | Itens customizados |
items[].title | string | ✅ | Título do item (max 200) |
items[].price | number | ✅ | Preço em centavos |
items[].quantity | number | ❌ | Quantidade (padrão: 1, max: 9999) |
items[].image | string | ❌ | URL da imagem |
items[].description | string | ❌ | Descrição (max 1000) |
items[].sku | string | ❌ | SKU do item |
successUrl | string | ❌ | URL de redirecionamento após sucesso |
cancelUrl | string | ❌ | URL de redirecionamento se cancelar |
customer | object | ❌ | Pré-preencher dados do cliente |
customer.email | string | ❌ | |
customer.name | string | ❌ | Nome |
customer.phone | string | ❌ | Telefone |
currency | string | ❌ | Moeda (padrão: BRL) |
expiresIn | number | ❌ | Expiração em minutos (5 a 10080) |
shipping | number | ❌ | Valor do frete em centavos |
couponCode | string | ❌ | Código de cupom (max 50) |
metadata | object | ❌ | Metadados (max 4KB) |
Você deve enviar productIds OU items, não ambos. Máximo de 50 itens por checkout.
Exemplo com Produtos
curl -X POST "https://api.plasmacheckout.com/api/sdk/checkout/create-link" \
-H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"productIds": ["cm5abc123def456ghi789", "cm5abc123def456ghi790"],
"successUrl": "https://meusite.com/obrigado",
"cancelUrl": "https://meusite.com/carrinho",
"expiresIn": 60
}'const response = await fetch(
'https://api.plasmacheckout.com/api/sdk/checkout/create-link',
{
method: 'POST',
headers: {
'X-PLASMA-Public-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxx',
'X-PLASMA-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
productIds: ['cm5abc123def456ghi789', 'cm5abc123def456ghi790'],
successUrl: 'https://meusite.com/obrigado',
cancelUrl: 'https://meusite.com/carrinho',
expiresIn: 60 // 60 minutos = 1 hora
})
}
);
const { data } = await response.json();
console.log(data.checkoutUrl); // URL para redirecionar o clienteExemplo com Itens Customizados
curl -X POST "https://api.plasmacheckout.com/api/sdk/checkout/create-link" \
-H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"title": "Consultoria 1 hora",
"price": 15000,
"quantity": 1
},
{
"title": "Material de apoio",
"price": 5000,
"quantity": 1
}
],
"customer": {
"email": "cliente@email.com",
"name": "João Silva"
},
"successUrl": "https://meusite.com/obrigado",
"metadata": {
"clienteId": "123",
"origem": "landing-page"
}
}'Resposta (201 Created)
{
"data": {
"id": "cm5session123abc456",
"token": "ck_lm7abc123xyz",
"status": "pending",
"checkoutUrl": "https://checkout.plasmacheckout.com/c/ck_lm7abc123xyz",
"items": [...],
"totals": {
"subtotal": 20000,
"shipping": 0,
"discount": 0,
"total": 20000
},
"currency": "BRL",
"customer": {
"email": "cliente@email.com",
"name": "João Silva",
"phone": null
},
"urls": {
"success": "https://meusite.com/obrigado",
"cancel": null
},
"environment": "live",
"expiresAt": "2025-01-15T11:00:00Z",
"createdAt": "2025-01-15T10:00:00Z"
}
}Buscar Sessão de Checkout
GET /api/sdk/checkout/:tokenEste endpoint é público e pode ser usado no frontend para exibir os detalhes do checkout.
Exemplo
curl -X GET "https://api.plasmacheckout.com/api/sdk/checkout/ck_lm7abc123xyz"Resposta
{
"data": {
"id": "cm5session123abc456",
"token": "ck_lm7abc123xyz",
"status": "pending",
"checkoutUrl": "https://checkout.plasmacheckout.com/c/ck_lm7abc123xyz",
"items": [
{
"title": "Camiseta Premium",
"price": 7990,
"quantity": 2,
"image": "https://..."
}
],
"totals": {
"subtotal": 15980,
"shipping": 1500,
"discount": 0,
"total": 17480
},
"currency": "BRL",
"customer": {
"email": "cliente@email.com",
"name": null,
"phone": null
},
"expiresAt": "2025-01-15T11:00:00Z",
"createdAt": "2025-01-15T10:00:00Z"
}
}Fluxo do Checkout
Criar Link
Sua aplicação cria um link de checkout via API com autenticação SDK.
Redirecionar Cliente
Redirecione ou envie o checkoutUrl para o cliente.
Cliente Completa
O cliente preenche os dados e paga.
Webhook
Você recebe um webhook checkout.completed e order.created com os detalhes.
Redirecionamento
O cliente é redirecionado para sua successUrl.
Expiração
O campo expiresIn é especificado em minutos:
| Valor | Tempo |
|---|---|
| Mínimo | 5 minutos |
| Padrão | 1440 minutos (24 horas) |
| Máximo | 10080 minutos (7 dias) |
{
"expiresIn": 60
}O valor é em minutos, não em segundos. 60 = 1 hora, 1440 = 24 horas.
Moedas Suportadas
| Código | Moeda |
|---|---|
BRL | Real Brasileiro |
USD | Dólar Americano |
EUR | Euro |
ARS | Peso Argentino |
CLP | Peso Chileno |
COP | Peso Colombiano |
MXN | Peso Mexicano |
PEN | Sol Peruano |
UYU | Peso Uruguaio |
Integração Frontend
Botão de Compra
function BotaoComprar({ produtoId }) {
const [loading, setLoading] = useState(false);
async function handleComprar() {
setLoading(true);
const response = await fetch('/api/criar-checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ produtoId })
});
const { checkoutUrl } = await response.json();
// Redireciona para o checkout
window.location.href = checkoutUrl;
}
return (
<button onClick={handleComprar} disabled={loading}>
{loading ? 'Carregando...' : 'Comprar Agora'}
</button>
);
}Backend (Next.js API Route)
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { produtoId } = await request.json();
const response = await fetch(
'https://api.plasmacheckout.com/api/sdk/checkout/create-link',
{
method: 'POST',
headers: {
'X-PLASMA-Public-Key': process.env.PLASMA_PUBLIC_KEY!,
'X-PLASMA-Secret-Key': process.env.PLASMA_SECRET_KEY!,
'Content-Type': 'application/json'
},
body: JSON.stringify({
productIds: [produtoId],
successUrl: `${process.env.NEXT_PUBLIC_URL}/obrigado`,
cancelUrl: `${process.env.NEXT_PUBLIC_URL}/produtos`
})
}
);
const result = await response.json();
return NextResponse.json({
checkoutUrl: result.data.checkoutUrl
});
}Nunca exponha suas API Keys no frontend. Use uma API Route no backend para intermediar.
Erros Comuns
| Código | Erro | Solução |
|---|---|---|
400 | VALIDATION_ERROR | Envie productIds ou items, não ambos |
400 | INVALID_EXPIRATION | expiresIn deve ser entre 5 e 10080 minutos |
400 | INVALID_CURRENCY | Use uma moeda suportada |
400 | TOO_MANY_ITEMS | Máximo 50 itens por checkout |
400 | INVALID_METADATA | Metadata deve ser objeto com max 4KB |
404 | NOT_FOUND | Loja não encontrada |
Finalizar Checkout
POST /api/sdk/checkout/:token/completeEste endpoint finaliza uma sessão de checkout, processa o pagamento e cria o pedido.
Este endpoint é público — o token é a autenticação.
Body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
customer.email | string | ✅ | Email do cliente |
customer.name | string | ✅ | Nome completo (min 2 chars) |
customer.phone | string | ❌ | Telefone (10-15 dígitos) |
customer.document | string | ❌ | CPF (11 dígitos) ou CNPJ (14 dígitos) |
shipping.address.street | string | ❌* | Rua (min 3 chars) |
shipping.address.number | string | ❌* | Número |
shipping.address.complement | string | ❌ | Complemento |
shipping.address.neighborhood | string | ❌* | Bairro |
shipping.address.city | string | ❌* | Cidade |
shipping.address.state | string | ❌* | Estado (2 letras) |
shipping.address.zipCode | string | ❌* | CEP (8 dígitos) |
shipping.method | string | ❌ | Método de envio |
shipping.price | number | ❌ | Valor do frete |
payment.method | string | ✅ | pix, credit_card, boleto, external |
payment.cardToken | string | ❌** | Token do cartão |
payment.installments | number | ❌ | Parcelas (1-12) |
payment.externalId | string | ❌ | ID do pagamento externo |
metadata | object | ❌ | Metadados adicionais |
* Campos de endereço são obrigatórios se shipping for informado.
** cardToken é obrigatório se payment.method for credit_card.
Exemplo
curl -X POST "https://api.plasmacheckout.com/api/sdk/checkout/ck_lm7abc123xyz/complete" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"email": "joao@email.com",
"name": "João Silva",
"phone": "+5511999999999",
"document": "123.456.789-00"
},
"shipping": {
"address": {
"street": "Rua das Flores",
"number": "123",
"complement": "Apto 45",
"neighborhood": "Centro",
"city": "São Paulo",
"state": "SP",
"zipCode": "01234-567"
},
"method": "SEDEX",
"price": 2500
},
"payment": {
"method": "pix"
}
}'const response = await fetch(
`https://api.plasmacheckout.com/api/sdk/checkout/${token}/complete`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
customer: {
email: 'joao@email.com',
name: 'João Silva',
phone: '+5511999999999'
},
shipping: {
address: {
street: 'Rua das Flores',
number: '123',
neighborhood: 'Centro',
city: 'São Paulo',
state: 'SP',
zipCode: '01234-567'
}
},
payment: { method: 'pix' }
})
}
);
const { data } = await response.json();
console.log(data.orderId);
console.log(data.payment.qrCode);Resposta (PIX)
{
"data": {
"orderId": "cm5order789xyz",
"orderNumber": "PLS-2025-X1Y2Z3",
"status": "pending",
"paymentStatus": "pending",
"payment": {
"method": "pix",
"qrCode": "00020126580014BR.GOV.BCB.PIX...",
"qrCodeBase64": null,
"copyPaste": "pix-cm5order789xyz-1705312200000",
"expiresAt": "2025-01-15T11:00:00Z"
},
"totals": {
"subtotal": 9990,
"shipping": 2500,
"discount": 0,
"total": 12490,
"currency": "BRL"
},
"successUrl": "https://meusite.com/obrigado",
"createdAt": "2025-01-15T10:30:00Z"
}
}Webhooks Disparados
Quando o checkout é completado, os seguintes webhooks são disparados:
checkout.completed— Sessão de checkout finalizadaorder.created— Novo pedido criadoorder.paid— Apenas se pagamento confirmado imediatamente (ex: cartão de crédito em test)