Guia rápido
Seu primeiro pagamento de teste, passo a passo
Faça um pagamento de teste no ambiente Stage depois do onboarding e da configuração inicial.
- Stage: sem dinheiro real
- cURL e Node.js
- Dados de teste fictícios
Visão geral
Três fases, seis passos
Tudo a seguir acontece no Stage, o ambiente de testes que espelha a produção. O acesso à produção vem no final, após as verificações do passo 6.
- 01
Configure o acesso
Receba as credenciais do Stage, guarde-as em um gerenciador de segredos e cadastre os IPs dos seus servidores.
Passos 1–2
- 02
Faça as primeiras chamadas
Obtenha um token, crie um pay-in de teste e verifique o webhook que o confirma.
Passos 3–5
- 03
Entre em produção
Conclua a revisão de segurança e a verificação da empresa (KYB) e troque para credenciais de produção.
Passo 6
Passo 1 de 6
Receba suas credenciais do Stage
As credenciais do Stage, um usuário e uma senha de API para api.stage.localpayment.com, são emitidas no início da sua parceria com a Localpayment. Trate-as como segredos de produção desde o primeiro dia.
- Carregue as credenciais de um gerenciador de segredos ou de variáveis de ambiente; nunca faça commit delas
- Stage e produção usam credenciais e URLs base diferentes
- Use apenas dados de teste fictícios, nunca dados reais de clientes
// Carregue as credenciais do Stage do AWS Secrets Manager na inicialização (AWS SDK v3).
// Qualquer cofre serve: o importante é que segredos nunca fiquem no código-fonte.
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManagerClient({ region: process.env.AWS_REGION });
export async function loadMerchantSecrets() {
const { SecretString } = await client.send(
new GetSecretValueCommand({ SecretId: 'localpayment/stage/api' }),
);
// JSON esperado: { "username": "…", "password": "…", "webhookSecret": "…" }
return JSON.parse(SecretString);
}Passo 2 de 6
Cadastre os IPs dos seus servidores
A API só aceita chamadas dos endereços IP que você cadastrou. Adicione os IPs de saída dos seus servidores no Business Portal do Stage antes da primeira requisição.
- Business Portal → Whitelist your IP
- Requisições de qualquer outro IP são rejeitadas
- Serverless ou autoescalável? Envie o tráfego de saída por um IP fixo (NAT)
- Repita a configuração na produção antes de entrar no ar
- PCI DSS v4.0.1
- SOC 2 Type II
- ISO 27001
- AML/KYC
- TLS 1.2+ · AES-256
Passo 3 de 6
Obtenha um token de acesso
Troque seu usuário e senha de API por um par de JWTs. Envie o token de acesso como token Bearer em cada chamada e renove-o antes que expire.
- Token de acesso: válido por 5 minutos
- Token de renovação: válido por 24 horas; use POST /api/token/refresh/
- Mantenha os tokens em memória e nunca os grave em logs
# Obtenha um token de acesso no Stage (válido por 5 minutos)
curl -X POST https://api.stage.localpayment.com/api/token/ \
-H "Content-Type: application/json" \
-d "{\"username\": \"$LP_API_USER\", \"password\": \"$LP_API_PASSWORD\"}"Passo 4 de 6
Crie um pay-in de teste
Este exemplo cria um pay-in Pix no Brasil. A resposta traz um QR Code e um código Pix Copia e Cola, com status 100 INPROGRESS até o pagador concluir o pagamento.
- Gere um UUID novo como externalId para cada transação
- Reenviar com o mesmo externalId retorna 409 Conflict em vez de criar um segundo pay-in
- Valor em USD: a resposta traz o valor em BRL que o pagador paga e a cotação aplicada
# Pay-in Pix ilustrativo no Stage (Brasil). Valores fictícios;
# veja docs.localpayment.com para o contrato completo.
curl -X POST https://api.stage.localpayment.com/api/payin/ \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"paymentMethod": { "type": "BankTransfer", "code": "1314", "flow": "DIRECT" },
"externalId": "7c1e2f7a-0000-4000-8000-000000000001",
"country": "BRA",
"currency": "USD",
"amount": 100,
"accountNumber": "<your-account-number>",
"conceptCode": "0003",
"merchant": { "type": "COMPANY", "name": "Nortia Commerce Ltda" },
"payer": {
"type": "INDIVIDUAL",
"name": "Maria",
"lastname": "Silva",
"document": { "type": "CPF", "id": "000.000.000-00" }
}
}'Passo 5 de 6
Processe o webhook
Quando o pagamento é concluído, a Localpayment envia uma notificação assinada para o seu endpoint HTTPS. Verifique a assinatura sobre o corpo bruto, responda 200 na hora e faça o processamento de forma assíncrona.
- Cadastre sua URL em Business Portal → Configurations → Clients → Notifications
- Compare o x-Signature com o seu próprio HMAC-SHA256 usando uma comparação de tempo constante
- Entregas sem resposta 200 são reenviadas com backoff exponencial
// Receptor Express para webhooks da Localpayment (Node.js 18+).
import crypto from 'node:crypto';
import express from 'express';
import { jobQueue } from './queue.js'; // sua própria fila de jobs assíncronos
const app = express();
// Carregue o segredo do webhook do seu gerenciador de segredos na inicialização. Nunca o deixe no código.
const WEBHOOK_SECRET = process.env.LP_WEBHOOK_SECRET;
if (!WEBHOOK_SECRET) throw new Error('LP_WEBHOOK_SECRET is not configured');
function hasValidSignature(rawBody, header) {
if (typeof rawBody !== 'string') return false;
// Formato do header: "x-Signature: HMAC-SHA256 <hex>". Remova o prefixo antes.
const received = String(header ?? '').replace(/^HMAC-SHA256\s+/i, '').trim();
if (!/^[0-9a-f]{64}$/i.test(received)) return false;
const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(rawBody, 'utf8').digest();
return crypto.timingSafeEqual(Buffer.from(received, 'hex'), expected);
}
// O corpo é JSON enviado como Content-Type text/plain: mantenha o texto bruto para o HMAC.
app.post('/webhooks/localpayment', express.text({ type: '*/*', limit: '1mb' }), (req, res) => {
if (!hasValidSignature(req.body, req.get('x-signature'))) return res.sendStatus(401);
let event;
try {
event = JSON.parse(req.body);
} catch {
return res.sendStatus(400);
}
res.sendStatus(200); // responda rápido, antes de qualquer processamento pesado
// Processe de forma assíncrona. Deduplique por internalId/externalId + status
// para aplicar cada reentrega uma única vez. Nunca registre o payload completo.
jobQueue.enqueue(event);
});Passo 6 de 6
Checklist para entrar em produção
As credenciais de produção só são emitidas após estas verificações. Planeje-as cedo: elas ajudam a proteger cada empresa na plataforma, inclusive a sua.
Conclua os testes no Stage
Cubra os caminhos de sucesso, recusa, pendência e erro para cada método e país que você vai lançar.
Passe na revisão de segurança
Nossa equipe revisa e certifica sua integração antes de liberar o acesso à produção.
Conclua a verificação da empresa
A equipe de compliance verifica sua empresa, os sócios e o caso de uso (KYB) como parte do credenciamento.
Guarde bem as credenciais de produção
Mantenha-as em um gerenciador de segredos, separadas do Stage, com acesso restrito aos serviços que precisam delas.
Cadastre os IPs de produção
Adicione os IPs de saída dos seus servidores de produção no Business Portal de produção.
Configure os webhooks de produção
Cadastre seu endpoint HTTPS de produção e confirme que a verificação de assinaturas funciona antes da primeira transação real.
Solução de problemas
Problemas comuns nas primeiras chamadas
Recebo 401 Unauthorized. O que devo verificar?
Os tokens de acesso expiram em 5 minutos. Renove com POST /api/token/refresh/ ou peça um token novo, e confirme que o cabeçalho é Authorization: Bearer seguido do token de acesso.
Minha requisição é rejeitada mesmo com um token válido.
Verifique se o IP de saída do servidor que faz a chamada está cadastrado no Business Portal daquele ambiente. Stage e produção são configurados separadamente.
Por que recebi 409 Conflict?
Esse externalId já foi usado. Consulte a transação existente com GET /api/transactions/{externalId}/status em vez de criar uma nova.
O pay-in continua em 100 INPROGRESS.
É o esperado em métodos assíncronos como Pix, transferências bancárias e contas virtuais: o status muda quando o pagador paga, e o status final chega por webhook.
A assinatura do meu webhook não confere.
Calcule o HMAC sobre o corpo bruto da requisição exatamente como recebido, antes de interpretar o JSON, e remova o prefixo "HMAC-SHA256 " do cabeçalho antes de comparar.
Precisa de credenciais do Stage?
Conte seu caso de uso e seus mercados. Nossa equipe vai acompanhar você no credenciamento e liberar o acesso ao Stage quando a parceria começar.

Stage: sem dinheiro real