Merchant API
v1.0

Developer Documentation

The Tribe Pay Merchant API lets you accept payments from your website or application. You initiate a payment session from your server, redirect your customer to a hosted checkout page, and receive the result via webhook or status query.

Card data is collected by the payment gateway directly — it never passes through Tribe Pay's servers or yours, satisfying PCI DSS SAQ-A.

Base URL

Base URL
https://api.tribe-pay.com

All API requests must be made over HTTPS. All request and response bodies are JSON.

During development, replace https://api.tribe-pay.com with your local instance URL (e.g. http://127.0.0.1:8123) and use a pk_test_ key to avoid charging real cards.

Quick Start

Get a payment running in three steps.

1
Register your business & get an API key

Log in to the Tribe Pay merchant portal, go to Developer → API Keys, and copy your live key (pk_live_…) or test key (pk_test_…).

2
Call /api/pay/initiate from your server

Send the order details and receive a checkout_url. Redirect your customer to that URL — Tribe Pay handles the card form.

3
Receive the result

After payment, the customer is sent to your return_url. Confirm the outcome by calling GET /api/pay/status/{order_id} or by listening for the payment.completed webhook event.

Authentication

All payment API requests require two headers: a public API key and a secret key.

Headers
X-API-Key:    pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

X-API-Key identifies your merchant account. X-Secret-Key proves the request is from you. Both are required on every request.

Key types

PrefixModeBehaviour
pk_live_…liveReal money is charged. Payments are credited to your wallet.
pk_test_…sandboxNo real money. Use test cards. Wallets are not credited.

Keep both keys secret. Never expose them in client-side code, mobile apps, or public repositories. If a key pair is compromised, revoke it immediately from the merchant portal and generate a new one. The secret key is shown only once — save it securely.

You can have up to 5 active keys at once. Label each key by environment or service (e.g. "Production Server", "Staging") for easy management.

Sandbox Mode

Use a pk_test_ key to run payments in sandbox mode. All requests hit real API endpoints — the only difference is that the payment gateway operates in test mode and no real funds move.

BehaviourLiveSandbox
Real money chargedYesNo
Wallet credited on successYesNo
Webhooks firedYesYes
Response mode fieldlivesandbox

See Test Cards for card numbers to use on the sandbox checkout page.

Initiate Payment

Creates a checkout session and returns a hosted checkout URL. Call this from your server when a customer is ready to pay.

POST /api/pay/initiate

Request parameters

ParameterTypeRequiredDescription
order_idstringRequiredYour unique order identifier. Max 100 characters. Must be unique per merchant.
amountnumberRequiredPayment amount as a decimal. Minimum 1, maximum 1,000,000.
currencystringRequiredISO 4217 currency code (e.g. USD, EUR, ARS). Must match the currency your gateway account supports.
customer_namestringOptionalCustomer's full name. Shown on the checkout page.
customer_emailstringOptionalCustomer's email address. Used for payment receipts.
customer_phonestringOptionalCustomer's phone number including country code.
descriptionstringOptionalShort description of the purchase. Shown on checkout. Max 255 characters.
return_urlstringRequiredURL where the customer is sent after payment (success or failure). Must be HTTPS in production.
cancel_urlstringOptionalURL when the customer cancels. Falls back to return_url if not provided.
webhook_urlstringOptionalOne-time webhook URL for this payment only. Overrides any webhook configured in the portal for this request.

Example request

bash
curl -X POST https://api.tribe-pay.com/api/pay/initiate \
  -H "X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id":       "ORD-2024-001",
    "amount":         99.00,
    "currency":       "USD",
    "customer_name":  "John Smith",
    "customer_email": "john@example.com",
    "customer_phone": "+1 555 000 1234",
    "description":    "Premium Plan — 1 Month",
    "return_url":     "https://yoursite.com/payment/return",
    "cancel_url":     "https://yoursite.com/payment/cancel",
    "webhook_url":    "https://yoursite.com/webhooks/tribepay"
  }'
php
<?php

$payload = [
    'order_id'       => 'ORD-2024-001',
    'amount'         => 99.00,
    'currency'       => 'USD',
    'customer_name'  => 'John Smith',
    'customer_email' => 'john@example.com',
    'customer_phone' => '+1 555 000 1234',
    'description'    => 'Premium Plan — 1 Month',
    'return_url'     => 'https://yoursite.com/payment/return',
    'cancel_url'     => 'https://yoursite.com/payment/cancel',
];

