EPaySe
Guide

Accept Payments

Learn how to integrate EPaySe payment processing into your application using the Redirect, Iframe, or Server-to-Server (S2S) integration methods.

Integration Methods

Redirect

Redirect customers to EPaySe's hosted checkout page. Simplest integration with no PCI scope.

Iframe

Embed the checkout form within your page using an iframe. Customers never leave your site.

Server-to-Server

Full control over the checkout UX. Requires PCI DSS SAQ D compliance for handling card data.

Payment Flow

1

Create Transaction

Your backend calls POST /api/v1/transaction/create with order details

2

Customer Checkout

Redirect to checkoutUrl or embed the iframe

3

Payment Processing

EPaySe processes payment through the selected PSP with fraud checks

4

Result Notification

Customer redirected to your redirectUrl + webhook sent asynchronously

1. Redirect Integration

The simplest way to accept payments. Create a transaction via API, then redirect your customer to the EPaySe hosted checkout page.

API Request

Bash
Create Transaction (cURL)
curl -X POST https://api.epayse.com/api/v1/transaction/create \
  -H "Content-Type: application/json" \
  -H "X-Api-Key-Id: your_api_key" \
  -H "X-Signature: generated_hmac_signature" \
  -H "X-Timestamp: 1700000000" \
  -H "X-Nonce: unique_nonce_value" \
  -d '{
    "ref": "ORDER-2024-001",
    "amount": 1000,
    "currency": "USD",
    "websiteUrl": "https://yoursite.com",
    "redirectUrl": "https://yoursite.com/payment/success",
    "cancelUrl": "https://yoursite.com/payment/cancel",
    "description": "Payment for Order #001",
    "customerDetails": {
      "firstName": "John",
      "lastName": "Doe",
      "email": "[email protected]",
      "country": "US",
      "ip": "203.0.113.50",
      "phoneCode": "US",
      "phoneNumber": "5551234567"
    }
  }'

Response

JSON
Success Response (200)
{
  "status": "SUCCESS",
  "message": "Transaction created successfully",
  "data": {
    "transactionId": "01kd096yg112e40pcyfwsahyev",
    "checkoutUrl": "/checkout/01kd096yg112e40pcyfwsahyev?expires=1766325765&signature=c0108b47..."
  }
}

PHP Integration Example

PHP
Create Payment (PHP)
<?php

$apiKey = 'your_api_key';
$secretKey = 'your_secret_key';

$timestamp = time();
$nonce = bin2hex(random_bytes(16));

$payload = json_encode([
    'ref' => 'ORDER-' . uniqid(),
    'amount' => 1000,            // Amount in cents ($10.00)
    'currency' => 'USD',
    'websiteUrl' => 'https://yoursite.com',
    'redirectUrl' => 'https://yoursite.com/payment/success',
    'cancelUrl' => 'https://yoursite.com/payment/cancel',
    'description' => 'Payment for Order #1234',
    'customerDetails' => [
        'firstName' => 'John',
        'lastName' => 'Doe',
        'email' => '[email protected]',
        'country' => 'US',
        'ip' => $_SERVER['REMOTE_ADDR'],  // Always use real customer IP
        'phoneCode' => 'US',
        'phoneNumber' => '5551234567',
    ],
]);

// Generate HMAC-SHA256 signature
$signatureString = $timestamp . $nonce . $payload;
$signature = hash_hmac('sha256', $signatureString, $secretKey);

$ch = curl_init('https://api.epayse.com/api/v1/transaction/create');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Api-Key-Id: ' . $apiKey,
        'X-Signature: ' . $signature,
        'X-Timestamp: ' . $timestamp,
        'X-Nonce: ' . $nonce,
    ],
    CURLOPT_RETURNTRANSFER => true,
]);

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

if ($response['status'] === 'SUCCESS') {
    // Redirect customer to EPaySe checkout
    header('Location: ' . $response['data']['checkoutUrl']);
    exit;
}

// Handle error
echo 'Error: ' . ($response['message'] ?? 'Unknown error');

Amount Format: The amount field is in cents for the standard API. For example, 1000 = $10.00 USD. The S2S API uses dollars (e.g., 100.00 = $100.00).

2. Required Parameters

Every transaction requires the following fields:

ParameterTypeDescription
refstringUnique merchant reference (max 250 chars). Acts as idempotency key.
amountintegerAmount in cents (min: 1, max: 150000 = $1,500.00)
currencystringISO 4217 currency code (e.g., USD)
websiteUrlstringYour website URL (must be registered)
redirectUrlstringURL to redirect customer after payment
cancelUrlstringURL to redirect customer if they cancel
descriptionstringPayment description shown to customer
customerDetailsobjectCustomer information (firstName, lastName, email, country, ip, phoneCode, phoneNumber)

3. Iframe Integration

Embed the EPaySe checkout directly within your page. Customers complete payment without leaving your site.

Iframe Response

Use the create-with-iframe endpoint to get embeddable URLs:

