nodejs
Node.js fetch sample
A Node.js example using the native fetch API to authenticate against a sandbox endpoint, covering environment configuration, timeout handling, retries and safe logging of processor responses.
Why native fetch
Node.js 18+ ships a native fetch implementation, so for most integrations you no longer need axios or node-fetch as a dependency just to call a published sandbox endpoint. This keeps the dependency surface small, which matters for anything handling payment credentials.
Environment configuration
Keep the base URL and API key in environment variables, loaded via dotenv in development and through your platform's secret manager in production:
# .env (development only — never commit)
PROCESSOR_BASE_URL=https://sandbox.example.com
PROCESSOR_API_KEY=sk_sandbox_xxxxxxxxxxxxxxxx
Node.js example
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10_000);
try {
const res = await fetch(`${process.env.PROCESSOR_BASE_URL}/v1/ping`, {
headers: {
Authorization: `Bearer ${process.env.PROCESSOR_API_KEY}`,
Accept: 'application/json',
},
signal: controller.signal,
});
if (!res.ok) {
const body = await res.text();
throw new Error(`Processor returned ${res.status}: ${body}`);
}
const data = await res.json();
console.log(data);
} catch (err) {
if (err.name === 'AbortError') {
console.error('Processor request timed out after 10s');
} else {
console.error('Processor request failed:', err.message);
}
throw err;
} finally {
clearTimeout(timeout);
}
Retries with backoff
For transient failures (network errors, 502/503/504), wrap the call in a small retry helper with exponential backoff rather than looping tightly:
async function withRetry(fn, attempts = 3, baseDelayMs = 200) {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (err) {
if (i === attempts - 1) throw err;
await new Promise((r) => setTimeout(r, baseDelayMs * 2 ** i));
}
}
}
Error handling
Treat 4xx responses as non-retryable request errors (fix the payload or auth, don't loop) and 5xx as potentially transient. Always read and log the response body on failure — processor error payloads usually include a machine-readable error code that is far more useful for triage than the HTTP status alone, but scrub any card or account identifiers before writing to logs.
Security notes
- Never expose
PROCESSOR_API_KEYto client-side/browser code — all calls to compliance endpoints must originate from your backend. - Set an explicit timeout (as shown with
AbortController) so a hanging upstream call cannot exhaust your Node event loop's available connections under load. - If you receive webhooks from the processor, verify the signature on the raw request body before parsing it as JSON — signature verification against an already-parsed/re-serialized body can fail even for legitimate payloads due to key ordering or whitespace differences.