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.
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.
| 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 Standard API key, an S2S API key and a Brand ID, all from the Developers section of your dashboard. |
| 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.
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:
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.
| 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 |
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.
checkout_urlThese 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.
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.
Processing without a 3D Secure challenge is available to approved merchants. It is not prohibited, but it changes your risk and cost position:
Approval is per brand. Contact your account manager before building against this flow.
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.
sequenceDiagram
participant M as Your server
participant P as Precium
participant I as Issuer
M->>P: POST /purchases/
P-->>M: purchase id + direct_post_url
M->>P: POST direct_post_url?s2s=true (card data)
P-->>M: 3D Secure parameters
M->>I: Redirect cardholder to authenticate
I-->>P: Authentication result
P-->>M: Webhook: purchase.paid3D 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 are the authoritative source of transaction outcomes. Do not rely on browser redirects — a customer who closes the tab still completes a payment.
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.
purchase.paid callback is sent for a purchase until every purchase.created callback 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.
There is no idempotency key. Precium prevents duplicates through transaction state instead:
409 ConflictPractically: 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.
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.
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.
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.