Documentation v1.0

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.

Base URL
https://payrize.et/api
Avg Response
< 100ms
Encryption
TLS 1.3 / AES-256

Quick Start Guide

Follow these 3 simple steps to integrate Payrize into your application:

1

Get Your API Key

Register for an account and generate your API key from the dashboard. Use test keys (sk_test_...) for sandbox testing.

2

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.

3

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

100

requests / month

Professional

10,000

requests / month

Enterprise

Unlimited

custom limits

Verify Transaction

POST https://payrize.et/api/v1/verify-transaction.php

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 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 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 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.