Payment Gateway API Documentation
Complete integration guide for our Payment Gateway API. Payments are captured on your payment provider's hosted checkout page — your integration initializes the payment, redirects the customer, and confirms the result server-side.
Key Features
- Hosted provider checkout — card data never touches your servers
- 3D Secure handled on the provider's hosted flow
- Automatic payment method selection per your account configuration
- Flexible address handling
- Transaction status API and refunds
- Multi-currency support
Authentication
All API requests must include your API credentials in the request headers:
X-Api-Key: your_api_key_here
X-Api-Secret: your_api_secret_here
Content-Type: application/json
Payment Processing
Our gateway automatically handles payment method selection and routing based on your account configuration. You don't need to specify payment providers - the system will use the optimal method for each transaction.
| Feature | Support | Description |
|---|---|---|
| Cards | ✅ Via your acquirer | Card schemes supported by the acquirer account you connect |
| 3D Secure | ✅ Provider-hosted | 3DS runs on the provider's hosted checkout where the issuer requires it |
| Local rails | ✅ Via providers | M-Pesa and other local methods through providers such as Paystack |
| Multi-Currency | ✅ Provider-dependent | Any 3-letter ISO currency your connected provider supports |
Address Handling
Proper billing address information is crucial for payment processing and 3DS authentication. The API supports flexible address formats:
Single String Format (Recommended)
{
"billing_address": "123 Main Street, New York, NY, 10001, US"
}
Individual Components Format
{
"address_line": "123 Main Street",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "US"
}
Address Requirements
| Component | Required | Description |
|---|---|---|
| Street Address | Required | Full street address including number and street name |
| City | Required | City or locality name |
| State/Province | Optional | State, province, or administrative area |
| Postal Code | Optional | ZIP/postal code (recommended for better approval rates) |
| Country | Required | 2-letter ISO country code (US, GB, CA, etc.) |
Initialize Payment
Create a new payment transaction. The system selects the payment provider from your account configuration and returns a hosted checkout URL — redirect your customer there to complete payment. No card details are sent to this endpoint.
Endpoint:
POST https://euppay.com/api/v1/payments/initialize
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| order_id | string | Required | Your unique order identifier |
| amount | decimal | Required | Payment amount (e.g., 100.50) |
| currency | string | Required | 3-letter currency code (USD, EUR, GBP) |
| customer_name | string | Optional | Cardholder name |
| customer_email | string | Optional | Customer email address |
| billing_address | string | Required | Complete billing address (see Address Handling section) |
| return_url | string | Required | URL for successful payment redirect |
| cancel_url | string | Required | URL for cancelled/failed payment redirect |
Example Request:
curl -X POST "https://euppay.com/api/v1/payments/initialize" \
-H "Content-Type: application/json" \
-H "X-Api-Key: your_api_key" \
-H "X-Api-Secret: your_api_secret" \
-d '{
"order_id": "ORDER123456",
"amount": 100.50,
"currency": "USD",
"customer_name": "John Doe",
"customer_email": "john.doe@example.com",
"billing_address": "123 Main Street, New York, NY, 10001, US",
"return_url": "https://your-website.com/payment/success",
"cancel_url": "https://your-website.com/payment/cancel"
}'
Response Types:
1. Redirect Response:
{
"success": true,
"action": "redirect",
"message": "Transaction initialized successfully",
"redirect_url": "https://checkout.provider.example/pay/abc123def456",
"transaction_reference": "550e8400-e29b-41d4-a716-446655440000"
}
redirect_url — the provider's hosted checkout page. The
customer enters payment details there (never on your site), completes any 3DS challenge, and is
returned to your return_url or cancel_url. Always confirm the result
with the status endpoint before fulfilling the order.
2. Error Response:
{
"success": false,
"message": "Validation failed",
"errors": {
"billing_address": ["Street address is required"],
"currency": ["The currency must be a valid 3-letter code"]
},
"error_code": "VALIDATION_ERROR"
}
3D Secure
3D Secure authentication happens on your payment provider's hosted checkout page — not in your
integration. When the issuer requires a challenge, the provider renders it as part of the hosted
flow after you redirect the customer to redirect_url.
return_url confirm the outcome server-side with the
status endpoint. A successful response includes
"3ds_authenticated": true when the issuer authenticated the cardholder.
return_url is not proof of payment — always verify the transaction status from your
server before fulfilling an order.
Check Transaction Status
Retrieve the current status and details of a transaction.
Endpoint:
GET https://euppay.com/api/v1/payments/{reference}/status
Example Request:
curl -X GET "https://euppay.com/api/v1/payments/550e8400-e29b-41d4-a716-446655440000/status" \
-H "X-Api-Key: your_api_key" \
-H "X-Api-Secret: your_api_secret"
Response:
{
"success": true,
"message": "Transaction status retrieved",
"data": {
"reference": "550e8400-e29b-41d4-a716-446655440000",
"order_id": "ORDER123456",
"status": "completed",
"amount": 100.50,
"currency": "USD",
"payment_method": "card",
"card_type": "visa",
"card_last_four": "1111",
"customer_email": "john.doe@euppay.com",
"created_at": "2023-12-01T10:30:00Z",
"completed_at": "2023-12-01T10:31:45Z",
"3ds_authenticated": true
}
}
Transaction Statuses
| Status | Description | Next Steps |
|---|---|---|
initialized |
Transaction created, pending processing | Wait for completion or check again |
processing |
Payment is being processed | Wait for completion |
completed |
Payment successfully completed | Fulfill order/service |
failed |
Payment failed or was declined | Retry with different card or method |
cancelled |
Payment was cancelled by user | Offer alternative payment method |
refunded |
Payment has been refunded | Update order status accordingly |
Refund Transaction
Process a full or partial refund for a completed transaction.
Endpoint:
POST https://euppay.com/api/v1/payments/{reference}/refund
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | decimal | Optional | Refund amount (defaults to full amount) |
| reason | string | Optional | Reason for refund |
Example Request:
curl -X POST "https://euppay.com/api/v1/payments/550e8400-e29b-41d4-a716-446655440000/refund" \
-H "Content-Type: application/json" \
-H "X-Api-Key: your_api_key" \
-H "X-Api-Secret: your_api_secret" \
-d '{
"amount": 50.25,
"reason": "Partial refund - item returned"
}'
Response:
{
"success": true,
"message": "Refund processed successfully",
"data": {
"refund_id": "ref_550e8400-e29b-41d4-a716-446655440000",
"original_reference": "550e8400-e29b-41d4-a716-446655440000",
"refund_amount": 50.25,
"currency": "USD",
"status": "completed",
"processed_at": "2023-12-01T15:30:00Z"
}
}
Error Handling
The API uses standard HTTP status codes and provides detailed error information in the response body.
Common Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid request format or parameters |
| 401 | UNAUTHORIZED | Invalid or missing API credentials |
| 422 | VALIDATION_ERROR | Request validation failed |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests - rate limit exceeded |
| 500 | INTERNAL_ERROR | Internal server error |
3DS Specific Errors
{
"success": false,
"message": "Authentication required",
"error_code": "3DS_AUTH_REQUIRED",
"details": {
"reason": "Card authentication required by issuer",
"recommended_action": "complete_3ds_challenge"
}
}
Address Validation Errors
{
"success": false,
"message": "Address validation failed",
"error_code": "ADDRESS_VALIDATION_ERROR",
"errors": {
"billing_address": [
"Street address is required",
"Country must be a valid 2-letter code"
]
}
}
Testing Your Integration
Integrate and test against sandbox credentials first. Sandbox access is available as soon as your account is set up. Going live on card rails is a separate step coordinated with your acquirer.
Sandbox Testing
- Use the test cards and test credentials published by your payment provider — never real card numbers
- Exercise the full flow: initialize → redirect to hosted checkout → return → status check
- Test success, decline, and cancellation outcomes, plus full and partial refunds
- Verify that your
return_urlhandler confirms the transaction status server-side
Before Going Live
Complete Code Examples
Complete PHP Integration
<?php
class PaymentGateway {
private $apiKey;
private $apiSecret;
private $baseUrl;
public function __construct($apiKey, $apiSecret) {
$this->apiKey = $apiKey;
$this->apiSecret = $apiSecret;
$this->baseUrl = 'https://euppay.com/api/v1';
}
public function initializePayment($paymentData) {
$url = $this->baseUrl . '/payments/initialize';
$headers = [
'Content-Type: application/json',
'X-Api-Key: ' . $this->apiKey,
'X-Api-Secret: ' . $this->apiSecret
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($paymentData));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception('API request failed with HTTP code: ' . $httpCode);
}
return json_decode($response, true);
}
public function checkTransactionStatus($reference) {
$url = $this->baseUrl . '/payments/' . $reference . '/status';
$headers = [
'X-Api-Key: ' . $this->apiKey,
'X-Api-Secret: ' . $this->apiSecret
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
// Usage: initialize, then redirect the customer to the provider's hosted checkout
try {
$gateway = new PaymentGateway('your_api_key', 'your_api_secret');
$paymentData = [
'order_id' => 'ORDER-' . time(),
'amount' => 100.50,
'currency' => 'USD',
'customer_name' => 'John Doe',
'customer_email' => 'john.doe@example.com',
'billing_address' => '123 Main Street, New York, NY, 10001, US',
'return_url' => 'https://your-website.com/success',
'cancel_url' => 'https://your-website.com/cancel'
];
$result = $gateway->initializePayment($paymentData);
if ($result['success'] && ($result['action'] ?? null) === 'redirect') {
// Send the customer to the provider's hosted checkout page
header('Location: ' . $result['redirect_url']);
exit;
}
echo 'Payment failed: ' . ($result['message'] ?? 'Unknown error');
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
// On your return_url handler: confirm before fulfilling
// $status = $gateway->checkTransactionStatus($_GET['reference'] ?? '');
// if (($status['data']['status'] ?? null) === 'completed') { /* fulfil order */ }
?>
Support and Resources
Need help with your integration? Here are your support options:
Technical Support
Email: hello@gateway.euppay.com
Founder-led support; same-business-day responses on Core plans and above.