API PurinCash
Integre pagamentos PIX na sua aplicação em minutos. Simples, segura e feita para desenvolvedores.
O que é a PurinCash?
A PurinCash é um gateway de pagamento que simplifica cobranças PIX. Nossa API foi construída com foco em simplicidade: endpoints intuitivos, respostas consistentes e zero burocracia.
Baseada em intenção
Cada endpoint faz exatamente o que o nome diz
Rápida
PIX gerado em milissegundos, callback instantâneo
Consistente
Respostas padronizadas com error/data em toda a API
Início rápido
- Crie uma API Key no painel
- Chame
POST /v1/paymentscom o valor ou produto - O cliente paga o PIX (brCode retornado)
- Receba o callback automático na sua URL
curl -X POST https://api.purincash.com/v1/payments \ -H "Authorization: Bearer ps_live_sua_chave" \ -H "Content-Type: application/json" \ -d '{ "productId": "665f1a2b3c4d5e6f7a8b9c0d", "callbackUrl": "https://seu-site.com/webhook" }'
{ "paymentId": "psa_a1b2c3d4e5f6...", "status": "pending", "amountCents": 2990, "pix": { "brCode": "00020126580014br.gov.bcb.pix...", "qrCodeImage": "https://api.openpix.com.br/..." }, "expiresAt": "2026-03-18T12:30:00.000Z" }
Autenticação
Todas as requisições exigem uma API Key no header Authorization.
Authorization: Bearer ps_live_sua_chave_aqui
Crie e gerencie suas chaves em Dashboard → API. Cada conta pode ter até 10 chaves ativas.
Erros
A API retorna erros no formato JSON com o campo error:
{ "error": "Product not found or inactive" }
400401404429502Produtos
Criar produto
/v1/productsnamestringobrigatórioNome do produto (max 200)
priceCentsnumberobrigatórioPreço em centavos (min 100 = R$ 1,00)
descriptionstringopcionalDescrição (max 500)
currencystringopcionalMoeda (default BRL)
metadatastringopcionalJSON string com dados extras (max 2KB)
curl -X POST https://api.purincash.com/v1/products \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Plano Premium", "description": "Acesso mensal ao conteúdo premium", "priceCents": 4990, "currency": "BRL", "metadata": "{\"sku\":\"premium-01\"}" }'
Cria um produto que pode ser referenciado em pagamentos e assinaturas. Limite: 500 produtos por conta/ambiente.
{ "_id": "60f7b2a1c3e4d5f6a7b8c9d0", "name": "Plano Premium", "description": "Acesso mensal", "priceCents": 4990, "currency": "BRL", "active": true, "metadata": "{}", "createdAt": "2026-03-18T10:00:00.000Z" }
Listar produtos
/v1/productsincludeInactivestringopcionalDefina como "true" para incluir produtos inativos
curl -X GET "https://api.purincash.com/v1/products?includeInactive=true" \ -H "Authorization: Bearer ps_live_..."
{ "products": [ { "_id": "60f7...", "name": "Plano Premium", "priceCents": 4990, "currency": "BRL", "active": true, "createdAt": "..." } ] }
Obter produto
/v1/products/:idRetorna o produto individual com os mesmos campos da listagem.
Atualizar produto
/v1/products/:idnamestringopcionalNovo nome (max 200)
descriptionstringopcionalNova descrição (max 500)
priceCentsnumberopcionalNovo preço em centavos (min 100)
activebooleanopcionalAtivar/desativar produto
metadatastringopcionalJSON string (max 2KB)
curl -X PUT https://api.purincash.com/v1/products/:id \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Plano Premium v2", "priceCents": 5990, "active": true }'
Todos os campos são opcionais. Envie apenas o que deseja alterar.
Deletar produto
/v1/products/:id{ "deleted": true }
Pagamentos PIX
Criar pagamento
/v1/paymentsproductIdstringopcionalID do produto (preço vem dele)
valueCentsnumberopcionalValor em centavos (min 100) — se sem productId
descriptionstringopcionalDescrição do pagamento
callbackUrlstringopcionalURL HTTPS para webhook quando pago
customer.namestringopcionalNome do cliente
customer.emailstringopcionalEmail do cliente
customer.externalIdstringopcionalID externo no seu sistema
metadatastringopcionalJSON string com dados extras (max 2KB)
curl -X POST https://api.purincash.com/v1/payments \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "valueCents": 4990, "description": "Pedido #1234", "callbackUrl": "https://seusite.com/webhooks/purincash", "customer": { "name": "João Silva", "email": "joao@email.com", "externalId": "user_123" } }'
Cria um pagamento PIX. Vincule a um produto (productId) ou envie valor livre (valueCents).
productId OU valueCents. Se ambos forem enviados, o preço do produto prevalece.{ "paymentId": "psa_a1b2c3d4e5f6...", "status": "pending", "amountCents": 4990, "currency": "BRL", "productName": "Produto Premium", "pix": { "brCode": "00020126580014br.gov.bcb.pix0136...", "qrCodeImage": "https://api.openpix.com.br/..." }, "expiresAt": "2026-03-18T12:30:00.000Z" }
brCode é o PIX Copia e Cola. O qrCodeImage é a URL da imagem do QR Code. Pagamento expira em 30 minutos.Consultar pagamento
/v1/payments/:paymentIdConsulta o status de um pagamento pelo paymentId.
{ "paymentId": "psa_a1b2c3d4...", "status": "paid", "amountCents": 4990, "paidAt": "2026-03-18T12:05:00.000Z" }
Status: pending · paid · expired · refunded
Listar pagamentos
/v1/paymentslimitnumberopcionalResultados por página (1-100, default 50)
offsetnumberopcionalPular N resultados
statusstringopcionalFiltrar: pending, paid, expired, refunded
curl -X GET "https://api.purincash.com/v1/payments?limit=50&status=paid" \ -H "Authorization: Bearer ps_live_..."
{ "payments": [ ... ], "total": 42, "limit": 50, "offset": 0 }
Cobranças PIX avulsas
Criar cobrança
/v1/chargesvalueCentsnumberobrigatórioValor em centavos (min 80). Aceita também `amountCents`/`amount` (decimais) quando usar splits.
descriptionstringopcionalDescrição (max 200, default "Pagamento PIX")
callbackUrlstringopcionalURL HTTPS para webhook quando pago
customer.namestringopcionalNome do cliente (max 100)
customer.emailstringopcionalEmail do cliente (max 255)
customer.externalIdstringopcionalID externo no seu sistema (max 200)
metadatastringopcionalJSON string com dados extras (max 2KB) — não suportado em cobranças com splits
curl -X POST https://api.purincash.com/v1/charges \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "valueCents": 1200, "description": "Pagamento avulso", "callbackUrl": "https://seu-site.com/webhook", "customer": { "name": "João Silva", "email": "joao@email.com", "externalId": "user_123" } }'
Cria uma cobrança PIX avulsa com valor customizado, sem necessidade de produto cadastrado. Opcionalmente, envie splits[] para dividir automaticamente o valor recebido entre múltiplas contas purincash (marketplaces, comissionamento, royalties).
curl -X POST https://api.purincash.com/v1/charges \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "valueCents": 1200, "description": "Pagamento avulso", "callbackUrl": "https://seu-site.com/webhook" }'
{ "paymentId": "psc_a1b2c3d4e5f6...", "status": "pending", "amountCents": 1200, "currency": "BRL", "environment": "live", "pix": { "brCode": "00020126580014br.gov.bcb.pix0136...", "qrCodeImage": "https://api.openpix.com.br/..." }, "expiresAt": "2026-03-18T12:30:00.000Z" }
psc_ indica cobrança avulsa. psa_ indica pagamento vinculado a produto. psplit_ indica cobrança com splits.Com splits (divisão automática)
Adicione splits[] ao request com apenas os OUTROS beneficiários. Você, dono da API key, é participante implícito: não entra na lista e recebe automaticamente o resto (100 − soma das percentages). Ao pagamento, cada conta recebe na própria carteira purincash. Também aceito em POST /v1/split-charges (alias).
/v1/split-chargesamountCentsnumberobrigatórioValor total em centavos (80–500000). Aceita também `valueCents`/`amount`.
splitsarrayobrigatório1 a 9 beneficiários ALÉM de você. Você (dono da API key) NÃO entra na lista — recebe o resto (100 − soma das percentages), que precisa ser a maior fatia.
recipientEmailstringpercentagenumberdescriptionstringopcionalDescrição (max 200)
callbackUrlstringopcionalURL HTTPS para webhook quando pago
customer.namestringopcionalNome do cliente
customer.emailstringopcionalEmail do cliente
curl -X POST https://api.purincash.com/v1/split-charges \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "amountCents": 10000, "description": "Venda compartilhada", "customer": { "name": "Cliente", "email": "cliente@example.com" }, "splits": [ { "recipientEmail": "socio@example.com", "percentage": 30 } ] }'
splits: 1 a 9 beneficiários (você é o implícito — até 10 no total)- Não liste você mesmo: o dono da API key recebe o resto automaticamente
- Cada
percentage: entre 0.01 e 99.99 - Soma das percentages: < 100.00 — sua fatia é o resto e precisa ser estritamente a maior
recipientEmailúnico por charge (sem duplicar)- Beneficiário deve ser conta purincash existente (validado por email)
amountCents: integer entre 80 (R$ 0.80) e 500.000 (R$ 5.000)
curl -X POST https://api.purincash.com/v1/charges \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "amountCents": 10000, "description": "Venda compartilhada", "splits": [ { "recipientEmail": "socio@example.com", "percentage": 30 } ], "customer": { "name": "Cliente", "email": "cliente@example.com" } }'
{ "paymentId": "psplit_a1b2c3d4...", "status": "pending", "amountCents": 10000, "currency": "BRL", "environment": "live", "pix": { "brCode": "00020126360014BR.GOV.BCB.PIX...", "qrCodeImage": null }, "splits": [ { "recipientEmail": "vo***@example.com", "percentage": 70, "isOwner": true }, { "recipientEmail": "so***@example.com", "percentage": 30, "isOwner": false } ], "expiresAt": "2026-05-28T12:30:00.000Z" }
Fluxo de pagamento:
- Você cria a cobrança com splits → recebe
brCode(PIX copia-e-cola) - Cliente paga o valor cheio (10000 cents = R$ 100,00)
- Os OUTROS beneficiários recebem a percentage cheia sobre o bruto (sócio 30% → R$ 30,00)
- A taxa do gateway (ex: 2% + R$ 0,50 = R$ 2,50) sai 100% da SUA parte
- Você recebe o resto: 10000 − 3000 − 250 = 6750 cents (R$ 67,50)
- Cada um recebe na própria carteira purincash, com evento financeiro auditável
- A: floor(10000 × 0.3333) = 3333 cents (R$ 33,33)
- B: floor(10000 × 0.3333) = 3333 cents (R$ 33,33)
- Você: 10000 − 3333 − 3333 − 250 = 3084 cents (R$ 30,84)
Consultar cobrança
/v1/charges/:paymentIdConsulta o status de uma cobrança pelo paymentId. Quando o ID começa com psplit_, a resposta inclui o breakdown de cada split (valor creditado em centavos e timestamp).
{ "paymentId": "psc_a1b2c3d4...", "status": "paid", "amountCents": 1200, "currency": "BRL", "description": "Pagamento avulso", "customer": { "name": "", "email": "", "externalId": "" }, "metadata": "{}", "paidAt": "2026-03-18T12:05:00.000Z", "expiresAt": "2026-03-18T12:30:00.000Z", "createdAt": "2026-03-18T12:00:00.000Z" }
{ "paymentId": "psplit_a1b2c3d4...", "status": "paid", "amountCents": 10000, "gatewayFeeCents": 250, "netAmountCents": 9750, "currency": "BRL", "environment": "live", "pix": { "brCode": "..." }, "splits": [ { "recipientEmail": "vo***@example.com", "percentage": 70, "isOwner": true, "amountCents": 6750, "creditedAt": "2026-05-28T12:15:00.000Z" }, { "recipientEmail": "so***@example.com", "percentage": 30, "isOwner": false, "amountCents": 3000, "creditedAt": "2026-05-28T12:15:00.000Z" } ], "paidAt": "2026-05-28T12:15:00.000Z", "expiresAt": "2026-05-28T12:30:00.000Z", "createdAt": "2026-05-28T12:00:00.000Z" }
Status values: pending | paid | expired | refunded | cancelled.
Pagamentos por Cartão
Criar pagamento cartão
/v1/card-paymentsvalueCentsnumberobrigatórioValor em centavos (min 100)
descriptionstringopcionalDescrição (max 200, default "Pagamento Cartao")
callbackUrlstringopcionalURL HTTPS para webhook quando pago
customer.namestringopcionalNome do cliente (max 100)
customer.emailstringopcionalEmail do cliente (max 255)
customer.externalIdstringopcionalID externo (max 200)
metadatastringopcionalJSON string com dados extras (max 2KB)
successUrlstringopcionalURL de redirecionamento após pagamento
cancelUrlstringopcionalURL de redirecionamento ao cancelar
curl -X POST https://api.purincash.com/v1/card-payments \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "valueCents": 4990, "description": "Pedido #1234", "callbackUrl": "https://seusite.com/webhooks/purincash", "customer": { "name": "João Silva", "email": "joao@email.com", "externalId": "user_123" }, "successUrl": "https://seusite.com/sucesso", "cancelUrl": "https://seusite.com/cancelado" }'
Cria um pagamento por cartão de crédito via Stripe Checkout. O cliente é redirecionado para a página de checkout.
{ "orderCode": "JUE7Y9MPSX", "status": "pending", "amountCents": 4990, "currency": "BRL", "checkoutUrl": "https://checkout.stripe.com/...", "expiresAt": "2026-03-18T12:30:00.000Z" }
checkoutUrl. Use successUrl e cancelUrl para controlar a experiência pós-pagamento.Consultar pagamento cartão
/v1/card-payments/:orderCodeConsulta o status de um pagamento por cartão pelo orderCode.
{ "orderCode": "JUE7Y9MPSX", "status": "paid", "amount": 49.9, "amountCents": 4990, "currency": "BRL", "description": "Pagamento Cartao", "checkoutUrl": null, "paidAt": "2026-03-18T12:05:00.000Z", "createdAt": "2026-03-18T12:00:00.000Z" }
Status: pending · paid · expired · canceled
Listar pagamentos cartão
/v1/card-paymentslimitnumberopcionalResultados por página (1-100, default 50)
offsetnumberopcionalPular N resultados
statusstringopcionalFiltrar: pending, paid, expired, refunded, failed
curl -X GET "https://api.purincash.com/v1/card-payments?limit=50&status=paid" \ -H "Authorization: Bearer ps_live_..."
{ "payments": [ { "orderCode": "JUE7Y9MPSX", "status": "paid", "amountCents": 4990, "paidAt": "...", "createdAt": "..." } ], "total": 10, "limit": 50, "offset": 0 }
Assinaturas
Criar assinatura
/v1/subscriptionsproductIdstringobrigatórioID do produto
customer.namestringobrigatórioNome do assinante
customer.externalIdstringopcionalID externo no seu sistema (max 200)
frequencystringopcionalWEEKLY, MONTHLY (default), SEMIANNUALLY ou ANNUALLY
dayGenerateChargenumberopcionalDia do mês para gerar cobrança (4-28)
callbackUrlstringopcionalURL HTTPS para webhook a cada pagamento
metadatastringopcionalJSON string com dados extras (max 2KB)
curl -X POST https://api.purincash.com/v1/subscriptions \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "productId": "60f7b2a1c3e4d5f6a7b8c9d0", "customer": { "name": "João Silva", "externalId": "user_123" }, "frequency": "MONTHLY", "dayGenerateCharge": 15, "callbackUrl": "https://seusite.com/webhooks/purincash" }'
Cria uma assinatura PIX recorrente vinculada a um produto. A cobrança é gerada automaticamente de acordo com a frequência escolhida.
{ "paymentId": "psa_sub_a1b2c3d4...", "status": "pending", "type": "subscription", "subscriptionId": "sub_xyz...", "amountCents": 4990, "currency": "BRL", "productName": "Plano Premium", "frequency": "MONTHLY", "environment": "live", "pix": { "brCode": "00020126580014br.gov.bcb.pix...", "paymentLinkUrl": "https://openpix.com.br/pay/..." }, "dayGenerateCharge": 15 }
WEEKLY (semanal), MONTHLY (mensal, padrão), SEMIANNUALLY (semestral) e ANNUALLY (anual).Listar assinaturas
/v1/subscriptionslimitnumberopcionalResultados por página (1-100, default 50)
offsetnumberopcionalPular N resultados (paginação)
statusstringopcionalFiltrar: pending, paid, expired, refunded
curl -X GET "https://api.purincash.com/v1/subscriptions?limit=50&status=paid" \ -H "Authorization: Bearer ps_live_..."
Retorna as assinaturas criadas na sua conta com paginação e filtros.
{ "subscriptions": [ { "paymentId": "psa_sub_a1b2c3d4...", "subscriptionId": "sub_xyz...", "status": "pending", "amountCents": 4990, "currency": "BRL", "productName": "Plano Premium", "customer": { "name": "João Silva", "email": "", "externalId": "user_123" }, "metadata": "{}", "paidAt": null, "createdAt": "2026-03-18T10:00:00.000Z" } ], "total": 5, "limit": 20, "offset": 0 }
Sandbox
Ambiente de Teste
Use uma API key ps_test_... para operar em sandbox. Nesse modo, pagamentos e cobranças são criados sem gateway real e você pode simular confirmação.
Simular pagamento realizado
/v1/sandbox/payments/:paymentId/simulate-paidMarca um pagamento sandbox como pago e dispara callback payment.paid (se callbackUrl foi configurado).
curl -X POST https://api.purincash.com/v1/sandbox/payments/psa_abc123/simulate-paid \ -H "Authorization: Bearer ps_test_..."
POST /v1/sandbox/charges/:paymentId/simulate-paid.Sandbox carteira
/v1/sandbox/walletRetorna saldo disponível e pendente apenas das transações sandbox.
{ "sandbox": true, "availableCents": 12990, "pendingCents": 4990, "available": 129.9, "pending": 49.9 }
Sandbox transações
/v1/sandbox/transactionslimitnumberopcionalResultados por página (1-200, default 50)
offsetnumberopcionalPular N resultados
curl -X GET "https://api.purincash.com/v1/sandbox/transactions?limit=50" \ -H "Authorization: Bearer ps_live_..."
{ "sandbox": true, "transactions": [ { "paymentId": "psa_abc123", "source": "payment", "type": "one_time", "status": "paid", "amountCents": 4990 } ], "total": 1, "limit": 50, "offset": 0 }
Disputas
Listar disputas
/v1/disputeslimitnumberopcionalResultados por página (1-100, default 50)
offsetnumberopcionalPular N resultados (paginação)
statusstringopcionalFiltrar: aberta, resolvida, perdida
curl -X GET "https://api.purincash.com/v1/disputes?limit=50&status=aberta" \ -H "Authorization: Bearer ps_live_..."
Retorna as disputas (MEDs) abertas contra sua conta. Use para monitorar contestações e enviar evidências.
{ "disputes": [ { "id": "665f1a2b3c4d5e6f7a8b9c0d", "code": "MED-2024-001", "wooviDisputeId": "abc123...", "endToEndId": "E123456782024...", "orderCode": "JUE7Y9MPSX", "buyer": "João Silva", "product": "Produto Premium", "amount": 23.07, "reason": "Produto não recebido", "status": "aberta", "evidences": [], "resolvedAt": null, "createdAt": "2026-03-18T10:00:00.000Z" } ], "total": 3, "limit": 50, "offset": 0 }
Status: aberta · resolvida · perdida
Obter disputa
/v1/disputes/:idRetorna detalhes de uma disputa pelo ID. Use o id retornado em listar disputas.
idreqcurl -X GET https://api.purincash.com/v1/disputes/665f1a2b3c4d5e6f7a8b9c0d \ -H "Authorization: Bearer ps_live_..."
{ "id": "665f1a2b3c4d5e6f7a8b9c0d", "code": "MED-2024-001", "wooviDisputeId": "abc123...", "endToEndId": "E123456782024...", "orderCode": "JUE7Y9MPSX", "buyer": "João Silva", "buyerDiscordId": "", "product": "Produto Premium", "amount": 23.07, "reason": "Produto não recebido", "status": "aberta", "evidences": [ { "url": "https://...", "description": "Comprovante", "correlationID": "MED-2024-001-EV1" } ], "resolvedAt": null, "createdAt": "2026-03-18T10:00:00.000Z" }
404 Dispute not found.Enviar evidências
/v1/disputes/:id/evidenceEnvia documentos como evidência para contestar uma disputa aberta. Apenas disputas com status aberta aceitam evidências.
idreqdocumentstextForPdfcurl -X POST https://api.purincash.com/v1/disputes/665f1a2b3c4d5e6f7a8b9c0d/evidence \ -H "Authorization: Bearer ps_live_..." \ -H "Content-Type: application/json" \ -d '{ "documents": [ { "url": "https://seu-site.com/comprovante.pdf", "description": "Comprovante de entrega", "correlationID": "MED-2024-001-EV1" } ], "textForPdf": "O cliente recebeu o produto em 15/03. Rastreio: BR123456789." }'
{ "success": true, "uploaded": 2 }
Pague-se via API
Solicitar saque
Solicita uma transferência do saldo disponível da loja. PIX cai pendente de aprovação admin; LTC envia direto após aprovação.
/v1/payoutsPIX: a chave PIX deve estar pré-verificada no dashboard.
methodreqamountreqwalletAddressreqcryptoAmountcurl -X POST https://api.purincash.com/v1/payouts \ -H "Authorization: Bearer ps_live_<key>" \ -H "Content-Type: application/json" \ -d '{ "method": "pix", "amount": 100.00, "walletAddress": "loja@email.com" }'
{ "id": "SAQ-API-A1B2C3D4", "code": "SAQ-API-A1B2C3D4", "method": "pix", "amount": 100, "status": "pending", "sandbox": false }
curl -X POST https://api.purincash.com/v1/payouts \ -H "Authorization: Bearer ps_live_<key>" \ -H "Content-Type: application/json" \ -d '{ "method": "ltc", "amount": 100.00, "cryptoAmount": 0.5, "walletAddress": "ltc1q..." }'
pending— aguardando aprovação admincompleted— pagodenied— negado
400— Saldo insuficiente / valor fora do range / endereço LTC inválido403— PIX não verificado (faça verificação no painel primeiro)429— Rate limit excedido (10/hr)
walletAddress é mascarado em logs e respostas (12345***).Cash-out em dólar (USDT)
Saque em USD
Converte o saldo BRL da loja e envia USDT na rede BEP20 na hora — é o mesmo fluxo instantâneo do saque Pix→USDT do painel (conversão + pagamento automático), exposto pela API. Usa o endpoint POST /v1/payouts com method: "usd".
/v1/payouts403.methodreqamountreqwalletAddressreqconfirmNotCoinbasereqcurl -X POST https://api.purincash.com/v1/payouts \ -H "Authorization: Bearer ps_live_<key>" \ -H "Content-Type: application/json" \ -d '{ "method": "usd", "amount": 100.00, "walletAddress": "0xAbC1230000000000000000000000000000000000", "confirmNotCoinbase": true }'
{ "success": true, "withdrawal": { "id": "665f1a2b3c4d5e6f7a8b9c0d", "code": "SAQ-U-1A2B3C4D5E6F7A8B", "amountBRL": 100, "receiveUSDT": 17.42, "rateBRLPerUSDT": 5.74, "status": "processando", "estimatedTime": "menos de 30 segundos" } }
processando = PIX enviado à processadora, USDT chega na wallet em segundos (confirmação via webhook). Em raros casos de incerteza de rede a resposta vem 202 com requiresReview: true — o valor NÃO é estornado até a reconciliação.400— Saldo insuficiente / fora dos limites por operação / acima da liquidez / endereço BEP20 inválido /confirmNotCoinbaseausente403— Ainda não fez o primeiro saque (faça um saque em PIX antes)429— Rate limit (10/hr) ou outro saque cripto em processamento502— Processadora rejeitou o pagamento (valor estornado pro saldo)503— Saque em cripto temporariamente indisponível
Listar saques
/v1/payoutslimitnumberopcionalResultados (1-100, default 20)
statusstringopcionalFiltrar: pendente, concluido, negado
curl -X GET "https://api.purincash.com/v1/payouts?limit=20&status=pendente" \ -H "Authorization: Bearer ps_live_..."
{ "payouts": [ { "id": "SAQ-API-A1B2C3D4", "code": "SAQ-API-A1B2C3D4", "method": "pix", "amount": 100, "cryptoAmount": null, "walletAddress": "12345***", "status": "pendente", "createdAt": "2026-04-27T12:00:00.000Z" } ] }
walletAddress sempre vem mascarado (primeiros 6 chars + ***).Webhooks
Segurança & Assinatura HMAC
Todo webhook que a gente envia (pagamento, cartão, pedido de loja, saque) vem assinado com HMAC-SHA256. A assinatura fica no header X-Webhook-Signature e é mandada sempre, sem flag de opt-in.
Onde fica meu webhook secret?
Cada loja tem um secret próprio. Você pega (ou regenera) em Dashboard → API & Desenvolvedores → Webhooks, ou via API:
GET https://api.purincash.com/api/developer/webhook-secret Authorization: Bearer <seu_token_dashboard> → { "secret": "whk_a1b2c3d4..." }
Como validar a assinatura
Calcule o HMAC-SHA256 do corpo cru da requisição (a string exata do JSON recebido, antes de qualquer parse) usando seu secret como chave. Compare com o valor do header. Use comparação timing-safe pra evitar timing attacks.
import crypto from "node:crypto"; import express from "express"; const app = express(); // Importante: precisa do body cru. O JSON.parse vem depois da validação. app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => { const signature = req.header("X-Webhook-Signature"); const expected = crypto .createHmac("sha256", process.env.PURINCASH_WEBHOOK_SECRET) .update(req.body) .digest("hex"); // timing-safe compare const valid = signature && signature.length === expected.length && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); if (!valid) return res.status(401).send("invalid signature"); const event = JSON.parse(req.body.toString()); // ... processa event.event, event.paymentId, etc. res.json({ ok: true }); });
<?php $payload = file_get_contents('php://input'); // body cru $signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''; $secret = getenv('PURINCASH_WEBHOOK_SECRET'); $expected = hash_hmac('sha256', $payload, $secret); if (!hash_equals($expected, $signature)) { http_response_code(401); exit('invalid signature'); } $event = json_decode($payload, true); // ... processa $event['event'], $event['paymentId'], etc. http_response_code(200); echo json_encode(['ok' => true]);
userId com uma chave global. Recomendamos chamar o endpoint acima pra gerar o seu próprio.Callback PIX (payment.paid / charge.paid)
Quando o PIX é confirmado, a gente faz um POST pro callbackUrl que você passou na criação. O nome do evento depende do recurso: payment.paid pros Payment Links (/v1/payments) e charge.paid pras cobranças PIX diretas (/v1/charges).
POST https://seu-site.com/webhook Content-Type: application/json X-Webhook-Signature: a3f5b8c2e1d4f7a9b6c8d2e5f1a4b7c9d2e5f8a1b4c7d0e3f6a9b2c5d8e1f4a7 { "event": "payment.paid", "paymentId": "psa_a1b2c3d4...", "amountCents": 4990, "status": "paid", "paidAt": "2026-03-18T12:05:00.000Z", "customer": { "name": "João Silva", "email": "joao@email.com", "externalId": "user_123" }, "metadata": "{\"orderId\": \"abc-123\"}" }
{ "event": "charge.paid", "paymentId": "psa_a1b2c3d4...", "amountCents": 4990, "status": "paid", "paidAt": "2026-03-18T12:05:00.000Z", "customer": { "name": "João Silva", "email": "joao@email.com" }, "metadata": "{\"orderId\": \"abc-123\"}", "payer": "João Silva", "cpfCensored": "123.***.**1-23", "bank": "077 - Banco Inter", "endToEndId": "E1818773820260318120500abc12345" }
GET /v1/payments/:paymentId pra conferir o status. O header X-Webhook-Signature está presente em todo callback; veja Segurança & HMAC pra validar.eventreqpaymentIdreqamountCentsreqstatusreqpaidAtreqcustomermetadatapayercpfCensoredbankendToEndIdCallback Cartão (card_payment.paid)
Quando uma cobrança no cartão é confirmada (via Stripe), a gente faz POST pro callbackUrl da cobrança. Evento card_payment.paid. A shape difere um pouco do PIX: o valor vem em amount (reais, decimal), não em amountCents.
POST https://seu-site.com/webhook Content-Type: application/json X-Webhook-Signature: a3f5b8c2e1d4f7a9b6c8d2e5f1a4b7c9d2e5f8a1b4c7d0e3f6a9b2c5d8e1f4a7 { "event": "card_payment.paid", "orderCode": "ORD-7K3B9X", "amount": 49.90, "status": "paid", "paidAt": "2026-03-18T12:05:00.000Z", "customer": { "name": "João Silva", "email": "joao@email.com" }, "metadata": "{\"orderId\": \"abc-123\"}" }
eventreqorderCodereqamountreqstatusreqpaidAtreqcustomermetadataWebhook Pedido (order.paid)
Específico pra lojas no Discord (bot PurinCash). Quando um pedido feito pelo bot é pago, a gente faz POST pra URL configurada na setting order_webhook_url. Útil pra sincronizar estoque ou CRM externo.
POST https://seu-site.com/webhook Content-Type: application/json X-Webhook-Signature: a3f5b8c2e1d4f7a9b6c8d2e5f1a4b7c9d2e5f8a1b4c7d0e3f6a9b2c5d8e1f4a7 { "event": "order.paid", "orderId": "665f1a2b3c4d5e6f7a8b9c0d", "orderCode": "ORD-7K3B9X", "total": 49.90, "paidAt": "2026-03-18T12:05:00.000Z", "acquirer": "cartwave" }
eventreqorderIdreqorderCodereqtotalreqpaidAtreqacquirerreqWebhook de Saques
Quando um saque é solicitado, aprovado ou negado, enviamos um POST para a URL configurada na setting withdrawal_webhook_url.
Saque solicitado
POST https://seu-site.com/webhook Content-Type: application/json X-Webhook-Signature: hmac_sha256_... { "event": "withdrawal.requested", "withdrawalId": "665f1a2b3c4d5e6f7a8b9c0d", "code": "SAQ-A1B2C3", "amount": 150.00, "method": "pix", "walletAddress": "email@exemplo.com", "status": "pendente", "requestedAt": "2026-03-18T14:00:00.000Z" }
Saque aprovado
{ "event": "withdrawal.completed", "withdrawalId": "665f1a2b3c4d5e6f7a8b9c0d", "code": "SAQ-A1B2C3", "amount": 150, "method": "pix", "walletAddress": "email@exemplo.com", "status": "concluido", "processedAt": "2026-03-18T15:30:00.000Z" }
Saque negado
{ "event": "withdrawal.denied", "withdrawalId": "665f1a2b3c4d5e6f7a8b9c0d", "code": "SAQ-A1B2C3", "amount": 150, "method": "pix", "walletAddress": "email@exemplo.com", "status": "negado", "processedAt": "2026-03-18T15:30:00.000Z" }
eventreqwithdrawalIdreqcodereqamountreqmethodreqwalletAddressreqstatusreqrequestedAt / processedAtreqX-Webhook-Signature com HMAC-SHA256. Veja Segurança & HMAC pra exemplos de validação.
