Clientes e Assinaturas
Gerencie clientes recorrentes e assinaturas de forma unificada em todos os gateways de pagamento.
Clientes
O que são Clientes?
Clientes são representações de compradores salvos no gateway. Ao criar um cliente, você pode:
- Salvar cartões de crédito de forma tokenizada (segura)
- Reutilizar dados de cobrança sem enviar novamente
- Criar assinaturas recorrentes
- Acompanhar histórico de transações por cliente
- Simplificar cobranças futuras (1-click checkout)
Criando um Cliente
const axios = require('axios');
const client = axios.create({
baseURL: 'https://api.toktus.com/api/v1',
headers: { 'x-api-key': process.env.TOKTUS_API_API_KEY }
});
async function createCustomer() {
const response = await client.post('/customers', {
gateway: 'stripe',
name: 'João Silva',
email: '[email protected]',
document: '12345678901',
phone: '11987654321',
address: {
street: 'Rua das Flores',
number: '123',
complement: 'Apto 45',
neighborhood: 'Centro',
city: 'São Paulo',
state: 'SP',
zipCode: '01310100'
},
metadata: {
internalId: 'user_123',
source: 'web',
plan: 'premium'
}
});
return response.data.data.externalId;
}Resposta:
{
"success": true,
"data": {
"id": "9176ac5d-19c0-42b9-a7ab-c50beccff57f",
"externalId": "cus_000007729932",
"gateway": "asaas",
"name": "João Silva",
"email": "[email protected]",
"document": "12345678901",
"phone": "11999998888"
}
}[!NOTE]
idé o UUID interno do Toktus API;externalIdé o ID gerado pelo gateway (ex:cus_xxxno Asaas,cus_abcno Stripe). UseexternalIdem chamadas subsequentes aos endpoints de clientes e cobranças.
Salvando Cartão de Crédito
[!WARNING]
NUNCA envie dados raw de cartão pelo backend. Use tokenização no frontend.
<!-- Frontend: Stripe.js -->
<script src="https://js.stripe.com/v3/"></script>
<script>
const stripe = Stripe('pk_test_SUA_PUBLIC_KEY');
const elements = stripe.elements();
const cardElement = elements.create('card');
cardElement.mount('#card-element');
// Tokeniza no frontend
const {token, error} = await stripe.createToken(cardElement);
// Envia APENAS o token ao backend
await fetch('/api/add-card', {
method: 'POST',
body: JSON.stringify({
customerId: 'cus_abc123',
cardToken: token.id
})
});
</script>Operações com Clientes
Assinaturas
Quando Usar Assinaturas?
Use assinaturas para:
- SaaS — Mensalidades e anuidades de software
- Clubes de assinatura — Cafés, vinhos, livros
- Streaming — Música, vídeos e cursos online
- Academias — Mensalidades recorrentes
- Publicações — Jornais e revistas digitais
Criando uma Assinatura
async function createSubscription() {
const response = await client.post('/subscriptions', {
gateway: 'stripe',
customerId: 'cus_abc123',
planName: 'Plano Premium',
amount: 4990, // R$ 49,90/mês
interval: 'monthly',
paymentMethod: 'credit_card',
description: 'Acesso completo à plataforma',
metadata: {
planId: 'premium_monthly',
features: 'unlimited_access,priority_support'
}
});
return response.data.data.externalId;
}Resposta:
{
"success": true,
"data": {
"id": "c0f542e9-289e-4c5d-87c5-2844b9a3b30c",
"externalId": "sub_qgxm1z8o8gq6p45n",
"gateway": "asaas",
"status": "active",
"amount": 4990,
"interval": "monthly",
"currentPeriodStart": "2026-03-30",
"currentPeriodEnd": "2026-04-30"
}
}Intervalos Disponíveis
| Interval | Descrição | Uso típico |
|---|---|---|
weekly | A cada 7 dias | Academias, aulas |
monthly | A cada 30 dias | SaaS, streaming |
quarterly | A cada 3 meses | Planos trimestrais |
yearly | A cada 365 dias | Licenças anuais |
Status de Assinaturas
| Status | Significado | Ação |
|---|---|---|
active | Ativa e cobrando | Liberar acesso |
trialing | Em período trial | Liberar acesso |
past_due | Pagamento falhou | Avisar usuário |
canceled | Cancelada | Bloquear acesso |
unpaid | Múltiplas falhas | Bloquear acesso |
paused | Pausada temporariamente | Bloquear acesso |
incomplete | Aguardando primeira cobrança | Aguardar webhook |
Operações com Assinaturas
Fluxo Completo do Ciclo de Vida
graph TD
A[Usuário se cadastra] --> B[Criar Cliente no Gateway]
B --> C[Tokenizar Cartão no Frontend]
C --> D[Salvar Token no Gateway]
D --> E[Criar Assinatura]
E --> F{Primeira Cobrança}
F -->|Sucesso| G[Status: active]
F -->|Falha| H[Status: incomplete]
G --> I[Liberar Acesso]
H --> J[Solicitar outro cartão]
J --> E
I --> K[Cobranças Automáticas]
K --> L{Cobrança OK?}
L -->|Sim| I
L -->|Não| M[Status: past_due]
M --> N[Retry automático 3x]
N --> O{Sucesso?}
O -->|Sim| I
O -->|Não| P[Status: unpaid]
P --> Q[Bloquear Acesso]
I --> R[Usuário cancela]
R --> S[Status: canceled]
Melhores Práticas
```javascript
// Avoid — never send raw card data through the backend
await client.post('/charges', { cardNumber: '4111...', cvv: '123' });
// Correct — tokenize in the frontend, send only the token
const token = await stripe.createToken(cardElement);
await client.post('/charges', { cardToken: token.id });
```
Não confie apenas na resposta da API. Webhooks garantem que eventos assíncronos sejam processados.
```javascript
await client.post('/subscriptions', {
gateway: 'stripe',
customerId: 'cus_abc',
planName: 'Plano Premium',
amount: 4990,
interval: 'monthly',
paymentMethod: 'credit_card',
metadata: {
userId: 'user_123',
source: 'mobile_app',
campaign: 'summer_2025'
}
});
```
Comparação de Gateways
| Recurso | Stripe | Pagar.me | Asaas | Mercado Pago | PagSeguro |
|---|---|---|---|---|---|
| Clientes | Sim | Sim | Sim | Sim | Sim |
| Cartões salvos | Sim | Sim | Sim | Sim | Sim |
| Listar/deletar cartões | Sim | Sim | Não | Sim | Não |
| Assinaturas | Sim | Sim | Sim | Sim | Sim |
| Consulta de saldo | Sim | Sim | Sim | Não | Não |
| Webhooks | Sim | Sim | Sim | Sim | Sim |
| Excluir cliente | Sim | Parcial | Sim | Sim | Parcial |
Updated about 2 hours ago