Quickstart
Il tuo primo pagamento di test, passo dopo passo
Esegui un pagamento di test nell’ambiente Stage dopo l’onboarding e la configurazione iniziale.
- Stage: niente denaro reale
- cURL e Node.js
- Dati di test fittizi
Panoramica
Tre fasi, sei passaggi
Tutto ciò che segue gira su Stage, la sandbox che rispecchia la produzione. L’accesso alla produzione arriva alla fine, dopo i controlli del passaggio 6.
- 01
Configura l’accesso
Ricevi le credenziali Stage, salvale in un secrets manager e autorizza gli IP dei tuoi server.
Passaggi 1–2
- 02
Fai le prime chiamate
Ottieni un token, crea un incasso di test e verifica il webhook che lo conferma.
Passaggi 3–5
- 03
Vai live
Completa la security review e la verifica aziendale (KYB), poi passa alle credenziali di produzione.
Passaggio 6
Passaggio 1 di 6
Ottieni le credenziali Stage
Le credenziali Stage, un utente e una password API per api.stage.localpayment.com, vengono rilasciate all’avvio della tua partnership con Localpayment. Trattale come segreti di produzione fin dal primo giorno.
- Carica le credenziali da un secrets manager o da variabili d’ambiente: non committarle mai
- Stage e Produzione usano credenziali e base URL diversi
- Usa solo dati di test fittizi, mai dati reali dei clienti
// Carica le credenziali di Stage da AWS Secrets Manager all’avvio (AWS SDK v3).
// Va bene qualsiasi vault: l’importante è che i segreti non stiano mai nel codice sorgente.
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 atteso: { "username": "…", "password": "…", "webhookSecret": "…" }
return JSON.parse(SecretString);
}Passaggio 2 di 6
Autorizza gli IP dei tuoi server
L’API accetta solo chiamate dagli indirizzi IP che hai autorizzato. Aggiungi gli IP in uscita dei tuoi server nel Business Portal di Stage prima della prima richiesta.
- Business Portal → Whitelist your IP
- Le richieste da qualsiasi altro IP vengono rifiutate
- Serverless o autoscaling? Instrada il traffico in uscita attraverso un IP di egress fisso (NAT)
- Ripeti la configurazione per la produzione prima del go-live
- PCI DSS v4.0.1
- SOC 2 Type II
- ISO 27001
- AML/KYC
- TLS 1.2+ · AES-256
Passaggio 3 di 6
Ottieni un token di accesso
Scambia utente e password API con una coppia di JWT. Invia il token di accesso come bearer token in ogni chiamata e rinnovalo prima che scada.
- Token di accesso: valido 5 minuti
- Refresh token: valido 24 ore, usa POST /api/token/refresh/
- Tieni i token in memoria e non scriverli mai nei log
# Ottieni un token di accesso su Stage (valido 5 minuti)
curl -X POST https://api.stage.localpayment.com/api/token/ \
-H "Content-Type: application/json" \
-d "{\"username\": \"$LP_API_USER\", \"password\": \"$LP_API_PASSWORD\"}"Passaggio 4 di 6
Crea un incasso di test
Questo esempio crea un incasso Pix in Brasile. La risposta restituisce un codice QR e una stringa Pix Copia e Cola, con stato 100 INPROGRESS finché il pagatore non completa il pagamento.
- Genera un nuovo UUID come externalId per ogni transazione
- Ripetere con lo stesso externalId restituisce 409 Conflict invece di creare un secondo incasso
- Importo in USD: la risposta indica l’importo in BRL pagato dal pagatore e il tasso di cambio applicato
# Incasso Pix di esempio su Stage (Brasile). Valori fittizi;
# consulta docs.localpayment.com per il contratto 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" }
}
}'Passaggio 5 di 6
Gestisci il webhook
Quando il pagamento si completa, Localpayment invia una notifica firmata al tuo endpoint HTTPS. Verifica la firma sul body grezzo, rispondi subito 200 ed elabora in modo asincrono.
- Registra il tuo URL in Business Portal → Configurations → Clients → Notifications
- Confronta x-Signature con il tuo HMAC-SHA256 usando un confronto a tempo costante
- Gli invii senza risposta 200 vengono ripetuti con backoff esponenziale
// Ricevitore Express per i webhook di Localpayment (Node.js 18+).
import crypto from 'node:crypto';
import express from 'express';
import { jobQueue } from './queue.js'; // la tua coda di job asincroni
const app = express();
// Carica il segreto del webhook dal tuo secrets manager all’avvio. Mai scriverlo nel codice.
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 dell’header: "x-Signature: HMAC-SHA256 <hex>". Rimuovi prima il prefisso.
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);
}
// Il body è JSON inviato come Content-Type text/plain: conserva il testo grezzo per l’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); // conferma subito, prima di qualsiasi elaborazione pesante
// Elabora in modo asincrono. Deduplica per internalId/externalId + stato
// così un nuovo invio viene applicato una sola volta. Non loggare mai il payload completo.
jobQueue.enqueue(event);
});Passaggio 6 di 6
Checklist per il go-live
Le credenziali di produzione vengono rilasciate solo dopo questi controlli. Pianificali per tempo: proteggono tutti i merchant della piattaforma, te compreso.
Completa i test su Stage
Copri i casi di successo, rifiuto, attesa ed errore per ogni metodo e paese che lancerai.
Supera la security review
Il nostro team esamina e certifica la tua integrazione prima di concedere l’accesso alla produzione.
Completa la verifica aziendale
Il team compliance verifica la tua azienda, la struttura proprietaria e il caso d’uso (KYB) durante l’onboarding.
Conserva al sicuro le credenziali di produzione
Tienile in un secrets manager, separate da Stage, e limita l’accesso ai soli servizi che ne hanno bisogno.
Autorizza gli IP di produzione
Aggiungi gli IP in uscita dei tuoi server di produzione nel Business Portal di produzione.
Configura i webhook di produzione
Registra il tuo endpoint HTTPS di produzione e verifica che il controllo della firma passi prima della prima transazione reale.
Risoluzione dei problemi
Problemi comuni alle prime chiamate
Ricevo 401 Unauthorized. Cosa devo controllare?
I token di accesso scadono dopo 5 minuti. Rinnovali con POST /api/token/refresh/ o richiedi un nuovo token, e verifica che l’header sia Authorization: Bearer seguito dal token di accesso.
La mia richiesta viene rifiutata anche con un token valido.
Verifica che l’IP in uscita del server chiamante sia autorizzato nel Business Portal per quell’ambiente. Stage e Produzione si configurano separatamente.
Perché ho ricevuto 409 Conflict?
Quell’externalId è già stato usato. Consulta la transazione esistente con GET /api/transactions/{externalId}/status invece di crearne una nuova.
L’incasso resta in 100 INPROGRESS.
È normale per i metodi asincroni come Pix, bonifici e conti virtuali: lo stato cambia quando il pagatore paga e lo stato finale arriva via webhook.
La firma del mio webhook non corrisponde.
Calcola l’HMAC sul body grezzo della richiesta esattamente come lo ricevi, prima di qualsiasi parsing JSON, e rimuovi il prefisso "HMAC-SHA256 " dall’header prima del confronto.
Ti servono le credenziali Stage?
Raccontaci il tuo caso d’uso e i tuoi mercati. Il nostro team ti guiderà nell’onboarding e attiverà l’accesso a Stage all’avvio della partnership.

Stage: niente denaro reale