The Precium Server-to-Server (S2S) API gives you direct control of the full card payment flow. You handle card data on your own infrastructure and call Precium for authentication, authorisation, capture, refunds and reporting.
This is the most flexible of the Precium integrations and the only one that requires full PCI DSS scope. If you do not need card data on your servers, one of the lower-scope options below will get you live faster.
Choosing an integration
All four options run on the same API and the same credentials. They differ only in where card data is entered, and therefore in your PCI DSS obligation.
| Integration | PCI scope | Card data entered | Best for |
|---|---|---|---|
| Hosted Checkout | SAQ-A | On a Precium-hosted page | Fastest route live, minimal compliance burden |
| Payment Links | SAQ-A | On a Precium-hosted page | Invoicing, email and manual billing |
| Direct Post | SAQ A-EP | In your form, posted straight to Precium | Branded checkout without card data touching your servers |
| Server-to-Server | SAQ-D | On your server | PSPs and platforms needing full control of the flow |
Direct Post is worth a look before committing to S2S: you keep a fully branded checkout, but because card data posts from the customer’s browser directly to Precium, your scope is raised only to SAQ A-EP rather than SAQ-D. See the Payment Orchestration documentation for both hosted and Direct Post flows.
Who this is for
- Payment service providers and payment facilitators serving their own merchant networks
- Enterprise merchants with an existing PCI-compliant cardholder data environment
- Platforms and marketplaces embedding payments where the checkout must be fully owned
Prerequisites
| Requirement | Detail |
|---|---|
| PCI DSS | Level 1 validation for your cardholder data environment, evidenced by a current Attestation of Compliance. Your Attestation must be on file with Precium before live keys are issued. |
| Credentials | A bearer token and a Brand ID from the Developers section of your dashboard, plus an S2S token issued separately by Precium to qualifying merchants. |
| HTTPS endpoints | TLS 1.2 or higher, for 3D Secure redirects and webhook delivery. |
| Webhook handling | An endpoint that verifies signatures and tolerates duplicate delivery. See Webhooks below. |
Your brand may need to be approved by support@precium.com before it can be used for live transactions.
Base URL and environments
Every request goes to:
https://gate.reviopay.com/api/v1/Endpoint paths in this documentation are relative to that base. For example, /purchases/ means https://gate.reviopay.com/api/v1/purchases/.
Test and production share this base URL. The environment is determined entirely by which API key you send — there is no separate sandbox host. Two consequences worth designing around:
- A key mixed up in configuration will send live card traffic through what you believe is a test integration. There is no URL-level safeguard, so keep test and live keys in separate secret stores and never fall back from one to the other.
- Test and live data are fully separate. A test webhook never receives events caused by live purchases, and vice versa.
Authentication
Precium uses bearer token authentication. Send your API key in the Authorization header of every request:
Authorization: Bearer YOUR_API_KEY| Key | Used for |
|---|---|
| Standard API key | All API operations: creating clients and purchases, capture, refund, cancel, webhooks and reporting |
| S2S API key | Submitting card data to the direct_post_url returned on a purchase |
Creating a purchase requires both your API key and your Brand ID. Never expose either in client-side code, mobile applications or logs.
Core endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /clients/ | Create a customer record |
| POST | /purchases/ | Create a transaction |
| GET | /purchases/{id}/ | Retrieve a transaction and its attempt history |
| POST | /purchases/{id}/charge/ | Charge a stored token |
| POST | /purchases/{id}/capture/ | Capture funds held by an authorisation |
| POST | /purchases/{id}/release/ | Release held funds without capturing |
| POST | /purchases/{id}/refund/ | Refund in full or in part |
| POST | /purchases/{id}/cancel/ | Cancel a purchase |
| POST | /purchases/{id}/delete_recurring_token/ | Delete a stored card token |
| GET | /clients/{id}/recurring_tokens/ | List a customer’s stored tokens |
| GET | /payment_methods/ | List methods enabled for a brand and currency |
| GET | /public_key/ | Retrieve the key for verifying callback signatures |
How transactions are classified
Precium classifies every transaction by who initiated it. This determines whether 3D Secure is required, whether a CVC is needed, and where chargeback liability sits — so it is the first thing to establish when choosing a flow.
| Class | Meaning | 3D Secure | CVC |
|---|---|---|---|
| CIT | Customer-initiated. The cardholder is present and acting. | Required | Required |
| CIT → MIT | A customer-initiated payment that stores a token for later merchant-initiated use. | Required on the first payment | Required on the first payment |
| MIT | Merchant-initiated against a stored token. The cardholder is not present. | Not presented | Not used — may be stubbed |
In South Africa the first charge on a card must always be authenticated with 3D Secure. Subsequent merchant-initiated charges against the resulting token do not present a challenge.
Supported flows
- Regular redirect — create a purchase, send the customer to the returned
checkout_url - Direct Post — your form, card data posted straight to Precium (SAQ A-EP)
- Preauthorisation — verify a card and store it without moving money
- Delayed capture — hold funds now, capture or release later
- Tokenised instant capture — charge a stored token immediately
- Tokenised delayed capture — hold against a stored token, capture later
- External MPI — bring your own 3D Secure provider
- External network tokens — present your own VTS or MDES token and cryptogram
- Non-3DS — for approved merchants only; see below
Preauthorisation and delayed capture
These are distinct operations and the difference matters. Both use skip_capture, and the amount decides which one you get.
| Operation | Request | Resulting status | Effect |
|---|---|---|---|
| Preauthorisation | skip_capture: true with a purchase total of 0 | preauthorized | Cardholder verification only. No financial transaction. The card is stored. |
| Delayed capture | skip_capture: true with a non-zero total | hold | Funds are reserved. Complete with /capture/ or release with /release/. |
A purchase in hold must be resolved. Capture takes an optional amount to capture less than was authorised; anything not captured is released. Both operations are asynchronous: if the acquirer is slow you receive HTTP 200 with a status of pending_capture or pending_release, and the outcome arrives by webhook.
Refunds
Refund a settled purchase in full, or in part by sending an amount. Partial refunds may be issued repeatedly until the original total is exhausted — check refund_availability and refundable_amount on the purchase before refunding, since not every payment method supports partial refunds.
A refund cannot be voided. Once submitted it runs to completion; there is no reversal operation.
Non-3DS processing
Processing without a 3D Secure challenge is available to approved merchants. It is not prohibited, but it changes your risk and cost position:
- Transactions attract a higher interchange fee and are treated as higher risk
- You do not receive the liability shift that authentication provides, so chargeback exposure sits with you
- Issuer decline rates are typically higher
Approval is per brand. Contact your account manager before building against this flow.
Your first request
Create a purchase. client or client_id, purchase and brand_id are all required. All amounts are integers in cents.
curl -X POST https://gate.reviopay.com/api/v1/purchases/ \
-H "Authorization: Bearer $PRECIUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"client_id": "00000000-0000-4000-8000-000000000001",
"brand_id": "00000000-0000-4000-8000-000000000002",
"purchase": {
"currency": "ZAR",
"products": [
{ "name": "Order 1042", "price": 149900 }
]
},
"reference": "ORDER-1042",
"success_redirect": "https://www.example.com/success",
"failure_redirect": "https://www.example.com/failure"
}'The response contains the purchase id, a checkout_url for hosted checkout, and a direct_post_url for submitting card data yourself. Note that direct_post_url is returned only when both success_redirect and failure_redirect are supplied.
Integration flow
3D Secure
3D Secure 2 is fully supported. The S2S flow exchanges MD, PaReq and PaRes, which are 3DS1 parameter names, but these operate as a proxy ACS wrapper: Precium performs full 3DS2 verification and challenge on your behalf while presenting the simpler redirect contract to your integration. You do not need to implement 3DS2 device fingerprinting or the challenge flow yourself.
If you already run your own Merchant Plug-In, use the External MPI flow and pass your own authentication results instead.
Webhooks
Webhooks are the authoritative source of transaction outcomes. Do not rely on browser redirects — a customer who closes the tab still completes a payment.
Verifying a callback
Payloads are signed with asymmetric public-key cryptography. Every delivery carries an X-Signature header containing a base64-encoded RSA PKCS#1 v1.5 signature of the SHA-256 digest of the raw request body.
| Callback type | Where to get the public key |
|---|---|
| Webhook subscription | public_key on the corresponding webhook object |
| Per-purchase success callback | GET /public_key/ |
Verify against the raw body bytes, before any JSON parsing or re-serialisation — reformatting the payload invalidates the signature. Precium is not responsible for losses arising from unverified payloads.
Delivery behaviour
- A delivery is successful only on a 2xx response. Failures are retried up to 8 further times at exponentially increasing intervals.
- No delivery is attempted more than 36 hours after the triggering event.
- Duplicates are possible even after you return 200, if the confirmation is lost in transit. Handlers must be idempotent.
- Deliveries are sequential per object: no
purchase.paidcallback is sent for a purchase until everypurchase.createdcallback for it has been delivered.
Twenty-nine event types are available, covering the purchase lifecycle, payments, refunds, chargebacks, payouts and settlement. Subscribe only to what you act on. See Integration guide for the full list.
Duplicate protection
There is no idempotency key. Precium prevents duplicates through transaction state instead:
- Every purchase has a unique identifier and may be paid only once
- Repeat attempts against an already-paid purchase are rejected, typically with
409 Conflict - You may create any number of purchases for a client, but each is independently payable once
Practically: create one purchase per order attempt and retry against that same purchase id rather than creating another. Confirm state with GET /purchases/{id}/ before retrying anything.
Rate limits and pagination
Requests are limited to 100 per minute, with short bursts to 200. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; back off when you see 429.
List endpoints are cursor-paginated, returning results with next and previous URLs. Follow next rather than constructing offsets.
Settlement
Transactions are authorised and settled the next day. Settlement of funds to your account may be scheduled differently depending on your commercial model, so confirm your settlement cycle with your account manager rather than inferring it from transaction timing.
Going live
- Complete your integration against test credentials
- Work through the scenarios in Test scenarios, including declines, expiries and 3D Secure failures
- Confirm your webhook endpoint verifies signatures and handles duplicate delivery
- Place your PCI Attestation of Compliance on file with Precium
- Request live credentials and brand approval from your account manager
Support
Technical questions, credential requests and brand approvals: support@precium.com.
For the full endpoint reference, including every request field and response code, see Technical reference documentation.