JSON
Iframe Response (200)
{
  "status": "SUCCESS",
  "message": "Transaction created successfully",
  "data": {
    "transactionId": "01kd096yg112e40pcyfwsahyev",
    "checkoutUrl": "/checkout/01kd096yg112e40pcyfwsahyev?expires=...",
    "iframe": {
      "fullCheckoutUrl": "https://gateway.epayse.com/checkout/01kd...?expires=...&signature=...",
      "fullCheckoutEmbedCode": "<iframe src=\"https://gateway.epayse.com/checkout/...\" />",
      "paymentMethods": [
        {
          "key": "credit_card",
          "name": "Credit/Debit Card",
          "url": "https://gateway.epayse.com/checkout-field/...",
          "embedCode": "<iframe src=\"...\" />"
        }
      ],
      "expiresAt": "2024-01-15T15:00:00+00:00",
      "configuration": { "width": "100%", "height": "900px" },
      "postMessageEvents": [
        "epayse:payment:success",
        "epayse:payment:failed",
        "epayse:payment:cancel",
        "epayse:height:change"
      ]
    }
  }
}

Listen for Iframe Events

Handle payment events from the embedded iframe using postMessage:

JavaScript
Iframe PostMessage Events
// Listen for EPaySe iframe events
window.addEventListener('message', function(event) {
  // IMPORTANT: Verify origin for security
  const ALLOWED_ORIGINS = [
    'https://gateway.epayse.com',    // Production
    'https://sandbox.epayse.com'     // Sandbox
  ];

  if (!ALLOWED_ORIGINS.includes(event.origin)) {
    return; // Ignore untrusted origins
  }

  const { type, data } = event.data;

  switch(type) {
    case 'epayse:payment:success':
      console.log('Payment successful:', data.transactionId);
      // Verify payment via webhook or API before fulfilling order
      break;

    case 'epayse:payment:failed':
      console.error('Payment failed:', data.message);
      // Show error message to customer
      break;

    case 'epayse:payment:cancel':
      console.log('Payment cancelled:', data.transactionId);
      // Redirect to cart or retry
      break;

    case 'epayse:height:change':
      // Dynamically resize iframe
      document.getElementById('epayse-checkout')
        .style.height = data.height + 'px';
      break;
  }
});

Security: Always verify the event.origin before processing iframe messages. Only trust messages from gateway.epayse.com (production) or sandbox.epayse.com (testing).

4. Payment Status Lifecycle

A transaction progresses through the following statuses:

StatusDescription
INCOMPLETE
Transaction created, awaiting customer action
PENDING
Payment submitted, processing at PSP
AUTHENTICATING
3D Secure authentication in progress
SUCCESS
Payment completed successfully
FAIL
Payment failed (max retries reached)
CANCEL
Customer cancelled the payment
EXPIRE
Checkout session expired

5. Redirect URL Parameters

After payment, the customer is redirected to your redirectUrl with query parameters:

JavaScript
Redirect URL Parameters
// Redirect URL query parameters after payment
// https://yoursite.com/payment/success?
//   status=SUCCESS
//   &ref=ORDER-2024-001
//   &transactionId=01kd096yg112e40pcyfwsahyev
//   &amount=1000
//   &paidAmount=1000
//   &currency=USD
//   &message=Payment+successful
//   &attemptCount=1
//   &maxAttempts=3

// IMPORTANT: Always verify via webhook or API call
// Never trust redirect parameters alone for order fulfillment

6. Verify Payment via Webhook

Always verify payment results using webhooks rather than relying on redirect parameters. Webhooks are sent asynchronously after the payment is processed.

PHP
Webhook Handler (PHP)
<?php

// Receive and verify webhook notification
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? '';
$nonce = $_SERVER['HTTP_X_NONCE'] ?? '';

// Verify timestamp (reject if older than 5 minutes)
if (abs(time() - (int) $timestamp) > 300) {
    http_response_code(401);
    exit('Timestamp expired');
}

// Verify HMAC signature
$expected = hash_hmac('sha256', $timestamp . $nonce . $payload, $secretKey);
if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

$event = json_decode($payload, true);

switch ($event['event']) {
    case 'transaction.success':
        // Payment confirmed - fulfill the order
        updateOrderStatus($event['data']['ref'], 'paid');
        break;

    case 'transaction.failed':
        // Payment failed
        updateOrderStatus($event['data']['ref'], 'failed');
        break;
}

// Always return 200 to acknowledge receipt
http_response_code(200);
echo json_encode(['received' => true]);

7. Testing

Use sandbox test cards to test your integration:

Card NumberResultUse Case
4111 1111 1111 1111
Success
Successful payment
4000 0000 0000 0002
Decline
Card declined
4000 0000 0000 0119
3DS
3D Secure required

Use any future expiry date and any 3-digit CVV for testing.

8. Common Mistakes

DON'T

Use your server IP instead of the customer's real IP address

DON'T

Trust redirect URL parameters as proof of payment

DON'T

Send amount as decimal in the standard API (use cents: 1000 not 10.00)

DO

Always verify payment via webhooks before fulfilling orders

DO

Use unique ref values for each transaction (idempotency key)

DO

Verify iframe event.origin before processing PostMessage events

Next Steps

Explore related documentation to complete your integration.