EPaySe
Testing

Testing Guide

Comprehensive guide to testing your EPaySe integration before going live.

Thorough testing is critical for a successful payment integration. Use our sandbox environment to test all scenarios before processing real payments.

Sandbox Environment

Accessing Sandbox

The sandbox environment provides full API functionality with test data

API Base URL

https://sandbox-gateway.epayse.com/api/v1

API Keys

Get sandbox API keys from the dashboard under Settings → API Keys

Test Scenarios

Test these critical scenarios to ensure your integration handles all payment flows correctly.

Successful Payment

Test successful payment flow with various card types

Failed Payment

Test declined cards and insufficient funds scenarios

3D Secure Flow

Test 3D Secure authentication process

Webhook Delivery

Test webhook notification reception and handling

Webhook Testing

Webhooks require a publicly accessible HTTPS URL. For local development, use ngrok to create a secure tunnel.

PHP
Webhook Testing Example
<?php
// Use ngrok to expose your local server for webhook testing:
// 1. Start ngrok: ngrok http 8000
// 2. Copy the HTTPS URL (e.g., https://abc123.ngrok.io)
// 3. In your EPaySe merchant dashboard → Settings → Webhooks → add https://abc123.ngrok.io/webhooks/payment

// EPaySe sends webhooks to your configured dashboard endpoints, not per-request URLs.

// Your webhook endpoint
// POST /webhooks/payment
$rawBody   = file_get_contents('php://input');   // the EXACT bytes EPaySe sent — never re-encode
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$secret    = getenv('EPAYSE_WEBHOOK_SECRET');    // the whsec_... secret of this webhook endpoint

// Log for debugging
error_log('Webhook received: ' . $rawBody);
error_log('Signature: ' . $signature);

// Signed string = timestamp immediately followed by the raw body (no separator)
$expected = hash_hmac('sha256', $timestamp . $rawBody, $secret);   // lowercase hex

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

$event = json_decode($rawBody, true);
error_log('Event type: ' . $event['type']);           // e.g. payment.paid
error_log('Event data: ' . json_encode($event['data']));

// Handle event...
http_response_code(200);   // acknowledge quickly, then process asynchronously

Webhook Testing Tips

  • Always verify webhook signatures before processing
  • Return HTTP 200 status code within 30 seconds (the delivery timeout), then process the event asynchronously
  • Handle webhook retries (EPaySe retries a failed delivery up to 5 times with the default schedule; each endpoint can override it)
  • Log all webhook payloads for debugging

Debugging

Log the HTTP status and the JSON body of every API response to get detailed information about your requests.

PHP
Debug Mode Example
<?php
// Enable detailed error logging
ini_set('display_errors', 1);
ini_set('log_errors', 1);
error_reporting(E_ALL);

// $url, $headers and $body are built exactly as on the Authentication page
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_TIMEOUT => 30,
]);

$response = curl_exec($ch);
$status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($response === false) {
    error_log('Transport error: ' . curl_error($ch));   // DNS, TLS, timeout...
} else {
    // Log the status and the JSON error the API returned (never log secret keys)
    error_log('HTTP status: ' . $status);
    error_log('Response body: ' . $response);
}
curl_close($ch);

Common Errors

401

Unauthorized

Invalid API key or signature

Solution: Verify your API credentials and HMAC signature generation

403

IP Not Whitelisted

Response code IP_NOT_WHITELISTED — the calling IP is not on your merchant IP whitelist

Solution: Add the public IP of your server under Settings → IP Whitelist (enforced on staging and production, not in the sandbox)

400

Bad Request

Invalid or missing parameters

Solution: Check the API documentation for required parameters

422

Validation Error

Parameters failed validation

Solution: Review validation error messages in the response

429

Rate Limit

Too many requests

Solution: Implement exponential backoff and respect rate limits

API Testing Tools

Testing with Postman

Use Postman to test API endpoints without writing code. Import our collection to get started.

JSON
Postman Collection Example
{
  "info": {
    "name": "EPaySe API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Create Transaction",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "X-Api-Key-Id",
            "value": "{{api_key_id}}"
          },
          {
            "key": "X-Signature",
            "value": "{{signature}}"
          },
          {
            "key": "X-Timestamp",
            "value": "{{timestamp}}"
          },
          {
            "key": "X-Nonce",
            "value": "{{nonce}}"
          },
          {
            "key": "X-Signature-Version",
            "value": "3"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"ref\": \"ORDER-1001\",\n  \"amount\": 100.5,\n  \"currency\": \"USD\",\n  \"websiteUrl\": \"https://example.com\",\n  \"redirectUrl\": \"https://example.com/payment/success\",\n  \"cancelUrl\": \"https://example.com/payment/cancel\",\n  \"description\": \"Premium subscription - monthly\",\n  \"customerDetails\": {\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"email\": \"[email protected]\",\n    \"country\": \"US\",\n    \"ip\": \"203.0.113.10\",\n    \"phoneCode\": \"US\",\n    \"phoneNumber\": \"5551234567\"\n  }\n}"
        },
        "url": {
          "raw": "{{base_url}}/api/v1/transaction/create",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "api",
            "v1",
            "transaction",
            "create"
          ]
        }
      }
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "https://sandbox-gateway.epayse.com"
    }
  ]
}

Testing with cURL

Use cURL commands to test API endpoints from the command line.

Bash
cURL Example
# Create a transaction against the sandbox with cURL (signature version 3)
SECRET_KEY="your_secret_key"        # sk_test_... — used only to sign, never sent
API_KEY_ID="your_api_key_id"        # shown next to the key in Settings → API Keys
BASE_URL="https://sandbox-gateway.epayse.com"
API_PATH="api/v1/transaction/create"          # no leading slash
BODY='{"ref":"ORDER-1001","amount":100.5,"currency":"USD","websiteUrl":"https://example.com","redirectUrl":"https://example.com/payment/success","cancelUrl":"https://example.com/payment/cancel","description":"Premium subscription - monthly","customerDetails":{"firstName":"John","lastName":"Doe","email":"[email protected]","country":"US","ip":"203.0.113.10","phoneCode":"US","phoneNumber":"5551234567"}}'

TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)       # new value for every request
# METHOD|PATH|TIMESTAMP|NONCE|BODY  →  HMAC-SHA256, lowercase hex, no prefix
SIGNATURE=$(printf '%s' "POST|$API_PATH|$TIMESTAMP|$NONCE|$BODY" \
  | openssl dgst -sha256 -hmac "$SECRET_KEY" | awk '{print $NF}')

curl -X POST "$BASE_URL/$API_PATH" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key-Id: $API_KEY_ID" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Nonce: $NONCE" \
  -H "X-Signature-Version: 3" \
  -d "$BODY"

Testing Best Practices

Test All Scenarios

Test successful payments, failures, refunds, and edge cases

Verify Webhooks

Always verify webhook signatures before processing

Handle Errors

Implement proper error handling and logging

Use Idempotency

Include idempotency keys to prevent duplicate transactions

Ready for Production?

Once you've thoroughly tested your integration, review our go-live checklist to prepare for production.