ArtsPay API
The Arts Pay payment gateway is built on the Fat Zebra REST API. It is designed around predictable, resource-oriented URLs, uses standard HTTP verbs, accepts JSON request bodies, and returns JSON in every response. Authentication is handled via HTTP Basic Auth — no OAuth flows, no SDK required.
Test card numbers for use in our sandbox environment, VISA, Mastercard, American Express etc. Each card number has a predetermined purchase response code.
Standard HTTP response codes to indicate success or failure of an API request. In general, codes in the 2XX range indicate success.
When making requests to the Gateway it is important to understand transaction processing timeouts to ensure the best customer experience possible.
Getting Started
All API requests are made over HTTPS to one of two base URLs depending on the environment you're targeting. Start in the Sandbox. Your sandbox credentials are separate from your production credentials and all transactions made against it are simulated — no real money moves. When your integration is complete and tested, swap the base URL and credentials to go live.
| Environment | Base URL |
|---|---|
| Sandbox | https://gateway.pmnts-sandbox.io/v1.0 |
| Production | https://gateway.pmnts.io/v1.0 |
The simplest way to verify your credentials is a GET against the health check endpoint:
curl https://gateway.pmnts-sandbox.io/v1.0/health \ -u YOUR_USERNAME:YOUR_API_TOKENA 200 OK means your credentials are valid and the gateway is reachable.
Never use real card numbers in the Sandbox. Use the test card numbers provided in the Testing section instead.
Authentication
The API uses HTTP Basic Authentication. Every request must include your username and API token as the Basic Auth credentials — the username as the user, the token as the password.
curl https://gateway.pmnts-sandbox.io/v1.0/purchases \ -u YOUR_USERNAME:YOUR_API_TOKEN \ -H "Content-Type: application/json"Your sandbox username is always prefixed with TEST (e.g. TEST-USERNAME). Usernames are case-insensitive, but API tokens are case-sensitive — copy them exactly as provided.
All requests must be made over HTTPS. Plain HTTP requests will fail.
Keeping credentials secure
- Store credentials in environment variables, never in source code.
- Your API token should be treated like a password — rotate it immediately if it is ever exposed.
- Sandbox and production credentials are entirely separate. You cannot use sandbox credentials against the production endpoint or vice versa — attempting to do so will return a
403 Forbidden.
Requests
Set the Content-Type header to application/json on all POST and PUT requests.
Amounts are always expressed as integers in the smallest unit for the currency — for AUD, that means cents. $49.95 is sent as 4995. This avoids any floating-point ambiguity.
Currencies use ISO 4217 codes (e.g. AUD, USD, NZD).
curl https://gateway.pmnts-sandbox.io/v1.0/purchases \ -u TEST:TEST \ -H "Content-Type: application/json" \ -X POST \ -d '{ "amount": 4995, "currency": "AUD", "reference": "order-1234", "card_holder": "Jane Smith", "card_number": "4005550000000001", "card_expiry": "10/2027", "cvv": "123" }'{ "successful": true, "response": { "id": "001-P-ABC12345", "authorization": "12345", "card_number": "400555XXXXXX0001", "card_holder": "Jane Smith", "card_expiry": "2027-10-31", "card_token": "tok_abc123", "card_type": "VISA", "amount": 4995, "decimal_amount": 49.95, "successful": true, "message": "Approved", "reference": "order-1234", "currency": "AUD", "transaction_id": "txn_xyz789", "response_code": "00", "transaction_date": "2026-07-08T10:42:00Z", "settlement_date": "2026-07-09" }, "errors": [], "test": true}The test field in every response confirms whether the request was processed in sandbox mode.
Pagination
List endpoints (GET /purchases, GET /refunds, etc.) return paginated results. By default, 10 records are returned per page. Pass limit (max 50) and offset (page number, starting at 1) as query parameters:
GET /v1.0/purchases?limit=25&offset=2Paginated responses include records, total_records, page, and total_pages at the top level alongside response.
Responses
Every API response shares the same top-level envelope. A successful: true response at the top level means the API request itself was valid and processed. For payment transactions, also check response.successful — a card decline returns successful: true (the request worked) but response.successful: false (the payment was declined).
| Field | Type | Description |
|---|---|---|
| successful | Boolean | Whether the request was processed without errors |
| response | Object or Array | The result data — a single object for individual resources, an array for list endpoints |
| errors | Array of strings | Validation or processing errors, if any |
| test | Boolean | true if the request was made against the Sandbox |
{ "successful": true, "response": { "successful": false, "message": "Declined", "response_code": "05" }, "errors": [], "test": true}