Table of contents

Test scenarios

Comprehensive test scenarios and sandbox testing instructions for the Precium Payment API. Contact your account manager to gain access to more advanced testing scenarios if required. Especially for s2s integrations.

Sandbox Environment

Sandbox Configuration

|Setting|Value| |---|---| |Base URL|`https://gate.reviopay.com/api/v1/`| |API Key|Your sandbox API key from dashboard| |Brand ID|Your sandbox brand ID|

Note: Sandbox and production use the same base URL but different credentials. Always verify you're using sandbox credentials when testing.

Test Card Numbers

Successful Payments

|Card Number|Brand|3DS|Behavior| |---|---|---|---| |`4444 3333 2222 1111`|Visa|Yes|Success| |`5555 5555 5555 4444`|Mastercard|Yes|Success| |`4000 0000 0000 0077`|Visa|No|Success (no 3DS)|

Test Card Details

|Field|Value| |---|---| |Expiry Date|Any future date (e.g., `12/28`)| |CVC|`123`| |Cardholder Name|Any Latin characters|

Failed Payments

Use these card numbers to simulate failures:

|Card Number|Error Type| |---|---| |Invalid card number|Card declined| |Invalid CVC|Validation error| |Past expiry date|Expired card|

Test Scenarios

Category 1: Basic Payment Flow

TC-1.1: Create Payment Link

Objective: Verify payment link creation with minimal parameters

Steps:

  1. POST to /purchases/ with client email, product, and brand_id
  2. Verify response contains checkout_url
  3. Open checkout_url in browser
  4. Verify the checkout page loads correctly

Request:

JSON

{
  "client": {"email": "test@example.com"},
  "purchase": {
    "currency": "ZAR",
    "products": [{"name": "Test Product", "price": 10000}]
  },
  "brand_id": "YOUR_BRAND_ID"
}

Expected: HTTP 201, response contains checkout_url and id

TC-1.2: Complete Card Payment

Objective: End-to-end card payment flow

Steps:

  1. Create a purchase with redirect URLs
  2. Navigate to checkout_url
  3. Enter test card details
  4. Complete 3DS if prompted
  5. Verify the redirect to success_redirect
  6. GET purchase to confirm the status is paid

Request:

JSON

{
  "client": {"email": "test@example.com"},
  "purchase": {
    "currency": "ZAR",
    "products": [{"name": "Test Product", "price": 10000}]
  },
  "brand_id": "YOUR_BRAND_ID",
  "success_redirect": "https://example.com/success",
  "failure_redirect": "https://example.com/failure"
}

Expected:

  • Payment completes
  • Redirected to the success URL
  • Purchase status is paid

TC-1.3: Payment with Multiple Products

Objective: Verify the correct total calculation

Steps:

  1. Create a purchase with multiple products
  2. Verify purchase.total equals the sum of all product prices
  3. Complete payment
  4. Verify the amount charged matches the total

Request:

JSON

{
  "client": {"email": "test@example.com"},
  "purchase": {
    "currency": "ZAR",
    "products": [
      {"name": "Product A", "price": 5000, "quantity": "2"},
      {"name": "Product B", "price": 3000},
      {"name": "Shipping", "price": 2000}
    ]
  },
  "brand_id": "YOUR_BRAND_ID"
}

Expected: Total should be 15000 (5000Ã2 + 3000 + 2000)

Category 2: Payment Method Restrictions

TC-2.1: Whitelist Card Only

Objective: Verify that only whitelisted methods appear

Steps:

  1. Create a purchase with payment_method_whitelist: ["visa", "mastercard"]
  2. Open checkout page
  3. Verify that only Visa and Mastercard options appear
  4. Verify EFT options are not available

Request:

JSON

{
  "client": {"email": "test@example.com"},
  "purchase": {
    "currency": "ZAR",
    "products": [{"name": "Test", "price": 10000}]
  },
  "brand_id": "YOUR_BRAND_ID",
  "payment_method_whitelist": ["visa", "mastercard"]
}

Expected: Only card payment options visible on checkout

TC-2.2: Whitelist EFT Only

Objective: Verify non-card methods work

Steps:

  1. Create a purchase with payment_method_whitelist: ["ozow"]
  2. Open checkout page
  3. Verify that only Ozow option appears
  4. Verify card options are not available

Expected: Only Ozow payment option visible

Category 3: Pre-Authorization (Hold Funds)

TC-3.1: Create Pre-Authorization

Objective: Reserve funds without capture

Steps:

  1. Create a purchase with skip_capture: true
  2. Complete payment
  3. Verify the status is hold (not paid)
  4. Verify funds are reserved on the test card

Request:

JSON

{
  "client_id": "CLIENT_UUID",
  "purchase": {
    "currency": "ZAR",
    "products": [{"name": "Hotel Deposit", "price": 500000}]
  },
  "brand_id": "YOUR_BRAND_ID",
  "skip_capture": true,
  "success_redirect": "https://example.com/success",
  "failure_redirect": "https://example.com/failure"
}

Expected: Status hold after payment completion

