Documentation

Integrate once, reach every rail

Everything needed to move from sandbox to production: authentication, the four core APIs, webhooks and going live.

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.

curlFirst request
# 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.

PrefixEnvironmentMoves real money
sk_test_SandboxNo
sk_live_ProductionYes

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

EnvironmentBase URL
Sandboxhttps://api.sandbox.securepaymentz.com/v1
Productionhttps://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.

nodeCreate an account
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.

FieldTypeNotes
amountintegerMinor units. $10.00 is 1000, never 10.0
currencystringISO 4217, uppercase
railstringach, sepa, wire, internal
referencestringShown 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.

jsonRequest body
{
  "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.

nodeVerify the signature
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

StatusMeaningRetry?
400Malformed requestNo — fix the request
401Bad or missing keyNo
409Idempotency conflictNo — inspect the original
429Rate limitedYes, honour Retry-After
5xxOur problemYes, with backoff and the same key

Go-live checklist

CheckWhy
Live keys stored in a secret managerNot in env files committed to git
Webhook signature verification enabledPrevents forged events
Idempotency keys on every writePrevents duplicate money movement
Amounts handled as integers end to endPrevents rounding drift
Reconciliation job scheduledCatches breaks the same day
Alerting on 5xx and webhook failuresYou hear it before your customer does

Talk to an engineer Visit Help Center