Developer documentation

DR PAY BD integration guide

Set up payments, plugins and apps with DR PAY BD. Every guide includes ready code that you can copy into your project.

No section matches your search. Try a shorter word.

Introduction

Overview

DR PAY BD lets your customers pay with mobile wallets. Your site creates a payment, the customer completes it on the gateway page, and then your server confirms the result with the verify API before it marks an order as paid.

1
Create a payment

Send the amount and your success and cancel URLs to the create API. Redirect the customer to the gateway.

2
Customer pays

The customer pays and is sent back to your success or cancel URL.

3
Verify on your server

Call the verify API with the transaction ID. Mark the order paid only when the status is COMPLETED.

APIs

REST

REST APIs are available in two environments. Use sandbox while you build, then move to live for real payments.

Base URL
https://pay.drpaybd.top/
Headers on every request
API-KEY, SECRET-KEY, BRAND-KEY, Content-Type
Keep your API key, secret key and brand key on your server only. If a key is exposed, regenerate it from your dashboard right away.

Create a payment

 <?php $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://pay.drpaybd.top/api/payment/create', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS =>'{"success_url":"yourdomain.com/success","cancel_url":"yourdomain.com/cancel","metadata":{"phone":"016****"},"amount":"10"}', CURLOPT_HTTPHEADER => array( 'API-KEY: gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type: application/json', 'SECRET-KEY: YourSecretKeyHere', 'BRAND-KEY: YourBrandKeyHere' ), )); $response = curl_exec($curl); curl_close($curl); echo $response; ?> 
 <?php $client = new Client(); $headers = [ 'API-KEY' => 'gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type' => 'application/json', 'SECRET-KEY' => 'YourSecretKeyHere', 'BRAND-KEY' => 'YourBrandKeyHere' ]; $body = '{ "success_url": "yourdomain.com/success", "cancel_url": "yourdomain.com/cancel", "metadata": { "phone": "016****" }, "amount": "10" }'; $request = new Request('POST', 'https://pay.drpaybd.top/api/payment/create', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> 
 const axios = require('axios'); let data = JSON.stringify({ "success_url": "yourdomain.com/success", "cancel_url": "yourdomain.com/cancel", "metadata": { "phone": "016****" }, "amount": "10" }); let config = { method: 'post', maxBodyLength: Infinity, url: 'https://pay.drpaybd.top/api/payment/create', headers: { 'API-KEY': 'gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type': 'application/json', 'SECRET-KEY': 'YourSecretKeyHere', 'BRAND-KEY': 'YourBrandKeyHere' }, data : data }; axios.request(config) .then((response) => { console.log(JSON.stringify(response.data)); }) .catch((error) => { console.log(error); }); 
 import requests import json url = "https://pay.drpaybd.top/api/payment/create" payload = json.dumps({ "success_url": "yourdomain.com/success", "cancel_url": "yourdomain.com/cancel", "metadata": { "phone": "016****" }, "amount": "10" }) headers = { 'API-KEY': 'gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type': 'application/json', 'SECRET-KEY': 'YourSecretKeyHere', 'BRAND-KEY': 'YourBrandKeyHere' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) 
 package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://pay.drpaybd.top/api/payment/create" method := "POST" payload := strings.NewReader(`{"success_url":"yourdomain.com/success","cancel_url":"yourdomain.com/cancel","metadata":{"phone":"01521412457"},"amount":"10"}`) client := &http.Client { } req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return } req.Header.Add("API-KEY", "gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef") req.Header.Add("Content-Type", "application/json") req.Header.Add("SECRET-KEY", "YourSecretKeyHere") req.Header.Add("BRAND-KEY", "YourBrandKeyHere") res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) } 

Response Details

Field Name Type Description
Success Response
status bool TRUE
message String Message for Status
payment_url String Payment Link (where customers will complete their payment)
Error Response
status bool FALSE
message String Message associated with the error response
Completing Payment Page task you will be redirected to success or cancel page based on transaction status with the following Query Parameters: yourdomain.com/(success/cancel)?transactionId=******&paymentMethod=***&paymentAmount=**.**&paymentFee=**.**&status=pending or success or failed

Verify a payment

<?php
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://pay.drpaybd.top/api/payment/verify', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS =>'{"transaction_id":"ABCDEFH"}', CURLOPT_HTTPHEADER => array( 'API-KEY: gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type: application/json', 'SECRET-KEY: Secret key From API credentials', 'BRAND-KEY: Brand key From Brands' ),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?> 
<?php
$client = new Client();
$headers = [ 'API-KEY' => 'gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type' => 'application/json', 'SECRET-KEY' => 'Secret key From API credentials', 'BRAND-KEY' => 'Brand key From Brands'
];
$body = '{ "transaction_id": "ABCDEFH"
}';
$request = new Request('POST', 'https://pay.drpaybd.top/api/payment/verify', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
?> 
const axios = require('axios');
let data = JSON.stringify({ "transaction_id": "ABCDEFH"
});
let config = { method: 'post', maxBodyLength: Infinity, url: 'https://pay.drpaybd.top/api/payment/verify', headers: { 'API-KEY': 'gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type': 'application/json', 'SECRET-KEY': 'Secret key From API credentials', 'BRAND-KEY': 'Brand key From Brands' }, data : data
};
axios.request(config)
.then((response) => { console.log(JSON.stringify(response.data));
})
.catch((error) => { console.log(error);
}); 
import http.client
import json
conn = http.client.HTTPSConnection("local.pay.expensivepay.com")
payload = json.dumps({ "transaction_id": "ABCDEFH"
})
headers = { 'API-KEY': 'gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef', 'Content-Type': 'application/json', 'SECRET-KEY': 'Secret key From API credentials', 'BRAND-KEY': 'Brand key From Brands'
}
conn.request("POST", "/api/payment/verify", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8")) 
package main
import ( "fmt" "strings" "net/http" "io/ioutil"
)
func main() { url := "https://pay.drpaybd.top/api/payment/verify" method := "POST" payload := strings.NewReader(`{"transaction_id":"ABCDEFH"}`) client := &http.Client { } req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return } req.Header.Add("API-KEY", "gnXi7etgWNhFyFGZFrOMYyrmnF4A1eGU5SC2QRmUvILOlNc2Ef") req.Header.Add("Content-Type", "application/json") req.Header.Add("SECRET-KEY", "Secret key From API credentials") req.Header.Add("BRAND-KEY", "Brand key From Brands") res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body))
} 
Sample Response
{ "cus_name": "John Doe", "cus_email": "[email protected]", "amount": "900.000", "transaction_id": "OVKPXW165414", "metadata": { "phone": "015****", }, "payment_method": "bkash", "status": "COMPLETED"
} 

