Introduction
Getting started
For payment checkout, use the invoice ID returned by InstaPay. For direct payment verification, customers enter only a TxID; your server supplies the expected amount and method. Keep credentials server-side.
Integrate payment checkout and verify transactions securely with a simple server-side flow.
Developer referenceFor payment checkout, use the invoice ID returned by InstaPay. For direct payment verification, customers enter only a TxID; your server supplies the expected amount and method. Keep credentials server-side.
https://pay.instapaybd.com/api/payment/createhttps://pay.instapaybd.com/api/payment/verifyinvoice transaction_id. For a separately submitted bank/mobile/Binance transaction, use the Transaction Verification API below.| Field | Required | Description |
|---|---|---|
| amount | Create only | Payable amount from your saved order/invoice. Never trust an amount submitted by the customer. |
| success_url | Yes | Successful payment redirect URL. |
| cancel_url | Yes | Cancelled payment redirect URL. |
| metadata | No | Optional JSON metadata. |
| transaction_id | Verify only | InstaPay checkout invoice Transaction ID (Payment Verify endpoint). |
| Header | Value |
|---|---|
| Content-Type | application/json |
| API-KEY | API/App Key |
| SECRET-KEY | Secret Key |
| BRAND-KEY | Brand Key |
Set the payable amount on your server and send your customer to the returned payment URL.
Use the amount from your saved order. A customer does not need to enter an amount or your API credentials.
curl --request POST 'https://pay.instapaybd.com/api/payment/create' \ --header 'Content-Type: application/json' \ --header 'API-KEY: YOUR_API_KEY' \ --header 'SECRET-KEY: YOUR_SECRET_KEY' \ --header 'BRAND-KEY: YOUR_BRAND_KEY' \ --data '{ "amount":"900.000", "success_url":"https://yourdomain.com/payment/success", "cancel_url":"https://yourdomain.com/payment/cancel" }' <?php$order = [ 'amount' => '900.000', 'success_url' => 'https://yourdomain.com/payment/success', 'cancel_url' => 'https://yourdomain.com/payment/cancel',];$ch = curl_init('https://pay.instapaybd.com/api/payment/create');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 25, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'API-KEY: YOUR_API_KEY', 'SECRET-KEY: YOUR_SECRET_KEY', 'BRAND-KEY: YOUR_BRAND_KEY', ], CURLOPT_POSTFIELDS => json_encode($order),]);$result = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);$error = curl_error($ch);curl_close($ch);if ($result === false) { throw new RuntimeException($error);}$data = json_decode($result, true);if ($httpCode >= 200 && $httpCode < 300 && !empty($data['payment_url'])) { $paymentUrl = $data['payment_url']; echo $paymentUrl;} else { echo $result;} <?php$client = new \GuzzleHttp\Client(['timeout' => 25]);$response = $client->post('https://pay.instapaybd.com/api/payment/create', [ 'headers' => [ 'API-KEY' => 'YOUR_API_KEY', 'SECRET-KEY' => 'YOUR_SECRET_KEY', 'BRAND-KEY' => 'YOUR_BRAND_KEY', ], 'json' => [ 'amount' => '900.000', 'success_url' => 'https://yourdomain.com/payment/success', 'cancel_url' => 'https://yourdomain.com/payment/cancel', ],]);$data = json_decode((string) $response->getBody(), true);$paymentUrl = $data['payment_url'] ?? null;var_dump($paymentUrl); import requestsorder = { "amount": "900.000", "success_url": "https://yourdomain.com/payment/success", "cancel_url": "https://yourdomain.com/payment/cancel",}response = requests.post( "https://pay.instapaybd.com/api/payment/create", headers={ "API-KEY": "YOUR_API_KEY", "SECRET-KEY": "YOUR_SECRET_KEY", "BRAND-KEY": "YOUR_BRAND_KEY", }, json=order, timeout=25,)response.raise_for_status()data = response.json()print(data.get("payment_url")) const order = { amount: '900.000', success_url: 'https://yourdomain.com/payment/success', cancel_url: 'https://yourdomain.com/payment/cancel',};const response = await fetch('https://pay.instapaybd.com/api/payment/create', { method: 'POST', headers: { 'Content-Type': 'application/json', 'API-KEY': 'YOUR_API_KEY', 'SECRET-KEY': 'YOUR_SECRET_KEY', 'BRAND-KEY': 'YOUR_BRAND_KEY', }, body: JSON.stringify(order), signal: AbortSignal.timeout(25000),});const data = await response.json();if (!response.ok) throw new Error(data.message || 'Create failed');console.log(data.payment_url); package mainimport ( "bytes" "fmt" "io" "net/http" "time")func main() { payload := []byte(`{"amount":"900.000","success_url":"https://yourdomain.com/payment/success","cancel_url":"https://yourdomain.com/payment/cancel"}`) req, err := http.NewRequest("POST", "https://pay.instapaybd.com/api/payment/create", bytes.NewReader(payload)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("API-KEY", "YOUR_API_KEY") req.Header.Set("SECRET-KEY", "YOUR_SECRET_KEY") req.Header.Set("BRAND-KEY", "YOUR_BRAND_KEY") client := &http.Client{Timeout: 25 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { panic(err) } fmt.Println(string(body))} The successful response includes a payment_url for redirecting the customer.
| Field | Purpose |
|---|---|
status | Creation request result |
message | Message from the API |
payment_url | Customer checkout URL |
payment_url as proof of payment.Send the checkout invoice Transaction ID only. Match the response against your saved invoice before marking it paid.
amount or method parameter for extra matching.curl --request POST 'https://pay.instapaybd.com/api/payment/verify' \ --header 'Content-Type: application/json' \ --header 'API-KEY: YOUR_API_KEY' \ --header 'SECRET-KEY: YOUR_SECRET_KEY' \ --header 'BRAND-KEY: YOUR_BRAND_KEY' \ --data '{"transaction_id":"OVKPXW165414"}' <?php$invoice = [ 'transaction_id' => 'OVKPXW165414', 'amount' => '900.000',];$ch = curl_init('https://pay.instapaybd.com/api/payment/verify');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 25, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'API-KEY: YOUR_API_KEY', 'SECRET-KEY: YOUR_SECRET_KEY', 'BRAND-KEY: YOUR_BRAND_KEY', ], CURLOPT_POSTFIELDS => json_encode([ 'transaction_id' => $invoice['transaction_id'], ]),]);$body = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);$error = curl_error($ch);curl_close($ch);if ($body === false) throw new RuntimeException($error);$data = json_decode($body, true);$paid = $httpCode >= 200 && $httpCode < 300 && ($data['status'] ?? '') === 'COMPLETED' && (string) ($data['transaction_id'] ?? '') === $invoice['transaction_id'] && isset($data['amount']) && is_numeric($data['amount']) && number_format((float) $data['amount'], 3, '.', '') === number_format((float) $invoice['amount'], 3, '.', '');if ($paid) { echo 'Payment verified';} else { echo 'Payment not verified';} <?php$invoiceId = 'OVKPXW165414';$expectedAmount = '900.000';$client = new \GuzzleHttp\Client(['timeout' => 25]);$response = $client->post('https://pay.instapaybd.com/api/payment/verify', [ 'headers' => [ 'API-KEY' => 'YOUR_API_KEY', 'SECRET-KEY' => 'YOUR_SECRET_KEY', 'BRAND-KEY' => 'YOUR_BRAND_KEY', ], 'json' => ['transaction_id' => $invoiceId],]);$data = json_decode((string) $response->getBody(), true);$paid = ($data['status'] ?? '') === 'COMPLETED' && ($data['transaction_id'] ?? '') === $invoiceId && isset($data['amount']) && is_numeric($data['amount']) && number_format((float) $data['amount'], 3, '.', '') === number_format((float) $expectedAmount, 3, '.', '');var_dump($paid); from decimal import Decimalimport requestsinvoice_id = "OVKPXW165414"invoice_amount = Decimal("900.000")response = requests.post( "https://pay.instapaybd.com/api/payment/verify", headers={ "API-KEY": "YOUR_API_KEY", "SECRET-KEY": "YOUR_SECRET_KEY", "BRAND-KEY": "YOUR_BRAND_KEY", }, json={"transaction_id": invoice_id}, timeout=25,)response.raise_for_status()data = response.json()paid = ( data.get("status") == "COMPLETED" and data.get("transaction_id") == invoice_id and data.get("amount") is not None and Decimal(str(data["amount"])) == invoice_amount)print("Payment verified" if paid else "Payment not verified") const invoice = { transactionId: 'OVKPXW165414', amount: '900.000',};const response = await fetch('https://pay.instapaybd.com/api/payment/verify', { method: 'POST', headers: { 'Content-Type': 'application/json', 'API-KEY': 'YOUR_API_KEY', 'SECRET-KEY': 'YOUR_SECRET_KEY', 'BRAND-KEY': 'YOUR_BRAND_KEY', }, body: JSON.stringify({ transaction_id: invoice.transactionId }), signal: AbortSignal.timeout(25000),});const data = await response.json();const paid = response.ok && data.status === 'COMPLETED' && data.transaction_id === invoice.transactionId && data.amount != null && Number.isFinite(Number(data.amount)) && Math.round(Number(data.amount) * 1000) === Math.round(Number(invoice.amount) * 1000);console.log(paid ? 'Payment verified' : 'Payment not verified'); package mainimport ( "bytes" "encoding/json" "fmt" "io" "net/http" "time")func main() { invoiceID := "OVKPXW165414" req, err := http.NewRequest("POST", "https://pay.instapaybd.com/api/payment/verify", bytes.NewBufferString(`{"transaction_id":"OVKPXW165414"}`)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("API-KEY", "YOUR_API_KEY") req.Header.Set("SECRET-KEY", "YOUR_SECRET_KEY") req.Header.Set("BRAND-KEY", "YOUR_BRAND_KEY") client := &http.Client{Timeout: 25 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { panic(err) } var data struct { Status string `json:"status"`; TransactionID string `json:"transaction_id"`; Amount string `json:"amount"` } if err := json.Unmarshal(body, &data); err != nil { panic(err) } paid := res.StatusCode == 200 && data.Status == "COMPLETED" && data.TransactionID == invoiceID && data.Amount == "900.000" fmt.Println("Verified:", paid)} { "cus_name": "John Doe", "cus_email": "[email protected]", "amount": "900.000", "transaction_id": "OVKPXW165414", "metadata": {}, "payment_method": "bkash", "status": "COMPLETED"}status === "COMPLETED", its Transaction ID matches your invoice, and the amount matches your saved payable amount. A PENDING response is not success. Check the payment method too when your invoice requires a specific gateway.Different API: For a Binance Order ID submitted by a customer, use /api/v1/transaction/verify with the Brand Key; the backend should add the expected USDT amount and method: "binance" from the saved order.
Ask the customer for Transaction ID only. Use your saved order data on the backend.
{"transaction_id":"M_P_71505104267788288"}{ "transaction_id":"M_P_71505104267788288", "amount":"5.25000000", "method":"binance"}PENDING response is not successful payment.Verify payments from your account's Stored Data.
https://instapaybd.com/api/v1/transaction/verify Only transaction_id is required. Add amount and method if needed.
| Header | Value |
|---|---|
API-KEY | Your Brand Key |
Content-Type | application/json |
Choose one request format. All provided fields must match.
{ "transaction_id": "DIJ1N1TWAB"} { "transaction_id": "DIJ1N1TWAB", "amount": 500} { "transaction_id": "DIJ1N1TWAB", "method": "bkash"} { "transaction_id": "DIJ1N1TWAB", "amount": 500, "method": "bkash"} transaction_id (required), amount (optional), method (optional). Invalid fields return HTTP 422.Use the same endpoint with method binance. Amount is in USDT.
{ "transaction_id": "M_P_71505104267788288", "amount": "5.25000000", "method": "binance"} If Binance data is still syncing, the API may return PENDING with retry_after. A payment can be verified only once.
| Status | Verified | Credit |
|---|---|---|
| COMPLETED | Yes | 1 |
| PENDING | No | 0 |
| MISMATCH | No | 0 |
| ALREADY_USED | No | 0 |
| NOT_FOUND | No | 0 |
One credit is deducted only on a first successful verification.
{ "success": true, "verified": true, "status": "COMPLETED", "credit_charged": 1, "remaining_credit": 999, "transaction": { "transaction_id": "DIJ1N1TWAB", "amount": "500.000", "currency": "BDT", "payment_method": "bkash" }}{ "success": false, "verified": false, "status": "PENDING", "credit_charged": 0, "remaining_credit": 1000, "retry_after": 90, "message": "Binance payment is being synchronized. Retry with the same Transaction ID."}{ "success": false, "verified": false, "status": "MISMATCH", "error": "parameter_mismatch", "mismatched_fields": ["amount"], "credit_charged": 0, "remaining_credit": 1000, "message": "One or more supplied parameters do not match the Stored Data transaction."}{ "success": false, "verified": false, "status": "ALREADY_USED", "credit_charged": 0, "remaining_credit": 999, "message": "This Transaction ID has already been used."}{ "success": false, "verified": false, "status": "NOT_FOUND", "credit_charged": 0, "remaining_credit": 1000, "message": "Transaction not found in Stored Data for this Brand Key."}Quick start: only transaction_id is required. For deposit crediting, send amount and method too.
curl --request POST 'https://instapaybd.com/api/v1/transaction/verify' \ --header 'Content-Type: application/json' \ --header 'API-KEY: YOUR_BRAND_KEY' \ --data '{"transaction_id":"DIJ1N1TWAB"}'<?php$payload = ['transaction_id' => 'DIJ1N1TWAB'];$ch = curl_init('https://instapaybd.com/api/v1/transaction/verify');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 25, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'API-KEY: YOUR_BRAND_KEY' ], CURLOPT_POSTFIELDS => json_encode($payload)]);$body = curl_exec($ch);if ($body === false) { throw new RuntimeException(curl_error($ch));}$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);$result = json_decode($body, true);$verified = $httpCode >= 200 && $httpCode < 300 && ($result['verified'] ?? false) === true && ($result['status'] ?? '') === 'COMPLETED';import requestsresponse = requests.post( 'https://instapaybd.com/api/v1/transaction/verify', headers={'API-KEY': 'YOUR_BRAND_KEY'}, json={'transaction_id': 'DIJ1N1TWAB'}, timeout=25)result = response.json()verified = ( response.ok and result.get('verified') is True and result.get('status') == 'COMPLETED')const response = await fetch('https://instapaybd.com/api/v1/transaction/verify', { method: 'POST', headers: { 'Content-Type': 'application/json', 'API-KEY': 'YOUR_BRAND_KEY' }, body: JSON.stringify({ transaction_id: 'DIJ1N1TWAB' }), signal: AbortSignal.timeout(25000)});const result = await response.json();const verified = response.ok && result.verified === true && result.status === 'COMPLETED';transaction_id, amount and method, and require verified === true with status === "COMPLETED".