Payrize API
Documentation
Integrate real-time payment verification into your application. Validate CBE, Telebirr, BOA, Amhara, and other Ethiopian bank receipts with a single API call.
https://payrize.et/api
< 100ms
TLS 1.3 / AES-256
Quick Start Guide
Follow these 3 simple steps to integrate Payrize into your application:
Get Your API Key
Register for an account and generate your API key from the dashboard. Use test keys (sk_test_...) for sandbox testing.
Make Your First API Call
Send a POST request to /v1/verify-transaction with the receipt details. See code examples below for your preferred language.
Handle the Response
Process the JSON response to confirm or reject transactions. Store the verification_id for your records.
Authentication
All API requests require authentication using a Bearer token. Include your API key in the Authorization header.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
Security Notice
Never expose your API key in client-side code or public repositories. Use environment variables or secure vaults in production.
Sandbox Mode
Use test API keys (sk_test_...) to simulate transactions without affecting real data. The sandbox returns deterministic responses based on test receipt numbers.
| Test Code | Description | Response |
|---|---|---|
| FT_TEST_SUCCESS | Valid receipt simulation | 200 Success |
| FT_TEST_DUPLICATE | Already verified receipt | 409 Conflict |
| FT_TEST_TIMEOUT | Bank network timeout | 504 Timeout |
| FT_TEST_INVALID | Invalid receipt format | 422 Unprocessable |
Rate Limits
API requests are subject to rate limiting based on your plan. Rate limit information is included in response headers and the response body.
Sandbox
requests / month
Professional
requests / month
Enterprise
custom limits
Verify Transaction
Validates a payment receipt against the issuing bank's records. Returns detailed transaction information when verified successfully.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| bank_id | string | Required |
Bank identifier. Supported values:cbe
telebirr
boa
awash
dashen
amhara
mpesa
ebirr_kaffi
ebirr_coopay
|
| receipt_number | string | Required | The unique receipt/transaction reference number or URL link from the payment confirmation. |
| merchant_account | string | Optional | Your merchant account number. If provided, the API validates that the payment was sent to this specific account, preventing account redirection fraud. |
| amount | float | Optional | Expected transaction amount in ETB. If the actual receipt amount differs, the API returns a 422 Unprocessable Entity error. |
| currency | string | Optional | Currency code. Defaults to ETB. Also supports USD. |
Success Response (200 OK)
{
"success": true,
"status": "VERIFIED",
"data": {
"receipt_number": "FT26189ABCDE",
"bank_id": "cbe",
"amount": 5500.00,
"currency": "ETB",
"sender_name": "ABEBE KEBEDE",
"receiver_account": "1000123456789",
"receiver_name": "MERCHANT SUITE PLC",
"payment_date": "2026-07-05",
"verified_at": "2026-07-05T11:05:01Z",
"verification_id": "ver_a1b2c3d4e5"
},
"meta": {
"client_ip": "197.156.86.22",
"response_time_ms": 72,
"rate_limit": {
"limit": 120,
"remaining": 119,
"reset_in_seconds": 60
}
}
}
Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid JSON payload or missing required fields. |
| 401 | UNAUTHORIZED | Invalid or missing API key. |
| 409 | DUPLICATE_TRANSACTION | Receipt has already been verified. Cannot be used again. |
| 422 | AMOUNT_MISMATCH | Provided amount does not match the actual receipt amount. |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests. Check rate limit headers for retry timing. |
| 504 | GATEWAY_TIMEOUT | Banking node unreachable. Retry with exponential backoff. |
Code Examples
cURL
Quick test from your terminal:
curl -X POST https://payrize.et/api/v1/verify-transaction.php \
-H "Authorization: Bearer sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"bank_id": "cbe",
"receipt_number": "FT26189ABCDE",
"amount": 5500.00,
"currency": "ETB"
}'
PHP
Using cURL in PHP with proper error handling:
<?php
// Payrize API Verification - PHP Example
// Requires: PHP 7.4+ with cURL extension
class PayrizeAPI {
private $apiKey;
private $baseUrl = 'https://api.payrize.et';
public function __construct($apiKey) {
$this->apiKey = $apiKey;
}
/**
* Verify a payment receipt
*
* @param string $bankId Bank identifier (cbe, telebirr, boa, etc.)
* @param string $receipt Receipt number to verify
* @param float $amount Expected amount (optional)
* @param string $merchantAcc Merchant account number (optional)
* @return array Decoded API response
* @throws Exception On API error
*/
public function verifyTransaction(
$bankId,
$receipt,
$amount = null,
$merchantAcc = null
) {
$payload = [
'bank_id' => $bankId,
'receipt_number' => $receipt,
];
if ($amount !== null) {
$payload['amount'] = $amount;
}
if ($merchantAcc !== null) {
$payload['merchant_account'] = $merchantAcc;
}
$ch = curl_init($this->baseUrl . '/v1/verify-transaction.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $this->apiKey,
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new Exception("cURL Error: $error");
}
$data = json_decode($response, true);
if ($httpCode >= 400) {
$errorMsg = $data['error'] ?? 'Unknown error';
throw new Exception("API Error ($httpCode): $errorMsg");
}
return $data;
}
}
// Usage Example
try {
$payrize = new PayrizeAPI('sk_test_your_key_here');
$result = $payrize->verifyTransaction(
'cbe', // Bank ID
'FT26189ABCDE', // Receipt number
5500.00, // Expected amount
'1000123456789' // Merchant account (optional)
);
if ($result['success'] && $result['status'] === 'VERIFIED') {
echo "✓ Payment verified successfully!\n";
echo "Amount: " . $result['data']['amount'] . " ETB\n";
echo "Sender: " . $result['data']['sender_name'] . "\n";
echo "Verification ID: " . $result['data']['verification_id'] . "\n";
}
} catch (Exception $e) {
error_log("Payrize Error: " . $e->getMessage());
echo "✗ Verification failed: " . $e->getMessage();
}
Python
Using the requests library:
import requests
import os
from typing import Optional, Dict, Any
class PayrizeAPI:
"""Payrize Payment Verification API Client"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://payrize.et/api"
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"Accept": "application/json",
})
def verify_transaction(
self,
bank_id: str,
receipt_number: str,
amount: Optional[float] = None,
merchant_account: Optional[str] = None,
currency: str = "ETB"
) -> Dict[str, Any]:
"""
Verify a payment receipt.
Args:
bank_id: Bank identifier (cbe, telebirr, boa, etc.)
receipt_number: Receipt number to verify
amount: Expected transaction amount (optional)
merchant_account: Merchant account number (optional)
currency: Currency code (default: ETB)
Returns:
Dict containing verification result
Raises:
requests.RequestException: On API error
"""
payload = {
"bank_id": bank_id,
"receipt_number": receipt_number,
"currency": currency,
}
if amount is not None:
payload["amount"] = amount
if merchant_account:
payload["merchant_account"] = merchant_account
try:
response = self.session.post(
f"{self.base_url}/v1/verify-transaction.php",
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
error_data = e.response.json() if e.response.text else {}
error_msg = error_data.get("error", str(e))
raise requests.RequestException(
f"API Error ({e.response.status_code}): {error_msg}"
)
except requests.exceptions.Timeout:
raise requests.RequestException("Request timed out after 30 seconds")
# Usage Example
if __name__ == "__main__":
# Get API key from environment variable (recommended)
api_key = os.environ.get("PAYRIZE_API_KEY", "sk_test_your_key_here")
payrize = PayrizeAPI(api_key)
try:
result = payrize.verify_transaction(
bank_id="cbe",
receipt_number="FT26189ABCDE",
amount=5500.00,
merchant_account="1000123456789"
)
if result["success"] and result["status"] == "VERIFIED":
data = result["data"]
print(f"✓ Payment verified successfully!")
print(f"Amount: {data['amount']} {data['currency']}")
print(f"Sender: {data['sender_name']}")
print(f"Verified at: {data['verified_at']}")
print(f"Verification ID: {data['verification_id']}")
else:
print(f"✗ Verification failed: {result}")
except requests.RequestException as e:
print(f"✗ Error: {e}")
JavaScript (Browser)
Using the Fetch API. Note: Never expose your API key in frontend code. Use a backend proxy.
// Payrize API - JavaScript Fetch Example
// WARNING: Never expose API keys in client-side code!
// Use a backend proxy for production applications.
class PayrizeClient {
constructor(apiKey, baseUrl = 'https://api.payrize.et') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async verifyTransaction({
bankId,
receiptNumber,
amount = null,
merchantAccount = null,
currency = 'ETB'
}) {
const payload = {
bank_id: bankId,
receipt_number: receiptNumber,
currency: currency
};
if (amount !== null) payload.amount = amount;
if (merchantAccount) payload.merchant_account = merchantAccount;
const response = await fetch(`${this.baseUrl}/v1/verify-transaction`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(payload)
});
const data = await response.json();
if (!response.ok) {
throw new Error(
data.error || `HTTP ${response.status}: Request failed`
);
}
return data;
}
}
// Usage Example
async function verifyPayment() {
const payrize = new PayrizeClient('sk_test_your_key_here');
try {
const result = await payrize.verifyTransaction({
bankId: 'cbe',
receiptNumber: 'FT26189ABCDE',
amount: 5500.00,
merchantAccount: '1000123456789'
});
if (result.success && result.status === 'VERIFIED') {
console.log('✓ Payment verified successfully!');
console.log('Amount:', result.data.amount, result.data.currency);
console.log('Sender:', result.data.sender_name);
console.log('Verification ID:', result.data.verification_id);
}
} catch (error) {
console.error('✗ Verification failed:', error.message);
}
}
verifyPayment();
Node.js
Using node-fetch or native fetch (Node 18+):
// Payrize API - Node.js Example
// Requires Node.js 18+ for native fetch, or install node-fetch
class PayrizeAPI {
constructor(apiKey, baseUrl = 'https://api.payrize.et') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async verifyTransaction({
bankId,
receiptNumber,
amount = null,
merchantAccount = null,
currency = 'ETB'
}) {
const payload = {
bank_id: bankId,
receipt_number: receiptNumber,
currency
};
if (amount) payload.amount = amount;
if (merchantAccount) payload.merchant_account = merchantAccount;
const response = await fetch(`${this.baseUrl}/v1/verify-transaction`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(payload)
});
const data = await response.json();
if (!response.ok) {
const error = new Error(data.error || `API returned ${response.status}`);
error.status = response.status;
error.data = data;
throw error;
}
return data;
}
}
// Usage Example with Express.js middleware
const payrize = new PayrizeAPI(process.env.PAYRIZE_API_KEY);
// Example Express route handler
app.post('/api/verify-payment', async (req, res) => {
try {
const result = await payrize.verifyTransaction({
bankId: req.body.bank_id,
receiptNumber: req.body.receipt_number,
amount: req.body.amount,
merchantAccount: req.body.merchant_account
});
if (result.success) {
// Store verification in your database
await db.saveVerification(result.data);
return res.json({
success: true,
message: 'Payment verified successfully',
data: result.data
});
}
} catch (error) {
console.error('Verification error:', error.message);
return res.status(error.status || 500).json({
success: false,
error: error.message
});
}
});
// Standalone usage
(async () => {
try {
const result = await payrize.verifyTransaction({
bankId: 'cbe',
receiptNumber: 'FT26189ABCDE',
amount: 5500.00
});
console.log('✓ Verified:', result.data);
} catch (error) {
console.error('✗ Failed:', error.message);
}
})();
Need Help?
Our team is here to help you integrate Payrize into your application. Reach out for technical support, custom integrations, or enterprise onboarding.