Verify API
Check the status of payment transactions
Verify API
The Verify endpoint allows you to check the status of a payment transaction after the customer has completed or attempted payment. This is essential for confirming payment success before fulfilling orders.
Endpoint Details
Endpoint:
GET /payments/verify/{transaction_id}
Base URLs:
- Sandbox:
https://sandbox.api.moneybag.com.bd/api/v2
- Production:
https://api.moneybag.com.bd/api/v2
Authentication
All requests require authentication via API key in the header:
X-Merchant-API-Key: <your_merchant_api_key>
Request
Headers
Header | Value | Required |
---|---|---|
X-Merchant-API-Key | Your merchant API key | Yes |
Path Parameters
Parameter | Type | Required | Description |
---|---|---|---|
transaction_id | string | Yes | The unique transaction ID received from Moneybag after payment processing |
Request Example
GET /payments/verify/txn1234567899
X-Merchant-API-Key: your_merchant_api_key
Response
Success Response
HTTP Status: 200 OK
{
"success": true,
"data": {
"transaction_id": "txn1234567899",
"order_id": "order123321",
"verified": true,
"status": "SUCCESS",
"amount": "1280.00",
"currency": "BDT",
"payment_method": "bkash",
"payment_reference_id": "REF_987654321",
"customer": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+8801700000000"
},
"paid_at": "2025-01-18T10:45:30Z",
"metadata": {
"source": "web",
"session_id": "SESSION12345"
}
},
"message": "Payment verification details retrieved"
}
Response Fields
Field | Type | Description |
---|---|---|
transaction_id | string | Unique transaction ID |
order_id | string | Merchant's order ID |
verified | boolean | Whether the payment is verified |
status | string | Payment status (SUCCESS, FAILED, PENDING, CANCELLED) |
amount | decimal | Paid amount |
currency | string | Currency code |
payment_method | string | Payment method used (card, bkash, nagad, etc.) |
payment_reference_id | string | Reference ID from payment provider |
customer | object | Customer information |
paid_at | datetime | Payment completion timestamp (ISO format) |
metadata | object | Additional transaction data |
Payment Status Values
Status | Description |
---|---|
SUCCESS | Payment completed successfully |
FAILED | Payment failed |
PENDING | Payment is being processed |
CANCELLED | Payment was cancelled by user |
EXPIRED | Payment session expired |
REFUNDED | Payment has been refunded |
Error Response
HTTP Status: 404/401/500
{
"success": false,
"error": {
"code": "TRANSACTION_NOT_FOUND",
"message": "Transaction with ID txn1234567899 not found"
}
}
Code Examples
cURL
curl -X GET \
"https://sandbox.api.moneybag.com.bd/api/v2/payments/verify/txn1234567899" \
-H "X-Merchant-API-Key: your_merchant_api_key"
JavaScript (Node.js)
const axios = require('axios');
async function verifyPayment(transactionId) {
try {
const response = await axios.get(
`https://sandbox.api.moneybag.com.bd/api/v2/payments/verify/${transactionId}`,
{
headers: {
'X-Merchant-API-Key': 'your_merchant_api_key'
}
}
);
const data = response.data.data;
if (data.verified && data.status === 'SUCCESS') {
console.log('Payment verified successfully');
console.log('Amount:', data.amount);
console.log('Payment Method:', data.payment_method);
// Process the successful payment
} else {
console.log('Payment not successful:', data.status);
}
} catch (error) {
console.error('Verification failed:', error.response.data);
}
}
// Example usage
verifyPayment('txn1234567899');
Python
import requests
def verify_payment(transaction_id):
url = f'https://sandbox.api.moneybag.com.bd/api/v2/payments/verify/{transaction_id}'
headers = {
'X-Merchant-API-Key': 'your_merchant_api_key'
}
response = requests.get(url, headers=headers)
result = response.json()
if result['success']:
data = result['data']
if data['verified'] and data['status'] == 'SUCCESS':
print('Payment verified successfully')
print(f"Amount: {data['amount']}")
print(f"Payment Method: {data['payment_method']}")
# Process the successful payment
else:
print(f"Payment not successful: {data['status']}")
else:
print(f"Verification error: {result['error']['message']}")
# Example usage
verify_payment('txn1234567899')
PHP
<?php
function verifyPayment($transactionId) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.api.moneybag.com.bd/api/v2/payments/verify/{$transactionId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-Merchant-API-Key: your_merchant_api_key'
]
]);
$response = curl_exec($curl);
$result = json_decode($response, true);
curl_close($curl);
if ($result['success']) {
$data = $result['data'];
if ($data['verified'] && $data['status'] === 'SUCCESS') {
echo 'Payment verified successfully' . PHP_EOL;
echo 'Amount: ' . $data['amount'] . PHP_EOL;
echo 'Payment Method: ' . $data['payment_method'] . PHP_EOL;
// Process the successful payment
return true;
} else {
echo 'Payment not successful: ' . $data['status'] . PHP_EOL;
return false;
}
} else {
echo 'Verification error: ' . $result['error']['message'] . PHP_EOL;
return false;
}
}
// Example usage
verifyPayment('txn1234567899');
?>
Try in Playground
When to Verify
Immediate Verification
Verify payment immediately after customer returns to your site:
// In your success callback handler
app.get('/payment/success', async (req, res) => {
const { transaction_id } = req.query;
// Verify immediately
const verification = await verifyPayment(transaction_id);
if (verification.success && verification.data.status === 'SUCCESS') {
// Process order fulfillment
await fulfillOrder(verification.data.order_id);
}
});
Webhook + Verification
Best practice: Use webhooks with verification for reliability:
// In your webhook handler
app.post('/webhook', async (req, res) => {
const { transaction_id, event_type } = req.body;
if (event_type === 'payment.success') {
// Always verify before processing
const verification = await verifyPayment(transaction_id);
if (verification.data.verified) {
await processPayment(verification.data);
}
}
res.status(200).send('OK');
});
Periodic Verification
For pending payments, verify periodically:
async function checkPendingPayments() {
const pendingTransactions = await getPendingTransactions();
for (const txn of pendingTransactions) {
const verification = await verifyPayment(txn.id);
if (verification.data.status !== 'PENDING') {
// Update transaction status
await updateTransactionStatus(txn.id, verification.data.status);
}
}
}
// Run every 5 minutes
setInterval(checkPendingPayments, 5 * 60 * 1000);
Best Practices
1. Always Verify Before Fulfillment
Never fulfill orders based solely on redirect URLs:
// ❌ Bad - Don't do this
app.get('/payment/success', (req, res) => {
fulfillOrder(req.query.order_id); // Unsafe!
});
// ✅ Good - Always verify first
app.get('/payment/success', async (req, res) => {
const verification = await verifyPayment(req.query.transaction_id);
if (verification.data.verified && verification.data.status === 'SUCCESS') {
fulfillOrder(verification.data.order_id);
}
});
2. Handle All Status Types
switch(verification.data.status) {
case 'SUCCESS':
await fulfillOrder(orderId);
break;
case 'PENDING':
await markOrderPending(orderId);
break;
case 'FAILED':
await cancelOrder(orderId);
break;
case 'CANCELLED':
await handleCancellation(orderId);
break;
default:
await logUnknownStatus(orderId, status);
}
3. Implement Idempotency
Prevent duplicate order processing:
async function processPayment(verification) {
// Check if already processed
const existing = await getProcessedTransaction(verification.transaction_id);
if (existing) {
return existing; // Already processed
}
// Process and mark as completed
await markTransactionProcessed(verification.transaction_id);
await fulfillOrder(verification.order_id);
}
4. Store Verification Results
Keep audit trail of all verifications:
async function verifyAndStore(transactionId) {
const verification = await verifyPayment(transactionId);
// Store verification result
await storeVerification({
transaction_id: transactionId,
verification_result: verification,
verified_at: new Date(),
ip_address: req.ip
});
return verification;
}
Testing
Use sandbox test transactions to verify different scenarios:
Transaction ID | Returns Status |
---|---|
txn_test_success | SUCCESS |
txn_test_failed | FAILED |
txn_test_pending | PENDING |
txn_test_cancelled | CANCELLED |
txn_test_expired | EXPIRED |
Common Issues
Transaction Not Found
- Ensure transaction ID is correct
- Check if using correct environment (sandbox vs production)
- Wait a few seconds after payment before verifying
Verification Timeout
- Implement retry logic with exponential backoff
- Check network connectivity
- Verify API endpoint status
Status Mismatch
- Always use latest verification result
- Don't cache verification results for extended periods
- Implement webhook handlers for status updates
Related Resources
- Checkout API - Create payment sessions
- Webhooks - Real-time notifications
- Error Codes - Complete error reference
- Sandbox Testing - Test verification flows