TC-3.2: Capture Pre-Authorization (Full)

Objective: Capture the full held amount

Steps:

  1. Create pre-auth purchase (TC-3.1)
  2. Complete payment
  3. POST to /purchases/{id}/capture/ with full amount
  4. Verify status changes to paid

Request:

BASH

POST /purchases/{id}/capture/
{"amount": 500000}

Expected: Status changes to paid

TC-3.3: Capture Pre-Authorization (Partial)

Objective: Capture less than held amount

Steps:

  1. Create pre-auth for 500000 cents
  2. Complete payment
  3. Capture only 300000 cents
  4. Verify capture succeeds
  5. Verify the remaining 200000 is released

Request:

BASH

POST /purchases/{id}/capture/
{"amount": 300000}

Expected: Capture succeeds with a partial amount

TC-3.4: Release Pre-Authorization

Objective: Release held funds without capture

Steps:

  1. Create a pre-auth purchase
  2. Complete payment (status = hold)
  3. POST to /purchases/{id}/release/
  4. Verify status changes to released
  5. Verify funds are released on the test card

Expected: Status released, funds returned

Category 4: Refunds

TC-4.1: Full Refund

Objective: Refund the entire payment

Steps:

  1. Create and complete a payment
  2. Verify the status is paid
  3. POST to /purchases/{id}/refund/ with an empty body
  4. Verify the refund is processed
  5. Check the purchase for refund status

Request:

bash

BASH

POST /purchases/{id}/refund/
{}

Expected: Refund processed, status updated

TC-4.2: Partial Refund

Objective: Refund portion of payment

Steps:

  1. Complete payment for 10000 cents
  2. POST refund for 3000 cents
  3. Verify partial refund succeeds
  4. Verify the remaining balance is 7000

Request:

BASH

POST /purchases/{id}/refund/
{"amount": 3000}

Expected: Partial refund of 3000 cents processed

TC-4.3: Multiple Partial Refunds

Objective: Issue multiple refunds on the same purchase

Steps:

  1. Complete payment for 10000 cents
  2. Refund 3000 cents (success)
  3. Refund another 4000 cents (success)
  4. Verify the total refunded is 7000
  5. Verify the remaining is 3000

Expected: Multiple refunds succeed up to the original amount

TC-4.4: Refund Exceeds Amount

Objective: Verify refund limit enforcement

Steps:

  1. Complete payment for 10000 cents
  2. Attempt to refund 15000 cents
  3. Verify request fails with appropriate error

Expected: HTTP 400, error refund_exceeds_amount

Category 5: Recurring Payments

TC-5.1: Tokenize Card

Objective: Save card for future payments

Steps:

  1. Create a purchase with force_recurring: true
  2. Complete payment
  3. GET /clients/{id}/recurring_tokens/
  4. Verify the token is created

Request:

JSON

{
  "client_id": "CLIENT_UUID",
  "purchase": {
    "currency": "ZAR",
    "products": [{"name": "Subscription", "price": 29900}]
  },
  "brand_id": "YOUR_BRAND_ID",
  "force_recurring": true,
  "success_redirect": "https://example.com/success",
  "failure_redirect": "https://example.com/failure"
}

Expected: Recurring token created after payment

TC-5.2: Zero-Amount Tokenization

Objective: Save the card without charging

Steps:

  1. Create a purchase with price: 0 and skip_capture: true
  2. Complete checkout (no charge)
  3. Verify that the token is created
  4. Use the token for subsequent charges

Request:

JSON

{
  "client_id": "CLIENT_UUID",
  "purchase": {
    "currency": "ZAR",
    "products": [{"name": "Card Authorization", "price": 0}]
  },
  "brand_id": "YOUR_BRAND_ID",
  "skip_capture": true,
  "force_recurring": true,
  "success_redirect": "https://example.com/success",
  "failure_redirect": "https://example.com/failure"
}

Expected: Token created, no charge to card

TC-5.3: Charge with Token

Objective: Process payment using saved token

Steps:

  1. Complete tokenization (TC-5.1)
  2. Create a new purchase for the same client
  3. POST to /purchases/{id}/charge/ with recurring_token
  4. Verify payment succeeds without customer interaction

Request:

BASH

POST /purchases/{new_id}/charge/
{"recurring_token": "ORIGINAL_PURCHASE_ID"}

Expected: Payment succeeds, status paid

TC-5.4: Charge with Invalid Token

Objective: Verify invalid token handling

Steps:

  1. Create purchase
  2. Attempt charge with non-existent token ID
  3. Verify the appropriate error returned

Expected: HTTP 404, error recurring_token_not_found

Category 6: Billing Templates (Subscriptions)

TC-6.1: Create Subscription Plan

Objective: Create a monthly subscription template

Steps:

  1. POST to /billing_templates/
  2. Verify template created
  3. Check subscription settings are correct

Request:

JSON

{
  "title": "Monthly Premium",
  "purchase": {
    "currency": "ZAR",
    "products": [{"name": "Premium Plan", "price": 29900}]
  },
  "brand_id": "YOUR_BRAND_ID",
  "is_subscription": true,
  "subscription_active": true,
  "subscription_period": 1,
  "subscription_period_units": "months",
  "force_recurring": true
}