Response Details

Field Name Type Description
Success Response
status string COMPLETED or PENDING or ERROR
cus_name String Customer Name
cus_email String Customer Email
amount String Amount
transaction_id String Transaction id Generated by System
metadata json Metadata used for Payment creation
Error Response
status bool FALSE
message String Message associated with the error response

Code guides

Per language

Choose the language your project uses. Each guide covers configuration, a reusable client, creating a payment, verifying it and handling the success URL.

PHP (cURL)

Native

Use PHP's built-in cURL extension. No Composer package is required, so it works on shared hosting and cPanel.

1. Keep your keys safe

Store the keys on your server, for example in a config file that is not public. Never put them in JavaScript or HTML.

config.php
<?phpdefine('DRPAY_BASE_URL', 'https://YOUR-GATEWAY-DOMAIN/');define('DRPAY_API_KEY', 'your-api-key');define('DRPAY_SECRET_KEY', 'your-secret-key');define('DRPAY_BRAND_KEY', 'your-brand-key');

2. Small helper function

One function sends every request with the required headers and returns the decoded JSON.

DrPayClient.php
<?phpfunction drpay_request(string $endpoint, array $payload): array{ $ch = curl_init(DRPAY_BASE_URL . 'api/payment/' . $endpoint); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'API-KEY: ' . DRPAY_API_KEY, 'SECRET-KEY: ' . DRPAY_SECRET_KEY, 'BRAND-KEY: ' . DRPAY_BRAND_KEY, ], ]); $body = curl_exec($ch); $error = curl_error($ch); curl_close($ch); if ($body === false) { throw new RuntimeException('Gateway request failed: ' . $error); } return json_decode($body, true) ?? [];}

