API Surfpay
Gere cobranças Pix no seu servidor e receba a confirmação de pagamento. A API mantém o mesmo contrato quando o processador da sua conta muda.
1. Preparação e autenticação
- Conclua o cadastro e confirme o e-mail.
- Envie os documentos em Configurações → Documentos. A criação de Pix exige aprovação.
- Gere sua chave em Configurações → Credenciais. Ela aparece uma única vez e deve ficar no servidor da sua loja.
- Declare sua atividade em Configurações e aguarde a análise comercial. Confirme com a administração o ambiente da conta e a configuração do seu webhook.
Base: https://app.gatewaysurfpay.com/api/gateway Authorization: Bearer SUA_CHAVE Content-Type: application/json
A chave identifica seu seller; não envie sellerId para acessar outra conta. Cada chave possui ambiente fixo, permissões charges.read e/ou charges.create e validade de 90 dias por padrão. Crie uma substituta e revogue a anterior individualmente após atualizar sua integração. Chaves não acessam saques, documentos ou configurações. Não use tokens Versell, Woovi, NexusPag, SmokePay, Meta ou UTMify na autenticação da API Surfpay.
As taxas padrão de cash-in são R$ 0,80 até R$ 50,00, inclusive; acima desse valor, R$ 0,80 + 2%. Uma cobrança de R$ 100,00 gera tarifa de R$ 2,80 e líquido de R$ 97,20. A administração pode configurar uma taxa de gateway na conexão que inicia o pedido; quando ativa, ela substitui a tarifa individual do seller. A tarifa é fixada no início da cobrança e não muda no fallback. Consulte o feeCents retornado para a condição efetiva do pedido.
2. Criar cobrança Pix
POST https://app.gatewaysurfpay.com/api/gateway/v1/charges
{
"externalId": "pedido-2026-001",
"amountCents": 10000,
"description": "Pedido na minha loja",
"customer": {
"name": "Nome do comprador",
"email": "comprador@example.com",
"taxID": "12345678909",
"phone": "11999999999"
},
"tracking": {
"consent": true,
"eventSourceUrl": "https://sua-loja.com/checkout",
"utm_source": "facebook",
"utm_campaign": "campanha-outubro",
"utm_medium": "paid_social",
"utm_content": "anuncio-01",
"utm_term": "feed",
"src": "facebook",
"sck": "campanha-01",
"country": "BR",
"phone": "5511999999999",
"fbp": "fb.1.1792000000000.123456789"
}
}| Campo | Regra |
|---|---|
| externalId | Obrigatório. Identificador único do pedido no seu seller, até 120 caracteres: letras, números, ponto, hífen, sublinhado e dois-pontos. |
| amountCents | Obrigatório. Inteiro positivo em centavos; 10000 = R$ 100,00. Respeite os limites da conta. |
| description | Opcional, até 140 caracteres. |
| customer | Opcional na cobrança básica. Quando enviado, exige name, email e taxID com 11 ou 14 dígitos. Necessário para UTMify. Na SyncPay, quando customer estiver presente, use CPF (11 dígitos) e phone nacional com DDD (10 ou 11 dígitos). O telefone operacional é separado de tracking.phone, usado para marketing. |
| tracking | Opcional. Parâmetros de campanha e dados do comprador, descritos abaixo. Necessário para enviar conversões. |
{
"charge": {
"id": "ID_DA_COBRANCA",
"externalId": "pedido-2026-001",
"amountCents": 10000,
"feeCents": 280,
"environment": "production",
"status": "pending",
"brCode": "CODIGO_PIX_RETORNADO_PELO_PROCESSADOR",
"expiresAt": "2026-10-15T16:00:00.000Z",
"paidAt": null
},
"replayed": false
}O exemplo de resposta mostra os campos principais; outros campos podem ser retornados. Exiba o QR Code e o brCode apenas enquanto a cobrança estiver pending e o código existir. O QR é obtido por GET /v1/charges/:id/qr com a mesma autenticação, como imagem PNG. O simulador não gera um Pix pagável.
Idempotência e falha do processador
Em timeout, repita o mesmo externalId com o mesmo conteúdo. A API recupera a cobrança existente. Outro conteúdo com o mesmo identificador retorna 409. Não gere um novo identificador para tentar novamente um pedido com status unknown ou creating: consulte a cobrança existente. O roteamento só tenta outro processador quando a rejeição anterior permite isso com segurança.
201 indica criação; 202 indica processamento ou conciliação; 200 com replayed=true indica repetição recuperada. O pagamento só está concluído quando status=paid, independentemente do HTTP da criação.
3. Consultar e acompanhar
GET https://app.gatewaysurfpay.com/api/gateway/v1/charges/ID_DA_COBRANCA GET https://app.gatewaysurfpay.com/api/gateway/v1/charges?page=1&status=paid&q=pedido
A lista retorna items, total e page, com 30 itens por página. Filtros: status, q, from, to e dateBasis=created|paid. As datas YYYY-MM-DD são inclusivas no horário de São Paulo. O vínculo do seller autenticado sempre limita os resultados.
| Status | Significado |
|---|---|
creating | Geração em andamento. Aguarde ou consulte. |
pending | Pix gerado, aguardando pagamento. |
unknown | Resultado incerto. Aguarde a conciliação, sem criar outro Pix. |
paid | Pagamento confirmado pelo processador. |
expired | Cobrança expirada. |
failed | Geração rejeitada ou sem processador elegível. |
O worker consulta o processador da tentativa original. Uma consulta manual pode ser solicitada no painel ou pelo atendimento; a chave comercial não executa a reconciliação. Comprovantes enviados pela loja não confirmam o pagamento. Status paid indica pagamento confirmado, e não saldo já liquidado e disponível para saque. Chaves comerciais não iniciam saques nem devoluções. Os saques do responsável são solicitados no painel, com dois fatores, saldo liquidado, reserva e análise de exceções conforme a política. A tarifa e o débito total são exibidos no painel.
4. Receber o pagamento confirmado
A administração configura a URL HTTPS pública e o segredo do seu webhook. O worker envia charge.paid após a confirmação do processador. Responda 2xx depois de persistir o evento. Falhas têm novas tentativas; trate o id como único para não entregar o produto duas vezes.
{
"id": "paid:ID_DA_COBRANCA",
"event": "charge.paid",
"createdAt": "2026-10-15T15:00:00.000Z",
"environment": "production",
"charge": {
"id": "ID_DA_COBRANCA",
"externalId": "pedido-2026-001",
"amountCents": 10000,
"feeCents": 280,
"netCents": 9720,
"currency": "BRL",
"status": "paid",
"paidAt": "2026-10-15T15:00:00.000Z"
}
}Cabeçalhos: X-Surfpay-Event, X-Surfpay-Timestamp (segundos Unix) e X-Surfpay-Signature (hexadecimal). A assinatura é HMAC-SHA256 de timestamp + ponto + corpo JSON original. Use o corpo bruto recebido, sem serializar novamente.
import { createHmac, timingSafeEqual } from 'node:crypto';
const expected = createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(timestamp + '.' + rawBody).digest();
const supplied = /^[a-f0-9]{64}$/.test(signature)
? Buffer.from(signature, 'hex') : Buffer.alloc(0);
if (supplied.length !== expected.length ||
!timingSafeEqual(supplied, expected)) throw new Error('Assinatura inválida');
if (!/^\d{10}$/.test(timestamp) ||
Math.abs(Date.now() / 1000 - Number(timestamp)) > 300)
throw new Error('Evento fora da janela');
// Confira environment, id, externalId, amountCents e status.
// Grave event.id com índice único antes de entregar o produto.Não aceite uma aprovação enviada pelo navegador do comprador. Em produção, confira environment=production; notificações do simulador não representam pagamentos reais.
5. UTMify e Pixel do Facebook / Meta
Em Integrações, ative somente os serviços que utiliza. UTMify: gere uma credencial em Integrações → Webhooks → Credenciais de API. Meta: informe o ID do Pixel/conjunto de dados e o token da API de Conversões no Gerenciador de Eventos. Os tokens ficam protegidos no servidor e não são exibidos novamente.
Na sua loja, capture os parâmetros da URL de entrada e mantenha-os até o checkout. Envie esses dados no objeto tracking ao criar a cobrança, pelo seu servidor:
- src, sck, utm_source, utm_campaign, utm_medium, utm_content, utm_term: opcionais, até 256 caracteres.
- consent: booleano obrigatório quando tracking estiver presente. Só envie true quando tiver autorização válida do comprador para esse compartilhamento.
- eventSourceUrl: URL HTTPS real do checkout, até 2048 caracteres, sem credenciais nem fragmento. Necessária para Meta.
- fbp e fbc: valores originais dos cookies _fbp e _fbc, quando disponíveis. Não invente cookies.
- buyerIP e userAgent: IP e navegador do comprador, se disponíveis. Não use o IP do servidor da loja como se fosse o comprador.
- phone: telefone com código do país, 10 a 15 dígitos; country: país ISO de duas letras.
UTMify recebe um pedido paid, em BRL e centavos, com datas UTC, UTMs e valores bruto, tarifa e líquido. A cobrança representa um produto único com o nome da descrição. Meta recebe Purchase com valor bruto em reais, moeda BRL e e-mail/telefone normalizados com hash SHA-256. Não é enviado Purchase de uma cobrança pendente.
Se também disparar Purchase no navegador, use eventID igual a paid:ID_DA_COBRANCA, o mesmo event_id do servidor, para deduplicação pela Meta. Envios usam identificadores estáveis nas novas tentativas; a entrega é ao menos uma vez, não uma promessa de atribuição de anúncios.
Acompanhe os envios na tela de Integrações. Dados ausentes bloqueiam a conversão sem impedir o Pix. Simulação e sandbox registram o evento localmente, sem envio externo. A configuração precisa estar ativa quando o pagamento for confirmado; não há importação automática do histórico. Alterar credenciais cancela eventos pendentes da configuração anterior.
Referências técnicas: API UTMify e Meta Conversions API.
6. Erros, limites e testes
Erros retornam JSON com error e code. 400: campo inválido; 401: credencial ausente ou inválida; 403: cadastro não aprovado ou acesso proibido; 404: recurso indisponível; 409: conflito de idempotência; 422: geração rejeitada; 429: limite de requisições; 503: configuração ou processador indisponível. Em falha de rede, recupere o pedido com o mesmo externalId.
Uma nova conta acessa o painel após confirmar o e-mail; enviar Pix depende da verificação documental. O ambiente da API é o configurado para sua conta. O TESTE LOCAL aprova cobranças simuladas. Confirmações manuais de simulação exigem sessão no painel e não são permitidas às chaves comerciais. O simulador não representa um pagamento real.
Faça os testes locais com o simulador. Use sandbox quando o processador disponibilizar esse ambiente; as documentações Versell, NexusPag e SmokePay apresentam somente produção, que exige homologação operacional antes de liberar cobranças reais. Credenciais válidas, homologação do processador, webhook HTTPS e worker ativo são necessários para operação real.