Expected: Template created with subscription configuration

TC-6.2: Add Subscriber

Objective: Subscribe the client to a plan

Steps:

  1. Attempt to create another with the same email

TC-6.3: Add Subscriber with Override

Objective: Subscribe with custom pricing

Steps:

  1. Create a template with a standard price
  2. Add subscriber with override price
  3. Verify the subscriber has a custom price
  4. Complete payment
  5. Verify the charged amount matches the override

Request:

JSON

{
  "client_id": "CLIENT_UUID",
  "override": {
    "products": [{"name": "Discounted Plan", "price": 19900}]
  }
}

Expected: Subscription uses override pricing

Category 7: Client Management

TC-7.1: Create Client

Objective: Create a new client record

Steps:

  1. POST to /clients/ with email and details
  2. Verify client created
  3. Verify all fields are saved correctly

Request:

JSON

{
  "email": "test@example.com",
  "full_name": "Test User",
  "phone": "+27821234567"
}

Expected: HTTP 201, client ID returned

TC-7.2: Search Client

Objective: Find a client by email

Steps:

  1. Create client
  2. GET /clients/?email=test@example.com
  3. Verify the client found in the results

Expected: Client returned in search results

TC-7.3: Duplicate Client Prevention

Objective: Verify duplicate email handling

Steps:

  1. Create a client with an email
  2. Attempt to create another with the same email
  3. Verify the appropriate error

Expected: HTTP 409, error duplicate_client

Category 8: Webhooks

TC-8.1: Payment Success Webhook

Objective: Verify webhook delivery on payment

Steps:

  1. Configure the webhook for purchase.paid
  2. Create and complete a payment
  3. Verify the webhook was received
  4. Verify payload contains purchase data

Expected: Webhook delivered with correct event type

TC-8.2: Payment Failure Webhook

Objective: Verify the webhook on failed payment

Steps:

  1. Configure the webhook for purchase.payment_failure
  2. Create purchase
  3. Attempt payment with an invalid card
  4. Verify failure webhook received

Expected: Webhook delivered with failure details

TC-8.3: Webhook Signature Verification

Objective: Verify webhook authenticity

Steps:

  1. Receive webhook
  2. Extract signature header
  3. Calculate the expected signature using the secret
  4. Verify signatures match

Expected: Calculated signature matches header

Category 9: Error Handling

TC-9.1: Invalid API Key

Objective: Verify authentication error

Steps:

  1. Make a request with an invalid API key
  2. Verify HTTP 401 returned
  3. Verify the error message is clear

Expected: HTTP 401, invalid_token error

TC-9.2: Missing Required Field

Objective: Verify validation error

Steps:

  1. POST purchase without brand_id
  2. Verify HTTP 400 returned
  3. Verify field-specific error message

Expected: HTTP 400, required error for brand_id

TC-9.3: Invalid UUID

Objective: Verify UUID validation

Steps:

  1. GET /purchases/invalid-uuid/
  2. Verify the appropriate error

Expected: HTTP 400 or 404 with clear error

TC-9.4: Rate Limiting

Objective: Verify rate limit handling

Steps:

  1. Make requests rapidly (>100/minute)
  2. Observe rate limit response
  3. Verify the retry-after information provided

Expected: HTTP 429 after limit exceeded

Test Checklist

Pre-Integration Checklist

  • Sandbox API key obtained
  • Brand ID configured
  • Webhook endpoint ready
  • Test card numbers available

Basic Flow Tests

  • TC-1.1: Create payment link
  • TC-1.2: Complete card payment
  • TC-1.3: Multiple products
  • TC-2.1: Payment method whitelist

Advanced Flow Tests

  • TC-3.1: Pre-authorization
  • TC-3.2: Full capture
  • TC-3.3: Partial capture
  • TC-3.4: Release hold
  • TC-4.1: Full refund
  • TC-4.2: Partial refund
  • TC-5.1: Card tokenization
  • TC-5.3: Token charge
  • TC-6.1: Create subscription
  • TC-6.2: Add subscriber

Error Handling Tests

  • TC-9.1: Invalid API key
  • TC-9.2: Validation errors
  • TC-9.3: Invalid UUID
  • TC-9.4: Rate limiting

Production Readiness

  • Webhook handling implemented
  • Error handling complete
  • Idempotency implemented
  • Logging configured
  • Production credentials ready

Go-Live Checklist

Before going live:

  1. Credentials
  • Production API key configured
  • Production brand ID configured
  • Sandbox credentials removed from production
  1. Webhooks
  • Production webhook URL configured
  • Webhook signature verification implemented
  • All relevant events subscribed
  1. Error Handling
  • All error codes handled gracefully
  • User-friendly error messages displayed
  • Errors logged for debugging
  1. Security
  • API keys stored securely (not in code)
  • HTTPS enforced
  • Webhook signatures verified
  1. Testing
  • End-to-end test in production sandbox
  • Small live transaction tested
  • Refund tested