Heads up: the endpoints, field names and base URLs below are a a live reference against our sandbox. Replace them with your real API surface before publishing — developers will copy this code verbatim.
Quickstart
Create a sandbox account, generate a key, and make your first authenticated call. The sandbox returns realistic responses and never moves real money.
# List accounts in the sandbox curl https://api.securepaymentz.com/v1/accounts \ -H "Authorization: Bearer sk_test_..." \ -H "SP-Version: 2026-01-15"
A successful call returns 200 with a paginated list. If you get 401, the key is
wrong or belongs to the other environment.
Authentication
All requests use a bearer token in the Authorization header. Keys are environment-scoped: a test key never touches production data.
| Prefix | Environment | Moves real money |
|---|---|---|
sk_test_ | Sandbox | No |
sk_live_ | Production | Yes |
Never put a secret key in frontend code. Anything shipped to a browser or mobile app is readable. Call our API from your server only.
Environments
| Environment | Base URL |
|---|---|
| Sandbox | https://api.sandbox.securepaymentz.com/v1 |
| Production | https://api.securepaymentz.com/v1 |
Pin the API version with the SP-Version header. Without it you get the newest version, which
can change under you.
Accounts
POST/v1/accounts — open an account under your programme.
const res = await fetch('https://api.securepaymentz.com/v1/accounts', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SP_SECRET_KEY}`, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID() }, body: JSON.stringify({ holder_name: 'Acme Ltd', currency: 'USD', type: 'business' }) });
Transfers
POST/v1/transfers — move funds between accounts or out to an
external rail.
| Field | Type | Notes |
|---|---|---|
amount | integer | Minor units. $10.00 is 1000, never 10.0 |
currency | string | ISO 4217, uppercase |
rail | string | ach, sepa, wire, internal |
reference | string | Shown on the recipient statement |
Amounts are integers in minor units. Floating point on money is how rounding bugs get into production ledgers.
Cards
POST/v1/cards — issue a virtual or physical card against an
account, with optional spend controls.
{
"account_id": "acct_9f3a...",
"form_factor": "virtual",
"spend_controls": {
"per_transaction_max": 50000,
"monthly_max": 2000000,
"allowed_categories": ["travel", "software"]
}
}
Ledger
GET/v1/ledger/entries — the immutable record behind every
balance. Entries are append-only; corrections are new entries, never edits.
Use this endpoint for reconciliation rather than reading balances, so you can prove how a balance was reached.
Idempotency
Send an Idempotency-Key header on every state-changing request. If the same key arrives twice,
we return the original result instead of performing the action again.
This is what protects you when a request times out and your client retries: the customer is charged once, not twice. Keys are retained for 24 hours.
Webhooks
We POST events to your endpoint and expect a 2xx within 5 seconds. Anything else is retried
with exponential backoff for up to 72 hours.
const sig = req.headers['sp-signature']; const expected = crypto .createHmac('sha256', process.env.SP_WEBHOOK_SECRET) .update(rawBody) .digest('hex'); // comparación en tiempo constante: evita timing attacks if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) { return res.status(400).send('invalid signature'); }
Always verify the signature and use a constant-time comparison. An unverified webhook endpoint lets anyone post fake events to your ledger.
Errors & retries
| Status | Meaning | Retry? |
|---|---|---|
400 | Malformed request | No — fix the request |
401 | Bad or missing key | No |
409 | Idempotency conflict | No — inspect the original |
429 | Rate limited | Yes, honour Retry-After |
5xx | Our problem | Yes, with backoff and the same key |
Go-live checklist
| Check | Why |
|---|---|
| Live keys stored in a secret manager | Not in env files committed to git |
| Webhook signature verification enabled | Prevents forged events |
| Idempotency keys on every write | Prevents duplicate money movement |
| Amounts handled as integers end to end | Prevents rounding drift |
| Reconciliation job scheduled | Catches breaks the same day |
Alerting on 5xx and webhook failures | You hear it before your customer does |