Authentication
Every Scan & Pay API request authenticates with a single header carrying your API Secret. There is no OAuth dance, no signed-request scheme, no nonces — keep the secret server-side and send it on every call.
The X-Scanpay-Key header
Set the header on every request to api.scanandpay.com.au except /ping. Requests without it return 401 Unauthenticated.
curl https://api.scanandpay.com.au/createPaymentSession \
-X POST \
-H "X-Scanpay-Key: $SCANANDPAY_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"merchantId": "xxxxxxxxxxxxxxxxxxxx",
"platformOrderId": "order_456",
"amount": 19.90,
"payId": "merchant@example.com.au",
"merchantName": "Acme Coffee"
}'The same header is used by both official SDKs:
use ScanAndPay\ScanAndPay;
$client = new ScanAndPay(
merchantId: 'xxxxxxxxxxxxxxxxxxxx',
apiSecret: getenv('SCANANDPAY_API_SECRET'),
);import { ScanAndPay } from '@scanandpay/node';
const sp = new ScanAndPay({
merchantId: 'xxxxxxxxxxxxxxxxxxxx',
apiSecret: process.env.SCANANDPAY_API_SECRET!,
});Where to find your credentials
- 1Sign in to merchant.scanandpay.com.au.
- 2Open Settings → Integrations.
- 3Copy Merchant ID, API Base URL, API Secret, and Webhook Secret into your environment variables.
SCANANDPAY_MERCHANT_ID=xxxxxxxxxxxxxxxxxxxx
SCANANDPAY_API_SECRET=sp_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SCANANDPAY_WEBHOOK_SECRET=sp_wh_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SCANANDPAY_API_BASE_URL=https://api.scanandpay.com.auRotation
Press Regenerate API Credentials in the dashboard only when you believe a secret is compromised. Rotation is immediate and total: the old API Secret and Webhook Secret are revoked the moment the new pair is issued. Every connected system fails closed until you paste in the new values.
Plan rotations during low traffic. There is no grace period and no overlap — both production and staging consume the same single credential set today.
Test vs live
No separate test environment yet. Every call hits the production API and creates real payment sessions. To test an integration without taking real money: create a session for a low amount (e.g. 0.01) and simply do not pay it — the session expires after 5 minutes. A sandboxed test mode is on the roadmap.
Authentication errors
| Status | error | Cause |
|---|---|---|
| 401 | Missing X-Scanpay-Key header | Header not set, or empty. |
| 401 | Invalid API key | Header set but does not match an active key. Check for stale rotation. |
| 403 | SUBSCRIPTION_REQUIRED | Merchant account has no active subscription. The merchant must update billing in the dashboard. |
Next
- → Payments API — create and read payment sessions
- → Webhooks — receive signed payment events
- → OpenAPI spec — full machine-readable contract