Set up payments, plugins and apps with DR PAY BD. Every guide includes ready code that you can copy into your project.
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.
Send the amount and your success and cancel URLs to the create API. Redirect the customer to the gateway.
The customer pays and is sent back to your success or cancel URL.
Call the verify API with the transaction ID. Mark the order paid only when the status is COMPLETED.
REST APIs are available in two environments. Use sandbox while you build, then move to live for real payments.
<?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)) } | 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 | ||
<?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))
} { "cus_name": "John Doe", "cus_email": "[email protected]", "amount": "900.000", "transaction_id": "OVKPXW165414", "metadata": { "phone": "015****", }, "payment_method": "bkash", "status": "COMPLETED"
} | 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 |
Choose the language your project uses. Each guide covers configuration, a reusable client, creating a payment, verifying it and handling the success URL.
Use PHP's built-in cURL extension. No Composer package is required, so it works on shared hosting and cPanel.
Store the keys on your server, for example in a config file that is not public. Never put them in JavaScript or HTML.
<?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'); One function sends every request with the required headers and returns the decoded JSON.
<?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) ?? [];} <?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); Call verify with the transaction ID you received. Only mark an order as paid when the response status is COMPLETED.
<?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} Laravel's HTTP client sends the requests. Keep the keys in your .env file and read them from a config file.
DRPAY_BASE_URL=https://YOUR-GATEWAY-DOMAIN/DRPAY_API_KEY=your-api-keyDRPAY_SECRET_KEY=your-secret-keyDRPAY_BRAND_KEY=your-brand-key <?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'),]; <?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() ?? []; }} <?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'); }} <?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'); COMPLETED. Store the transaction ID so the same payment cannot be used twice.Use the requests library. Install it once and keep the keys in environment variables.
pip install requests 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}) 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") 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" raise_for_status() so network or server errors are not silently ignored. Log the response for support requests.Call the gateway from your Node.js server. Node 18 and newer include fetch, so no extra package is needed.
DRPAY_BASE_URL=https://YOUR-GATEWAY-DOMAIN/DRPAY_API_KEY=your-api-keyDRPAY_SECRET_KEY=your-secret-keyDRPAY_BRAND_KEY=your-brand-key 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 }); 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');} 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); Download a ready-made plugin or module for your platform and follow its setup steps.
Install the Android app on the phone that receives the SMS. The app connects with your live API keys to verify every transaction.