ZAYANPAY SANDBOX

Create invoices & verify status

This documentation covers the essential Create Invoice and Verify Invoice endpoints for merchant and partner developers. Follow the instructions to test transactions securely.

Base URL
https://zayanpay.com
Checkout Endpoint
POST /api/checkout/redirect
Verify Endpoint
POST /api/verify-payment
Preferred Auth Header
ZAYANPAY-API-KEY

Overview

ZayanPay exposes two primary external REST APIs for sandbox and production testing: Create Invoice and Verify Invoice.

How to get your API key

  1. Login to your ZayanPay dashboard.
  2. Navigate to the Main Menu.
  3. Select Brands / API Keys.
  4. Copy your Brand Key / API Key.
Sandbox test API key
sandbox_test_8f4c9a2e7b31

Authentication

Every request must include your API key to authenticate securely with our verification cluster.

Method Value Notes
Preferred header zayan-api-key: sandbox_test_8f4c9a2e7b31 Recommended
Also supported header zayanpay-api-key: sandbox_test_8f4c9a2e7b31 Supported
Query parameter ?apikey=sandbox_test_8f4c9a2e7b31 Supported

Endpoints

Name Method Path Purpose
Create Invoice POST /v1/payment/create Create a hosted invoice and return payment_url.
Verify Invoice POST /v1/payment/verify Verify invoice payment status and TrxID authenticity.

Common rules

  • Set Content-Type to application/json.
  • Every request must include an API key.
  • Only active merchant brands are allowed.
  • redirect_url domain must match the merchant registered website domain.
  • amount must be greater than 0 BDT.
  • metadata must be valid JSON object and stay within 1 KB.

Laravel Full Website Integration Guide

Laravel 9, 10, 11+

Follow this step-by-step guide to connect your Laravel website with ZayanPay. This architecture uses native Laravel HTTP Client, handles customer checkout redirect, verifies transaction authenticity upon return, and receives instant asynchronous background Webhook (IPN) notifications.

1

Configure Environment (.env)

Add your ZayanPay credentials to your Laravel project's .env file. Get your live API key from Merchant Portal → Developer API Keys.

.env
# ZayanPay Automated Gateway Configuration
ZAYANPAY_BASE_URL=https://zayanpay.com
ZAYANPAY_API_KEY=zp_live_your_secret_api_key
ZAYANPAY_CURRENCY=BDT
2

Create Service Class (app/Services/ZayanPayService.php)

Create a dedicated service to encapsulate communication with the ZayanPay API using Laravel's built-in Http client.

app/Services/ZayanPayService.php
<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use RuntimeException;

class ZayanPayService
{
    protected string $baseUrl;
    protected string $apiKey;

    public function __construct()
    {
        $this->baseUrl = rtrim(env('ZAYANPAY_BASE_URL', 'https://zayanpay.com'), '/');
        $this->apiKey = (string) env('ZAYANPAY_API_KEY');
    }

    /**
     * Create hosted checkout session and get redirect payment URL.
     */
    public function createPayment(
        string $name,
        string $email,
        string $phone,
        float $amount,
        string $returnUrl,
        ?string $webhookUrl = null,
        array $metadata = []
    ): array {
        $response = Http::timeout(15)
            ->withHeaders([
                'ZAYANPAY-API-KEY' => $this->apiKey,
                'Accept' => 'application/json',
            ])
            ->post("{$this->baseUrl}/api/checkout/redirect", [
                'full_name'     => $name,
                'email_address' => $email,
                'mobile_number' => $phone,
                'amount'        => (string)$amount,
                'currency'      => env('ZAYANPAY_CURRENCY', 'BDT'),
                'return_url'    => $returnUrl,
                'webhook_url'   => $webhookUrl ?? '--',
                'metadata'      => $metadata,
            ]);

        if ($response->failed()) {
            throw new RuntimeException($response->json('error.message') ?? 'Failed to connect to ZayanPay.');
        }

        return $response->json(); // Returns ['pp_id' => '...', 'pp_url' => 'http://...', 'status' => 'pending']
    }

    /**
     * Verify payment status and ensure transaction authenticity.
     */
    public function verifyPayment(string $ppId): array
    {
        $response = Http::timeout(10)
            ->withHeaders([
                'ZAYANPAY-API-KEY' => $this->apiKey,
                'Accept' => 'application/json',
            ])
            ->post("{$this->baseUrl}/api/verify-payment", [
                'pp_id' => $ppId,
            ]);

        return $response->json();
    }
}
3