$ch = curl_init('https://api.tribe-pay.com/api/pay/initiate');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        'X-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

$data = json_decode(curl_exec($ch), true);
curl_close($ch);

header('Location: ' . $data['checkout_url']);
exit;
javascript
const axios = require('axios');

const { data } = await axios.post(
  'https://api.tribe-pay.com/api/pay/initiate',
  {
    order_id:       'ORD-2024-001',
    amount:         99.00,
    currency:       'USD',
    customer_name:  'John Smith',
    customer_email: 'john@example.com',
    customer_phone: '+1 555 000 1234',
    description:    'Premium Plan — 1 Month',
    return_url:     'https://yoursite.com/payment/return',
    cancel_url:     'https://yoursite.com/payment/cancel',
  },
  { headers: { 'X-API-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'X-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' } }
);

res.redirect(data.checkout_url);
python
import requests

response = requests.post(
    'https://api.tribe-pay.com/api/pay/initiate',
    json={
        'order_id':       'ORD-2024-001',
        'amount':         99.00,
        'currency':       'USD',
        'customer_name':  'John Smith',
        'customer_email': 'john@example.com',
        'customer_phone': '+1 555 000 1234',
        'description':    'Premium Plan — 1 Month',
        'return_url':     'https://yoursite.com/payment/return',
        'cancel_url':     'https://yoursite.com/payment/cancel',
    },
    headers={'X-API-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'X-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'}
)

data = response.json()
return redirect(data['checkout_url'])

Response 201 Created

json
{
  "success":      true,
  "order_id":     "ORD-2024-001",
  "reference":    "TRP-K7XB-NQ2A",
  "amount":       99.00,
  "currency":     "USD",
  "mode":         "live",
  "checkout_url": "https://api.tribe-pay.com/checkout/a8f3c2e1d0b4...",
  "expires_at":   "2024-07-22T15:30:00+00:00"
}
FieldTypeDescription
referencestringTribe Pay's unique transaction reference (TRP-XXXX-XXXX). Store this alongside your order ID.
modestringlive or sandbox depending on which key was used.
checkout_urlstringRedirect your customer here. The session expires in 30 minutes.
expires_atstringISO 8601 timestamp when the checkout URL expires.

The checkout_url expires in 30 minutes. If the customer does not complete payment in time, the status becomes expired. Create a new session to let them retry.

Handle Return URL

After the customer pays (or cancels), Tribe Pay redirects them to your return_url with the following query parameters appended.

example redirect
https://yoursite.com/payment/return
  ?status=completed
  &order_id=ORD-2024-001
  &reference=TRP-K7XB-NQ2A
ParameterValues
statuscompleted · failed · cancelled · expired
order_idYour original order ID.
referenceTribe Pay reference code (TRP-XXXX-XXXX).

Do not rely on return URL parameters alone to confirm payment. These can be manipulated in the browser. Always verify by calling GET /api/pay/status/{order_id} from your server or by processing a signed webhook event.

Recommended pattern

php
<?php
$orderId = $_GET['order_id'] ?? '';

$ch = curl_init("https://api.tribe-pay.com/api/pay/status/{$orderId}");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'X-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);

if ($data['status'] === 'completed') {
    fulfil_order($orderId);
    show_success_page();
} else {
    show_failure_page($data['status']);
}

Check Payment Status

Query the current status of any payment by its order_id.

GET /api/pay/status/{order_id}
bash
curl https://api.tribe-pay.com/api/pay/status/ORD-2024-001 \
  -H "X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
php
<?php
$ch = curl_init('https://api.tribe-pay.com/api/pay/status/ORD-2024-001');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'X-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $data['status'];
javascript
const { data } = await axios.get(
  'https://api.tribe-pay.com/api/pay/status/ORD-2024-001',
  { headers: { 'X-API-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'X-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' } }
);
console.log(data.status);
python
response = requests.get(
    'https://api.tribe-pay.com/api/pay/status/ORD-2024-001',
    headers={'X-API-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'X-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'}
)
print(response.json()['status'])

Response 200 OK

json
{
  "success":   true,
  "order_id":  "ORD-2024-001",
  "reference": "TRP-K7XB-NQ2A",
  "amount":    99.00,
  "currency":  "USD",
  "status":    "completed",
  "mode":      "live",
  "paid_at":   "2024-07-22T14:35:22+00:00"
}

Webhooks

Webhooks are server-to-server notifications sent by Tribe Pay when a payment event occurs. They are the most reliable way to fulfil orders — unlike the return URL, webhooks are delivered even if the customer closes their browser.

Setup

Add a webhook endpoint in the merchant portal under Developer → Webhooks. Specify your URL and choose which events to receive. You'll receive a signing secret — save it, it's shown only once.

Your webhook endpoint must respond with HTTP 200 within 10 seconds. Acknowledge receipt first, then process the event asynchronously.

Events

payment.initiatedA checkout session was created. Payment has not been attempted yet.
payment.completedPayment was captured successfully. Safe to fulfil the order.
payment.failedPayment was declined or encountered an error.
payment.refundedA completed payment was reversed. Reverse fulfilment if applicable.

Subscribe to * to receive all events now and in the future.

Payload format

json
{
  "event":     "payment.completed",
  "timestamp": "2024-07-22T14:35:22+00:00",
  "data": {
    "order_id":  "ORD-2024-001",
    "reference": "TRP-K7XB-NQ2A",
    "amount":    99.00,
    "currency":  "USD",
    "status":    "completed",
    "mode":      "live",
    "paid_at":   "2024-07-22T14:35:22+00:00"
  }
}

Verifying the signature

Every webhook includes an X-TribePay-Signature header. Verify it before processing to confirm the request came from Tribe Pay.

Always verify the signature. Anyone who knows your webhook URL can send fake events. Reject requests with a missing or invalid signature with 401.

php
<?php
$rawBody       = file_get_contents('php://input');
$signature     = $_SERVER['HTTP_X_TRIBEPAY_SIGNATURE'] ?? '';
$signingSecret = getenv('TRIBE_WEBHOOK_SECRET');

$expected = hash_hmac('sha256', $rawBody, $signingSecret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Unauthorized');
}

$event = json_decode($rawBody, true);

http_response_code(200);
echo 'OK';
ob_flush(); flush();

if ($event['event'] === 'payment.completed') {
    fulfil_order($event['data']['order_id']);
}
if ($event['event'] === 'payment.refunded') {
    reverse_fulfilment($event['data']['order_id']);
}
javascript
const crypto = require('crypto');

app.post('/webhooks/tribepay',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const signature    = req.headers['x-tribepay-signature'] ?? '';
    const signingSecret = process.env.TRIBE_WEBHOOK_SECRET;

    const expected = crypto
      .createHmac('sha256', signingSecret)
      .update(req.body)
      .digest('hex');

    if (!crypto.timingSafeEqual(
      Buffer.from(expected),
      Buffer.from(signature)
    )) return res.status(401).send('Unauthorized');

    res.status(200).send('OK');

    const event = JSON.parse(req.body);
    if (event.event === 'payment.completed') {
      fulfilOrder(event.data.order_id);
    }
  }
);
python
import hmac, hashlib, json, os
from flask import Flask, request, abort

SIGNING_SECRET = os.environ['TRIBE_WEBHOOK_SECRET']

@app.route('/webhooks/tribepay', methods=['POST'])
def tribepay_webhook():
    signature = request.headers.get('X-TribePay-Signature', '')
    raw_body  = request.get_data()

    expected = hmac.new(
        SIGNING_SECRET.encode(), raw_body, hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(expected, signature):
        abort(401)

    event = json.loads(raw_body)
    if event['event'] == 'payment.completed':
        fulfil_order(event['data']['order_id'])

    return 'OK', 200

Retry policy

If your endpoint does not respond with 200 within 10 seconds, Tribe Pay retries with exponential back-off:

AttemptDelay
1st retry5 minutes
2nd retry30 minutes
3rd retry2 hours
4th retry8 hours
5th retry24 hours — final attempt

Your handler may receive the same event more than once due to retries. Make order fulfilment idempotent — check if an order is already fulfilled before acting on a webhook.

Payment Statuses

StatusDescriptionTerminal?
pendingCheckout session created. Customer has not yet reached the payment page.No
processingCustomer redirected to the payment gateway. Awaiting confirmation.No
completedPayment captured successfully. Funds will be credited to your Tribe Pay wallet.Yes
failedPayment was declined, rejected by the bank, or an error occurred at the gateway.Yes
expiredThe 30-minute checkout window elapsed before the customer completed payment.Yes
refundedA completed payment was reversed. The amount is deducted from your wallet.Yes

Error Codes

Errors return a JSON object with a human-readable message. Validation errors also include an errors object.

json — 422 example
{
  "message": "The given data was invalid.",
  "errors": {
    "amount":     ["The amount field is required."],
    "return_url": ["The return url must be a valid URL."]
  }
}

HTTP status codes

400
Bad request — invalid parameters or a gateway error while creating the checkout.
401
Missing or invalid X-API-Key / X-Secret-Key. Both headers are required and must match an active key pair.
404
Order ID not found, or the order belongs to a different merchant account.
422
Validation failed. Check the errors object for field-level details.
500
Internal server error. Retry with exponential back-off. If it persists, contact support.

Common errors & fixes

Error messageFix
No active payment gateway assignedAsk your Tribe Pay admin to assign a gateway account to your merchant profile.
The order id has already been takenYour order_id is not unique. Each payment must use a different value.
The return url field is requiredInclude a valid absolute URL in the return_url field.
UnauthenticatedThe X-API-Key or X-Secret-Key header is missing, invalid, or the key pair has been revoked.

Test Cards

Use these card numbers on the sandbox checkout page (any future expiry date, any CVV unless specified).

Cards that complete successfully

BrandNumberCVVExpiry
Visa4200 0000 0000 0000Any 3 digitsAny future date
Visa4000 0000 0000 0051745Any future date
Mastercard5101 0821 8725 6503123Any future date
Mastercard5454 5454 5454 5454Any 3 digitsAny future date
Amex3755 1051 3169 537123Any future date

3D Secure test cards

BrandNumberCVVBehaviour
Visa (3DS)4000 0000 0000 0002237Triggers 3D Secure challenge, then completes

Test cards only work with a pk_test_ API key. Using a test card number with a live key will result in a real declined charge.


Questions or issues? Contact your Tribe Pay account manager or open a support ticket from the merchant portal.

API Test Console

An interactive browser-based tool for testing the Tribe Pay Merchant API — without writing any code. The console shows a live request preview, generates a ready-to-run curl command, sends the request, and displays the response with syntax highlighting.

⚡
Tribe Pay API
Initiate a payment and poll its status using your X-API-Key and X-Secret-Key headers.
Initiate Status check Live preview
🔒
S2S Charge API
Test the server-to-server charge endpoint with a real card number, billing details, and live/sandbox credentials.
Charge 3DS redirect Raw JSON

Server-to-Server (S2S) API

The S2S API allows your server to submit a card payment in a single HTTP call — no hosted checkout page is involved. Your backend collects the card number, sends it directly to Tribe Pay, and receives an immediate response telling you whether the payment completed, requires 3DS authentication, or failed.

PCI DSS scope applies. Because your server handles raw card numbers you must be PCI DSS SAQ-D compliant (or use a certified vault/tokenisation service). Contact your acquirer or QSA before going live.

Hosted checkout vs S2S

Hosted Checkout (default)

  • Card data never touches your server
  • PCI DSS SAQ-A — minimal compliance burden
  • Tribe Pay renders the payment form
  • Customer is redirected then returned via return_url

S2S API (this section)

  • Your server collects and sends card data
  • Full control over the UI and checkout flow
  • Requires IP whitelisting + PCI compliance
  • Response includes a redirect_url when 3DS is triggered

POST /api/s2s/charge

Submit a card payment from your server. The gateway is called synchronously and the response includes the final status or a 3DS redirect URL.

POST /api/s2s/charge

Uses the same X-API-Key / X-Secret-Key headers as the hosted checkout API. In addition, your server's IP address must be in the merchant's S2S whitelist — requests from unlisted IPs receive 403 Forbidden.

Request fields

FieldTypeRequiredDescription
order_id string required Your unique order reference (max 100 chars). Must be different for every payment.
amount number required Payment amount in the minor currency unit (e.g. 1500 = ₹1,500 or $15.00). Min 1, max 1,000,000.
currency string required ISO 4217 currency code, e.g. INR, USD.
return_url string (URL) required Where the customer is sent after 3DS. Must be an absolute HTTPS URL.
customer_name string required Full name of the customer, max 150 chars.
customer_email string required Customer email address. Passed to the gateway for fraud scoring.
customer_phone string optional Customer phone number. Digits only recommended.
description string optional Human-readable order description, max 255 chars.
webhook_url string (URL) optional Override the merchant's default webhook URL for this transaction.
cancel_url string (URL) optional Where to send the customer if they cancel at the 3DS page.

card object

FieldTypeRequiredDescription
card.number string required Card number, 13–19 digits. Spaces are stripped automatically.
card.expiry_month string required 2-digit month, e.g. "09".
card.expiry_year string required 4-digit year, e.g. "2028". Must be 4 digits — 2-digit years are rejected.
card.cvv string required 3 or 4 digit security code. Never logged.
card.holder_name string required Cardholder name exactly as it appears on the card.
card.country string optional* 2-letter ISO 3166-1 country code, e.g. "IN", "US". Required for Paynectra.
card.postcode string optional* Billing postcode / ZIP code. Required for Paynectra.
card.city string optional* Billing city. Required for Paynectra.
card.address string optional* Street address. Required for Paynectra.
card.state string optional State or province code, e.g. "MH".
card.phone string optional Billing contact phone. Digits only, up to 20 chars.

* Fields marked optional* are required when the merchant's active gateway is Paynectra.

Example request

curl
curl -X POST https://api.tribe-pay.com/api/s2s/charge \
  -H "X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id":       "ORDER-20240917-001",
    "amount":         1500,
    "currency":       "INR",
    "return_url":     "https://yoursite.com/payment/return",
    "customer_name":  "Rahul Sharma",
    "customer_email": "rahul@example.com",
    "customer_phone": "9876543210",
    "card": {
      "number":       "4111111111111111",
      "expiry_month": "09",
      "expiry_year":  "2028",
      "cvv":          "123",
      "holder_name":  "RAHUL SHARMA",
      "country":      "IN",
      "postcode":     "400001",
      "city":         "Mumbai",
      "address":      "12 MG Road",
      "state":        "MH",
      "phone":        "9876543210"
    }
  }'

S2S Response Types

The status field in every response tells you what action to take next.

StatusHTTPMeaning & next step
completed 200 Payment captured. A paid_at timestamp is included. Show a success screen immediately.
pending_3ds 200 Card requires 3DS authentication. Redirect the customer to redirect_url. After auth the customer returns to your return_url. Poll GET /api/pay/status/{order_id} or wait for the webhook.
processing 200 Gateway accepted the charge but has not yet confirmed. Poll /api/pay/status or wait for the webhook.
failed 422 Card declined by the gateway. Show an appropriate error to the customer and allow retry.
invalid 422 Input validation failed (missing/invalid field). The message field explains what is wrong. No payment record was created.

Successful completion

JSON — completed
{
  "success":   true,
  "status":    "completed",
  "order_id":  "ORDER-20240917-001",
  "reference": "TRB-20240917-A1B2C3",
  "amount":    1500,
  "currency":  "INR",
  "mode":      "live",
  "paid_at":   "2024-09-17T10:32:44+05:30"
}

3DS redirect required

JSON — pending_3ds
{
  "success":      true,
  "status":       "pending_3ds",
  "order_id":     "ORDER-20240917-001",
  "reference":    "TRB-20240917-A1B2C3",
  "amount":       1500,
  "currency":     "INR",
  "mode":         "live",
  "redirect_url": "https://gateway.paynectra.com/3ds/xxxxxxxx",
  "message":      "Card requires 3DS authentication. Redirect customer to redirect_url to complete payment."
}

Declined / invalid

JSON — failed
{
  "success":   false,
  "status":    "failed",
  "order_id":  "ORDER-20240917-001",
  "reference": "TRB-20240917-A1B2C3",
  "amount":    1500,
  "currency":  "INR",
  "mode":      "live",
  "message":   "Payment declined by the gateway. Please check card details and try again."
}

IP Whitelist Setup

The S2S endpoint accepts requests only from server IPs you have explicitly whitelisted. Any request from an unlisted IP receives 403 Forbidden, even with valid credentials.

Whitelisting is per-merchant. You can list individual IPv4/IPv6 addresses or CIDR ranges (e.g. 203.0.113.0/24). Changes take effect immediately.

How to add IPs

1
Log in to TribeAdmin

Go to Merchants → [your merchant] → S2S API Access.

2
Click Configure

Enter one IP address or CIDR block per line in the text area that appears.

3
Save

The list is updated immediately. Test with tribe-s2s-test.php or a curl command from your server to verify access.

Never whitelist 0.0.0.0/0. S2S carries raw card data; allowing any IP defeats the access control entirely. If you need broader access, use the hosted checkout API instead.

S2S error responses

403
Caller IP is not in the merchant's S2S whitelist.
401
Missing or invalid X-API-Key / X-Secret-Key headers.
422
Validation error — message explains which field. Status is invalid and no payment record is created.
422
Gateway declined — status is failed. A payment record exists in failed state.