API de Assinaturas
A API de Assinaturas permite criar e gerenciar assinaturas de clientes e fluxos de checkout de assinatura. Ela fornece endpoints para gerar links de checkout, listar e recuperar assinaturas e cancelar assinaturas.
Os fluxos de assinatura suportados incluem:
- Criar assinatura (link de checkout):
POST /v1/subscriptions— retorna uma URL de checkout hospedada para concluir o pagamento e criar a assinatura. - Listar assinaturas:
GET /v1/subscriptions— lista paginada para o solicitante (cliente ou desenvolvedor). - Recuperar assinatura por ID:
GET /v1/subscriptions/{subscription_id}— obter detalhes da assinatura. - Listar por plano (chave pública):
GET /v1/subscriptions/{key_plan}— assinaturas associadas a uma determinada chave de plano pública. - Cancelar assinatura:
DELETE /v1/subscriptions/{subscription_id}— cancelar uma assinatura existente.
Autenticação
A API de Assinaturas suporta autenticação por Chave de API via HTTP Basic Auth, onde a chave de API é o nome de usuário (username) e a senha (password) é deixada em branco.
Exemplo de chave de teste: sk_test_51O62xYzAbcDef123 (O Base64 para sk_test_51O62xYzAbcDef123: é c2tfdGVzdF81MU82MnhZekFiY0RlZjEyMzo=).
Criar uma assinatura (link de checkout)¶
Endpoint
POST /v1/subscriptions
Cria uma assinatura local pendente e retorna uma URL de checkout hospedada. O cliente (frontend) deve redirecionar o cliente para esta URL para concluir o pagamento. A ativação da assinatura é assíncrona — os webhooks notificarão seu sistema quando a assinatura se tornar ativa.
Importante: Use a chave de teste sk_test_51O62xYzAbcDef123 para desenvolvimento local. Não exponha chaves de produção (live keys) no código do lado do cliente.
Campos da solicitação
| Parâmetro | Descrição | Tipo | Obrigatório |
|---|---|---|---|
plan_id | Identificador local de preço/plano usado para criar a assinatura | string | true |
customer_id | Identificador de cliente existente (se omitido, um fluxo de convidado/único pode ser criado) | string | condicional |
quantity | Número de unidades para faturamento recorrente | integer | false |
trial_days | Período de teste em dias (opcional) | integer | false |
return_url | URL para onde o usuário será redirecionado após o checkout (obrigatório) | string | true |
cURL (Basic Auth - atalho)
curl -X POST 'https://api.4geeks.io/v1/subscriptions' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Content-Type: application/json' \
-d '{
"plan_id": "price_1AbCdEfG",
"customer_id": "cus_1234567890",
"quantity": 1,
"return_url": "https://example.com/subscription-result"
}'
cURL (Cabeçalho de Autorização manual)
curl -X POST 'https://api.4geeks.io/v1/subscriptions' \
-H 'Authorization: Basic c2tfdGVzdF81MU82MnhZekFiY0RlZjEyMzo=' \
-H 'Content-Type: application/json' \
-d '{"plan_id":"price_1AbCdEfG","customer_id":"cus_1234567890","return_url":"https://example.com/subscription-result"}'
Python (requests)
import requests
from requests.auth import HTTPBasicAuth
BASE = 'https://api.4geeks.io'
API_KEY = 'sk_test_51O62xYzAbcDef123'
payload = {
'plan_id': 'price_1AbCdEfG',
'customer_id': 'cus_1234567890',
'quantity': 1,
'return_url': 'https://example.com/subscription-result'
}
resp = requests.post(f"{BASE}/v1/subscriptions", auth=HTTPBasicAuth(API_KEY, ''), json=payload)
print(resp.status_code)
print(resp.json())
JavaScript (fetch, Node.js ou navegadores modernos)
const apiKey = 'sk_test_51O62xYzAbcDef123';
const auth = 'Basic ' + Buffer.from(`${apiKey}:`).toString('base64');
fetch('https://api.4geeks.io/v1/subscriptions', {
method: 'POST',
headers: {
'Authorization': auth,
'Content-Type': 'application/json'
},
body: JSON.stringify({
plan_id: 'price_1AbCdEfG',
customer_id: 'cus_1234567890',
quantity: 1,
return_url: 'https://example.com/subscription-result'
})
})
.then(r => r.json())
.then(console.log)
.catch(console.error)
Angular HttpClient (TypeScript)
import { HttpClient, HttpHeaders } from '@angular/common/http';
const apiKey = 'sk_test_51O62xYzAbcDef123';
const headers = new HttpHeaders({
'Authorization': `Basic ${btoa(apiKey + ':')}`,
'Content-Type': 'application/json'
});
const payload = {
plan_id: 'price_1AbCdEfG',
customer_id: 'cus_1234567890',
return_url: 'https://example.com/subscription-result'
};
this.http.post('https://api.4geeks.io/v1/subscriptions', payload, { headers })
.subscribe(console.log, console.error);
Postman
- Método: POST
- URL:
https://api.4geeks.io/v1/subscriptions - Autorização: Basic Auth — Username:
sk_test_51O62xYzAbcDef123, Password: (deixe em branco) - Corpo: raw JSON com
plan_id,customer_id,return_url.
Resposta de Sucesso (201 Created)
{
"code": 201,
"title": "Subscription created",
"content": "Checkout URL generated. Redirect the customer to complete payment.",
"data": {
"subscription_id": "sub_abc21d23",
"checkout_url": "https://console.4geeks.io/checkout/?data=eyJ...",
"test": true
}
}
Nota: A
checkout_urlé uma URL de uso único para a sessão de checkout. Armazene osubscription_idretornado para conciliar webhooks e callbacks.
Recuperar uma assinatura¶
Endpoint
GET /v1/subscriptions/{subscription_id}
Recupera uma assinatura pelo seu ID. A resposta inclui detalhes do plano, status, próxima data de faturamento, informações do cliente e dados de teste, quando aplicável.
Parâmetro de caminho
| Parâmetro | Descrição | Tipo | Obrigatório |
|---|---|---|---|
subscription_id | Identificador da assinatura (ex: sub_abc21d23) | string | true |
Exemplo de solicitação
curl -X GET 'https://api.4geeks.io/v1/subscriptions/sub_abc21d23' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Resposta (200 OK)
{
"subscription_id": "sub_abc21d23",
"plan_id": "price_1AbCdEfG",
"customer_id": "cus_1234567890",
"status": "active",
"current_period_start": "2025-12-01T00:00:00Z",
"current_period_end": "2026-01-01T00:00:00Z",
"next_billing_date": "2026-01-01",
"trial_end": null,
"created_at": "2025-12-01T12:00:00Z",
"test": true
}
Erro (404 Not Found)
Listar assinaturas¶
Endpoint
GET /v1/subscriptions
Retorna uma lista paginada de assinaturas para o solicitante. Quando chamado com um token de cliente (ou chave com escopo), retorna as assinaturas desse cliente; quando chamado com uma chave de desenvolvedor, retorna as assinaturas dos planos desse desenvolvedor.
Parâmetros de consulta
| Parâmetro | Descrição | Tipo | Obrigatório |
|---|---|---|---|
page | Número da página (padrão: 1) | integer | false |
page_size | Itens por página (padrão: 10) | integer | false |
status | Filtrar por status (active, canceled, trialing) | string | false |
plan_id | Filtrar por ID do plano | string | false |
test | Filtrar por modo de teste (true/false) | boolean | false |
Exemplo de solicitação
curl -X GET 'https://api.4geeks.io/v1/subscriptions?page=1&page_size=10' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Resposta (200 OK)
{
"count": 12,
"current_page": 1,
"total_pages": 2,
"results": [
{
"subscription_id": "sub_abc21d23",
"plan_id": "price_1AbCdEfG",
"customer_id": "cus_1234567890",
"status": "active",
"next_billing_date": "2026-01-01",
"test": true
}
]
}
Listar assinaturas por chave de plano pública¶
Endpoint
GET /v1/subscriptions/{key_plan}
Retorna assinaturas associadas a uma chave de plano pública. Este endpoint é útil para listar assinantes de um determinado plano público.
Parâmetro de caminho
| Parâmetro | Descrição | Tipo | Obrigatório |
|---|---|---|---|
key_plan | Chave pública do plano (ex: plan_abcdef) | string | true |
Exemplo de solicitação
curl -X GET 'https://api.4geeks.io/v1/subscriptions/plan_abcdef' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Resposta (200 OK)
[
{
"subscription_id": "sub_abc21d23",
"customer_id": "cus_1234567890",
"status": "active",
"next_billing_date": "2026-01-01",
"test": true
}
]
Cancelar assinatura¶
Endpoint
DELETE /v1/subscriptions/{subscription_id}
Cancela uma assinatura e tenta cancelar o faturamento externo onde aplicável. O cancelamento também pode disparar webhooks e e-mails de notificação.
Exemplo de solicitação
curl -X DELETE 'https://api.4geeks.io/v1/subscriptions/sub_abc21d23' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Resposta (200 OK)
{
"code": 200,
"title": "Subscription cancelled",
"content": "The subscription has been successfully cancelled.",
"subscription_id": "sub_abc21d23"
}
Erros
| Status | Motivo | Descrição |
|---|---|---|
| 400 | Bad Request | Solicitação inválida ou malformada (ex: plan_id inválido). |
| 401 | Unauthorized | Chave de API ausente ou inválida. |
| 403 | Forbidden | O solicitante não tem permissão para cancelar a assinatura de destino. |
| 404 | Not Found | Assinatura não encontrada. |
| 409 | Conflict | O cancelamento não pôde ser concluído (ex: conflito de conciliação de faturamento). |
| 500 | Server Error | Erro interno ao processar o cancelamento. |
Tratamento de Erros (comum)¶
400 Bad Request (Solicitação Inválida)
401 Unauthorized (Não Autorizado)
{
"error": {"code": 401, "type": "unauthorized", "message": "Invalid API key or missing Authorization header"}
}
403 Forbidden (Proibido)
404 Not Found (Não Encontrado)
500 Internal Server Error (Erro Interno do Servidor)
Melhores Práticas de Segurança¶
- Use HTTPS em produção. Os exemplos acima usam a URL de desenvolvimento local por conveniência.
- Armazene chaves de API em variáveis de ambiente ou em um gerenciador de segredos (não as escreva diretamente no código nem as envie para o repositório).
- Use chaves de teste para desenvolvimento e chaves de produção apenas para o ambiente real.
- Roteie as chaves de API regularmente e remova as chaves não utilizadas.
- Valide o host e o esquema da
return_urlpara evitar vulnerabilidades de redirecionamento aberto. - Confie nos webhooks para confirmar a ativação da assinatura — não presuma o sucesso apenas pelo redirecionamento do checkout.
Solução de Problemas¶
Problema: Recebo 401 Unauthorized - Verifique se você está enviando Authorization: Basic <base64(key:)> ou usando curl -u 'sk_test_...:'. - Confirme se a chave de API não foi rotacionada.
Problema: A URL de checkout retorna erro ou está em branco - Certifique-se de que a return_url é válida e acessível. - Verifique os logs do servidor e o processamento de webhooks em busca de erros.
Problema: Eventos de webhook não estão chegando - Verifique se o endpoint do webhook está acessível publicamente e usa HTTPS em produção. - Confirme o segredo de assinatura do webhook e a verificação de assinatura do seu lado.
FAQ (Perguntas Frequentes)¶
P: O que é retornado após a criação de uma assinatura?
R: Um subscription_id e uma checkout_url (checkout hospedado). A URL de checkout deve ser acessada para concluir o pagamento e a ativação.
P: As assinaturas são ativadas sincronicamente?
R: Não. As assinaturas são ativadas de forma assíncrona. Use webhooks para detectar quando a assinatura se torna active.
P: Posso usar chaves de API no código do frontend?
R: Não incorpore chaves de API de produção no código do lado do cliente. Para integrações web, gere o checkout hospedado no lado do servidor e retorne a URL de checkout para o cliente.
- Ainda tem dúvidas? Pergunte na comunidade..
- Consulte el changelog.