Create Payment Controller (app/Http/Controllers/PaymentController.php)

Handles initiating the checkout, customer redirect return callback, and backend IPN webhook.

app/Http/Controllers/PaymentController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\ZayanPayService;

class PaymentController extends Controller
{
    protected ZayanPayService $zayanPay;

    public function __construct(ZayanPayService $zayanPay)
    {
        $this->zayanPay = $zayanPay;
    }

    /**
     * 1. Initiate Checkout and redirect customer to bKash/Nagad gateway
     */
    public function pay(Request $request)
    {
        $orderId = 'ORD-' . time();
        $amount = (float) $request->input('amount', 500);

        try {
            $checkout = $this->zayanPay->createPayment(
                name: $request->input('name', 'Tanvir Ahmed'),
                email: $request->input('email', '[email protected]'),
                phone: $request->input('phone', '01712345678'),
                amount: $amount,
                returnUrl: route('payment.callback'),
                webhookUrl: url('/api/payment/webhook'),
                metadata: ['order_id' => $orderId]
            );

            // Store pending order in session or DB
            session(['pending_order' => ['order_id' => $orderId, 'pp_id' => $checkout['pp_id']]]);

            // Redirect customer directly to ZayanPay hosted payment screen
            return redirect()->away($checkout['pp_url']);
        } catch (\Throwable $e) {
            return back()->with('error', 'Unable to initiate payment: ' . $e->getMessage());
        }
    }

    /**
     * 2. Customer Return Callback (handles redirect after payment)
     */
    public function callback(Request $request)
    {
        $trxRef = $request->query('transaction_ref');
        $status = $request->query('pp_status');

        // Verify transaction authenticity directly with ZayanPay API
        $verification = $this->zayanPay->verifyPayment($trxRef);

        if (($verification['status'] ?? '') === 'completed' || $status === 'completed') {
            $trxId = $verification['transaction_id'] ?? $trxRef;
            
            // TODO: Update your Order model status to 'paid' in DB
            // Order::where('order_id', session('pending_order.order_id'))->update(['status' => 'paid', 'trx_id' => $trxId]);

            return view('payment.success', compact('trxId'));
        }

        return redirect('/')->with('error', 'Payment was cancelled or could not be verified.');
    }

    /**
     * 3. Asynchronous IPN Webhook (guaranteed delivery)
     */
    public function webhook(Request $request)
    {
        $payload = $request->all();

        if (($payload['status'] ?? '') === 'completed') {
            $orderId = $payload['metadata']['order_id'] ?? null;
            // TODO: Update Order status to 'paid'
            return response()->json(['status' => 'success', 'message' => 'Order fulfilled']);
        }

        return response()->json(['status' => 'acknowledged']);
    }
}
4

Register Routes (routes/web.php)

Add these routes to your routes/web.php:

routes/web.php
use App\Http\Controllers\PaymentController;

// 1. Submit form to create payment and redirect to ZayanPay
Route::post('/payment/checkout', [PaymentController::class, 'pay'])->name('payment.checkout');

// 2. Customer Return URL after paying
Route::get('/payment/callback', [PaymentController::class, 'callback'])->name('payment.callback');

// 3. Instant Payment Notification (IPN / Webhook)
Route::post('/api/payment/webhook', [PaymentController::class, 'webhook'])->name('payment.webhook');
5

Exclude Webhook Route from CSRF Protection

Because server-to-server webhooks do not have a browser session, exclude the webhook URL from CSRF verification:

Laravel 11 (bootstrap/app.php)
->withMiddleware(function (Middleware $middleware): void {
    $middleware->validateCsrfTokens(except: [
        'api/payment/webhook', // Exclude ZayanPay IPN
    ]);
})
That's it! Your Laravel site is now fully integrated with ZayanPay.
Customers can now click checkout on your website, pay using bKash, Nagad, or Rocket, and get their purchase fulfilled automatically in real-time with 0% gateway commission.

Checkout Redirect API

Create a hosted checkout invoice session and receive the secure payment URL to redirect your customers for instant payment.

POST https://zayanpay.com/api/checkout/redirect

Required headers

  • Content-Type: application/json
  • ZAYANPAY-API-KEY: your_merchant_api_key

Request fields

