Your First Transaction
Step-by-step guide to creating and processing your first payment with EPaySe.
Get Credentials
API key, approved website, USD, IP whitelist
Sign the Request
HMAC-SHA256, five headers
Create Transaction
Create and process payment
Handle Webhook
Receive payment notifications
Get Your Credentials
Everything below runs against the REST API. Before your first request you need four things from your dashboard.
- An API key: Settings → API Keys → "Generate New Key". Copy the Secret Key immediately (it is shown once) and note the API Key ID.
- An approved website: the websiteUrl you send must belong to a website that is approved on your merchant account, otherwise the API answers 422 "Domain ... is not in your list of allowed websites".
- USD: USD is the only currency accepted today.
- Your server IP on the whitelist: on staging and production the gateway answers 403 IP_NOT_WHITELISTED to every call from an IP that is not listed under Settings → IP Whitelist (an empty list refuses everything). The sandbox does not enforce it.
Use Sandbox Keys for Testing
Sign the Request
Every request carries five headers and an HMAC-SHA256 signature made with your Secret Key. The Authentication guide explains each header; the summary below is all you need for this tutorial.
string_to_sign = METHOD|PATH|TIMESTAMP|NONCE|BODY
e.g. POST|api/v1/transaction/create|1699564800|5f2c9e1a7b3d4c68a1e0b9...
X-Signature = lowercase hex of HMAC-SHA256(secret_key, string_to_sign)
Headers: X-Api-Key-Id, X-Signature, X-Timestamp, X-Nonce, X-Signature-Version (X-Signature-Version: 3)Create a Transaction
Send the request, then redirect your customer to the checkoutUrl in the response. The amount is in dollars (major units, e.g. 100.50 = $100.50) with at most two decimals.
<?php
$gateway = 'https://staging-gateway.epayse.com';
$apiKeyId = getenv('EPAYSE_API_KEY_ID');
$secretKey = getenv('EPAYSE_SECRET_KEY'); // sk_test_... for sandbox
$path = 'api/v1/transaction/create';
$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 = time();
$nonce = bin2hex(random_bytes(16));
$signature = hash_hmac('sha256', implode('|', ['POST', $path, $timestamp, $nonce, $body]), $secretKey);
$ch = curl_init($gateway . '/' . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Key-Id: ' . $apiKeyId,
'X-Signature: ' . $signature,
'X-Timestamp: ' . $timestamp,
'X-Nonce: ' . $nonce,
'X-Signature-Version: 3',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($response['status'] ?? null) !== 'SUCCESS') {
error_log('EPaySe error: ' . json_encode($response));
exit(1);
}
// Redirect the customer to the checkout page
header('Location: ' . $gateway . $response['data']['checkoutUrl']);Required Parameters
Eight fields are required; customerDetails carries seven of its own. See the Transaction API reference for every optional field.
ref, amount, currency, websiteUrl, redirectUrl, cancelUrl, description + customerDetails (firstName, lastName, email, country, ip, phoneCode, phoneNumber)
amountAmount in dollars (major units, 100.50 = $100.50) with up to two decimal places.
currencyUSD is the only supported currency.
redirectUrlURL where customers are redirected after a successful payment. cancelUrl is where they go if the payment fails or is cancelled. Both redirects are signed with your secret key: verify the signature before trusting them (see Redirect URL in the Transaction API reference).
metadataOptional custom key-value data (order ID, customer ID, etc.). Returned in webhooks for reconciliation.
Handle Webhook Notifications
Set up a webhook endpoint to receive real-time payment status updates. Webhooks are the recommended way to handle payment completion. The Webhooks guide has the payload formats and the exact signature check.
Always Verify Webhook Signatures
Test Cards
Use these test card numbers in the sandbox environment to simulate different payment scenarios.
Sandbox Test Cards
Valid only in sandbox mode - these cards will not work in production
| Card Number | Card Type | Result |
|---|---|---|
4242 4242 4242 4242 | Visa | Success |
5555 5555 5555 4444 | Mastercard | Success |
Use any future expiration date (MM/YY), any 3-digit CVV, and any billing ZIP code. The complete list, including declined, pending and 3D Secure cards, is on the Test Cards page.