Quickstart
Take a sandbox terminal from cold start to your first approved sale and webhook delivery in under ten minutes.
Provision a sandbox terminal
Sandbox terminals are free, instant, and behave identically to production. They run real EMV kernels against simulated card images and a mock acquirer.
Sign in at dashboard.atlas-softpos.com and click Provision sandbox terminal. You'll get a terminal ID and a sandbox API key (prefix sk_test_). Stash both in environment variables:
export ATLAS_API_KEY="sk_test_..."
export BASE_URL="https://sandbox.atlas-softpos.com"Confirm the terminal is reachable
Always health-check the terminal before trying to take a payment. The endpoint is cheap, idempotent, and surfaces network and firmware status in one call.
curl $BASE_URL/v1/device/health \
-H "X-Api-Key: $ATLAS_API_KEY"{
"connected": true,
"terminalId": "TID-SBX-00001",
"firmwareVersion": "1.4.2",
"connectivity": { "method": "WIFI", "signalStrength": -42 },
"uptime": 86400
}Run your first sale
Sandbox sales auto-approve unless you use one of the magic decline PANs. Note the Idempotency-Key — this is the safe-retry token that lets you survive network blips without double-charging.
curl $BASE_URL/v1/transaction/sale \
-H "X-Api-Key: $ATLAS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"type": "SALE",
"amount": 2500,
"currency": "NZD",
"referenceId": "DEMO-001"
}'{
"transactionId": "txn_01JQXYZ123456",
"status": "APPROVED",
"type": "SALE",
"amount": 2500,
"currency": "NZD",
"authorizationCode": "A12345",
"responseCode": "00",
"cardScheme": "VISA",
"maskedPan": "************0002",
"entryMode": "CONTACTLESS",
"timestamp": "2026-04-08T11:14:22Z"
}See Test Cards for the full set of sandbox PANs and decline scenarios.
Listen for the settlement webhook
Atlas delivers a signed webhook to your backend when the transaction settles, when a refund completes, when a dispute opens, and at end-of-day reconciliation. Always verify the signature before trusting the payload.
import express from "express";
import crypto from "crypto";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/atlas-webhook", (req, res) => {
const sig = req.headers["atlas-signature"];
const expected = crypto
.createHmac("sha256", process.env.ATLAS_WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
if (sig !== `v1=${expected}`) {
return res.status(401).end();
}
const event = JSON.parse(req.body);
console.log("Received:", event.type, event.data.transactionId);
res.status(200).end();
});
app.listen(4242);Full event taxonomy and signature scheme on the Webhooks page.
Go live
When you're ready, swap your sandbox key for a live key (prefix sk_live_) and point your client at the production base URL. There are no code changes — same schema, same behavior, real funds.
export ATLAS_API_KEY="sk_live_..."
export BASE_URL="https://api.atlas-softpos.com"Before flipping to production, walk through the Error reference and the Idempotency contract one more time.
You now have a working integration end-to-end. Browse the Sale endpoint reference for the complete schema, or read Connectivity & Flows to understand how to switch between local, cloud, and embedded modes without changing your code.