Field Type Required Description
full_name string Yes Customer full name.
email_address string Yes Customer email address.
mobile_number string Yes Customer mobile phone number.
amount number Yes Invoice amount in BDT (e.g. 500).
currency string No Currency code (default BDT).
return_url string Yes Customer return URL after payment completion.
webhook_url string No Server-to-server IPN webhook notification listener.
metadata object No Custom key-value dictionary (e.g. {"order_id": "ORD-1001"}).

Request examples

curl -X POST "https://zayanpay.com/api/checkout/redirect" \
  -H "Content-Type: application/json" \
  -H "ZAYANPAY-API-KEY: your_api_key_here" \
  -d '{
    "full_name": "Tanvir Ahmed",
    "email_address": "[email protected]",
    "mobile_number": "01712345678",
    "amount": "500",
    "currency": "BDT",
    "return_url": "https://your-site.com/payment/callback",
    "webhook_url": "https://your-site.com/api/payment/webhook",
    "metadata": {
      "order_id": "ORD-1001"
    }
  }'

Success response (200 OK)

JSON Response
{
  "pp_id": "291583772135977897208017178",
  "pp_url": "https://zayanpay.com/payment/291583772135977897208017178",
  "status": "pending",
  "expires_at": "2026-09-16T18:30:00Z"
}

Verify Invoice / Payment Status

Verify the real-time payment status directly from your Laravel or custom backend before fulfilling an order or granting service access.

POST https://zayanpay.com/api/verify-payment

Required headers

  • Content-Type: application/json
  • ZAYANPAY-API-KEY: your_api_key_here

Request fields

Field Type Required Description
pp_id string Yes Unique Payment Invoice ID returned in callback or checkout response.

Request examples

curl -X POST "https://zayanpay.com/api/verify-payment" \
  -H "Content-Type: application/json" \
  -H "ZAYANPAY-API-KEY: your_api_key_here" \
  -d '{
    "pp_id": "291583772135977897208017178"
  }'
Success response (200 OK) application/json
{
  "status": "completed",
  "pp_id": "291583772135977897208017178",
  "trx_id": "9J8A7K210L",
  "payment_method": "bkash",
  "amount": "500.00",
  "currency": "BDT",
  "customer_mobile": "01712345678"
}

Status values

pending completed failed expired
Recommendation

Always verify the invoice from your backend using this endpoint before fulfilling any order, delivering digital services, or sending a "Received Payment" notification.

Webhook Callback Flow

If webhook_url is sent during invoice creation, ZayanPay will automatically dispatch an asynchronous POST event after a verified payment update.

Webhook payload (JSON Body)

application/json
{
  "invoice_id": "INV_9F8B27D3",
  "status": "true"
}

Query parameter style

https://merchant.com/api/zayanpay/webhook?invoice_id=INV_9F8B27D3&status=true

Recommended merchant flow

1 Create order
2 Create invoice
3 Redirect user
4 Receive callback
5 Verify invoice
6 If completed, mark paid
7 If pending, retry
8 If failed, cancel order

Production Checklist

Before deploying to your live environment, verify these final steps to ensure a smooth transition.

API key stored in environment variables
HTTPS enabled on all endpoints
Redirect domain matched to brand
Backend verification added
Logging & error alerts enabled
Webhook secured with secret validation
Need the original PDF?

Download the full API documentation for offline reference and team sharing.

Download PDF

Apps and Plugins

ZayanPay provides Android apps, WordPress plugins, SDKs, and ready-made modules to help you integrate faster.

View all modules
v3.0 APK

ZayanPay Android APK

Official Android notification listener app for nonstop background transaction forwarding.

Download APK
WooCommerce

WooCommerce Plugin

Turnkey payment gateway plugin with instant checkout verification and order status synchronization.

Download Plugin
WHMCS

WHMCS Gateway

Automated invoice payment and service activation gateway module for web hosting providers.

Download Module
SMM Panel

SMM Panel Module

Instant automated wallet balance refill for SmartPanel, PerfectPanel, and custom SMM scripts.

Download Module
PHP & Laravel

PHP / Laravel SDK

PSR-4 PHP library and Laravel Service Provider / Facade for checkout creation and IPN validation.

Download SDK

Advanced API

Beta

Programmatic merchant balance inquiry, automated payout triggers, and raw bank SMS event streaming for high-volume enterprise users.

Enterprise Access Required

The Advanced API features high-throughput socket connections, custom transaction parsing rules, and multi-SIM balancing. Contact enterprise support at [email protected] or WhatsApp for sandbox access keys.