3. Create a payment

create-payment.php
<?phprequire 'config.php';require 'DrPayClient.php';$response = drpay_request('create', [ 'success_url' => 'https://yourdomain.com/success', 'cancel_url' => 'https://yourdomain.com/cancel', 'metadata' => ['phone' => '016****'], 'amount' => '10',]);print_r($response);

4. Verify a payment

Call verify with the transaction ID you received. Only mark an order as paid when the response status is COMPLETED.

verify-payment.php
<?phprequire 'config.php';require 'DrPayClient.php';$trxId = $_GET['transactionId'] ?? '';$result = drpay_request('verify', ['transaction_id' => $trxId]);if (($result['status'] ?? '') === 'COMPLETED') { // mark the order as paid in your database} else { // payment not completed, keep the order pending}
Use a database transaction and check the amount in your system before you release goods or services. Do not trust the success URL alone.

Laravel

Framework

Laravel's HTTP client sends the requests. Keep the keys in your .env file and read them from a config file.

1. Add the keys to .env

.env
DRPAY_BASE_URL=https://YOUR-GATEWAY-DOMAIN/DRPAY_API_KEY=your-api-keyDRPAY_SECRET_KEY=your-secret-keyDRPAY_BRAND_KEY=your-brand-key

2. Config file

config/drpay.php
<?phpreturn [ 'base_url' => env('DRPAY_BASE_URL'), 'api_key' => env('DRPAY_API_KEY'), 'secret_key' => env('DRPAY_SECRET_KEY'), 'brand_key' => env('DRPAY_BRAND_KEY'),];

3. Service class

app/Services/DrPayService.php
<?phpnamespace App\Services;use Illuminate\Support\Facades\Http;class DrPayService{ private function client() { return Http::withHeaders([ 'API-KEY' => config('drpay.api_key'), 'SECRET-KEY' => config('drpay.secret_key'), 'BRAND-KEY' => config('drpay.brand_key'), ])->acceptJson()->timeout(30); } public function createPayment(array $data): array { $response = $this->client()->post(config('drpay.base_url') . 'api/payment/create', [ 'success_url' => route('payment.success'), 'cancel_url' => route('payment.cancel'), 'metadata' => ['phone' => $data['phone']], 'amount' => (string) $data['amount'], ]); return $response->json() ?? []; } public function verifyPayment(string $transactionId): array { $response = $this->client()->post(config('drpay.base_url') . 'api/payment/verify', [ 'transaction_id' => $transactionId, ]); return $response->json() ?? []; }}

4. Controller and routes

app/Http/Controllers/PaymentController.php
<?phpnamespace App\Http\Controllers;use App\Services\DrPayService;use Illuminate\Http\Request;class PaymentController extends Controller{ public function success(Request $request, DrPayService $drpay) { $result = $drpay->verifyPayment($request->query('transactionId', '')); if (($result['status'] ?? '') === 'COMPLETED') { // mark the order as paid return view('payment.success', ['payment' => $result]); } return redirect()->route('payment.cancel'); } public function cancel() { return view('payment.cancel'); }}
routes/web.php
<?phpuse App\Http\Controllers\PaymentController;Route::get('/payment/success', [PaymentController::class, 'success'])->name('payment.success');Route::get('/payment/cancel', [PaymentController::class, 'cancel'])->name('payment.cancel');
Only mark an order as paid after verify returns COMPLETED. Store the transaction ID so the same payment cannot be used twice.

Python

Requests

Use the requests library. Install it once and keep the keys in environment variables.

terminal
pip install requests

1. Client module

drpay_client.py
import osimport requestsBASE_URL = os.environ.get("DRPAY_BASE_URL", "https://YOUR-GATEWAY-DOMAIN/")HEADERS = { "Content-Type": "application/json", "API-KEY": os.environ.get("DRPAY_API_KEY", ""), "SECRET-KEY": os.environ.get("DRPAY_SECRET_KEY", ""), "BRAND-KEY": os.environ.get("DRPAY_BRAND_KEY", ""),}def _post(endpoint, payload): response = requests.post( BASE_URL + "api/payment/" + endpoint, json=payload, headers=HEADERS, timeout=30, ) response.raise_for_status() return response.json()def create_payment(amount, phone, success_url, cancel_url): return _post("create", { "success_url": success_url, "cancel_url": cancel_url, "metadata": {"phone": phone}, "amount": str(amount), })def verify_payment(transaction_id): return _post("verify", {"transaction_id": transaction_id})

2. Create and verify

example.py
from drpay_client import create_payment, verify_paymentorder = create_payment( amount=10, phone="016****", success_url="https://yourdomain.com/success", cancel_url="https://yourdomain.com/cancel",)print(order)result = verify_payment("ABCDEFH")if result.get("status") == "COMPLETED": print("Paid:", result["transaction_id"], result["amount"])else: print("Not completed yet")

3. Success URL with Flask

app.py
from flask import Flask, requestfrom drpay_client import verify_paymentapp = Flask(__name__)@app.route("/success")def success(): result = verify_payment(request.args.get("transactionId", "")) if result.get("status") == "COMPLETED": return "Payment received" return "Payment is not completed", [email protected]("/cancel")def cancel(): return "Payment cancelled"
Call raise_for_status() so network or server errors are not silently ignored. Log the response for support requests.

JavaScript (Node.js)

Server side

Call the gateway from your Node.js server. Node 18 and newer include fetch, so no extra package is needed.

Never call the gateway from browser JavaScript. The secret and brand keys would be visible to every visitor. Always call it from your backend.

1. Environment file

.env
DRPAY_BASE_URL=https://YOUR-GATEWAY-DOMAIN/DRPAY_API_KEY=your-api-keyDRPAY_SECRET_KEY=your-secret-keyDRPAY_BRAND_KEY=your-brand-key

2. Client module

drpay.js
const BASE_URL = process.env.DRPAY_BASE_URL;async function post(endpoint, payload) { const response = await fetch(BASE_URL + 'api/payment/' + endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'API-KEY': process.env.DRPAY_API_KEY, 'SECRET-KEY': process.env.DRPAY_SECRET_KEY, 'BRAND-KEY': process.env.DRPAY_BRAND_KEY, }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error('Gateway returned HTTP ' + response.status); } return response.json();}export const createPayment = (amount, phone, successUrl, cancelUrl) => post('create', { success_url: successUrl, cancel_url: cancelUrl, metadata: { phone }, amount: String(amount), });export const verifyPayment = (transactionId) => post('verify', { transaction_id: transactionId });

3. Create and verify

example.js
import { createPayment, verifyPayment } from './drpay.js';const order = await createPayment( 10, '016****', 'https://yourdomain.com/success', 'https://yourdomain.com/cancel');console.log(order);const result = await verifyPayment('ABCDEFH');if (result.status === 'COMPLETED') { console.log('Paid', result.transaction_id, result.amount);} else { console.log('Not completed yet');}

4. Success route with Express

server.js
import express from 'express';import { verifyPayment } from './drpay.js';const app = express();app.get('/success', async (req, res) => { try { const result = await verifyPayment(req.query.transactionId); if (result.status === 'COMPLETED') { return res.send('Payment received'); } res.status(402).send('Payment is not completed'); } catch (error) { res.status(502).send('Could not confirm the payment'); }});app.get('/cancel', (req, res) => res.send('Payment cancelled'));app.listen(3000);

Integration plugins

Ready made

Download a ready-made plugin or module for your platform and follow its setup steps.

WordPress / WooCommerce
Download Plugin
PHP TOPUP Gateway
Download Module
Sketchware (SWB + Blocks)
Download Assets

Mobile App

Android

Install the Android app on the phone that receives the SMS. The app connects with your live API keys to verify every transaction.