Map and Location Illustration 1

Nagad支付配置教程

Nagad支付配置教程

📋 目录


🚀 Nagad平台介绍

什么是Nagad?

Nagad是孟加拉国邮政部门推出的官方数字支付平台,于2019年正式上线。作为政府背景的金融科技服务,Nagad在孟加拉国数字支付市场占据重要地位。

核心优势

  • 政府支持:国家邮政部门运营,政策扶持力度大
  • 网络覆盖:依托全国9,000+邮政网点和60万+代理商
  • 安全可靠:银行级安全标准,符合监管要求
  • 功能完善:支持转账、缴费、商户支付等全场景

市场数据

用户规模:4,800万+ 注册用户
日交易量:1,200万笔
市场份额:18%(移动支付领域)
商户数量:50万+ 活跃商户

主要服务

  • 个人服务:转账汇款、话费充值、账单缴费
  • 商户服务:线上支付、POS收款、批量转账
  • 政府服务:补贴发放、税费缴纳、公共缴费

📝 商户申请步骤

商户类型分级

等级 适用对象 月限额 费率 结算周期
基础商户 个体户、小店 300万塔卡 1.99%起 T+2
标准商户 中小企业 1,500万塔卡 1.75%起 T+1
企业商户 大型企业 无限制 1.55%起 T+0可选

申请材料准备

个人商户

必需材料:
✓ 国民身份证(NID)扫描件
✓ 手机号实名认证
✓ 银行账户证明
✓ 营业场所照片
✓ 业务说明书

企业商户

必需材料:
✓ 营业执照(Trade License)
✓ 税务登记证(TIN Certificate)
✓ 公司章程
✓ 法人身份证明
✓ 银行开户许可证
✓ 近12个月财务报表

申请流程时间

  • 基础商户:7-10个工作日
  • 标准商户:12-15个工作日
  • 企业商户:20-25个工作日

🔌 API接口说明

环境配置

bash
# 沙盒环境 API_URL=https://api-sandbox.mynagad.com/api/dfs

# 生产环境 API_URL=https://api.mynagad.com/api/dfs

核心接口流程

mermaid
sequenceDiagram participant 商户 as 商户系统
    participant Nagad as Nagad API
    participant 用户 as 用户
    
    商户->>Nagad: 1. 初始化支付
    Nagad->>商户: 2. 返回支付链接
    商户->>用户: 3. 跳转支付页面
    用户->>Nagad: 4. 完成支付
    Nagad->>商户: 5. 支付回调
    商户->>Nagad: 6. 确认支付状态

1. 支付初始化

http
POST /check-out/initialize/{merchant_id}
Content-Type: application/json X-KM-Api-Version: v-0.2.0 X-KM-IP-V4: {client_ip} X-KM-Client-Type: PC_WEB X-KM-Signature: {digital_signature}

请求参数:
{ "account_number": "01XXXXXXXXX", // 商户手机号 "amount": "100.50", // 交易金额 "currency": "BDT", "challenge": "32位随机字符串", "datetime": "20241215120000", // YYYYMMDDHHmmss "order_id": "ORDER_001", // 商户订单号 "product_name": "商品名称", "callback_url": "https://yoursite.com/callback" }

成功响应:
{ "status": "Success", "statusCode": "000", "redirectGatewayURL": "https://api.mynagad.com/redirect-url", "paymentReferenceId": "NGD_PAY_001", "callBackUrl": "https://yoursite.com/callback" }

2. 支付完成确认

http
POST /check-out/complete/{payment_reference_id}

请求参数:
{
    "paymentRefId": "NGD_PAY_001",
    "challenge": "32位随机字符串"
}

成功响应:
{
    "status": "Success",
    "statusCode": "000",
    "gatwayTransactionId": "TXN_123456",
    "amount": "100.50",
    "orderId": "ORDER_001",
    "paymentDateTime": "2024-12-15 12:30:45"
}

3. 支付状态查询

http
GET /verify/payment/{payment_reference_id}

响应:
{
    "status": "Success",
    "statusCode": "000",
    "transactionStatus": "Success",    // Success/Pending/Failed
    "amount": "100.50",
    "orderId": "ORDER_001"
}

💻 代码集成示例

Node.js示例

javascript
const crypto = require('crypto'); const axios = require('axios'); const fs = require('fs'); class NagadPayment { constructor(config) { this.merchantId = config.merchantId; this.baseUrl = config.sandbox ? 'https://api-sandbox.mynagad.com/api/dfs' : 'https://api.mynagad.com/api/dfs'; // 加载RSA密钥 this.privateKey = fs.readFileSync(config.privateKeyPath, 'utf8'); this.publicKey = fs.readFileSync(config.publicKeyPath, 'utf8'); } // 创建支付 async createPayment(paymentData) { const url = `${this.baseUrl}/check-out/initialize/${this.merchantId}`; const requestData = { account_number: paymentData.merchantPhone, amount: paymentData.amount.toFixed(2), currency: 'BDT', challenge: this.generateChallenge(), datetime: this.getCurrentDateTime(), order_id: paymentData.orderId, product_name: paymentData.productName, callback_url: paymentData.callbackUrl }; const headers = { 'Content-Type': 'application/json', 'X-KM-Api-Version': 'v-0.2.0', 'X-KM-IP-V4': paymentData.clientIp || '127.0.0.1', 'X-KM-Client-Type': 'PC_WEB', 'X-KM-Signature': this.generateSignature(requestData) }; try { const response = await axios.post(url, requestData, { headers }); return { success: true, data: response.data }; } catch (error) { return { success: false, error: error.response?.data || error.message }; } } // 完成支付 async completePayment(paymentRefId, challenge) { const url = `${this.baseUrl}/check-out/complete/${paymentRefId}`; const requestData = { paymentRefId: paymentRefId, challenge: challenge
        }; const headers = { 'Content-Type': 'application/json', 'X-KM-Api-Version': 'v-0.2.0', 'X-KM-IP-V4': '127.0.0.1', 'X-KM-Client-Type': 'PC_WEB', 'X-KM-Signature': this.generateSignature(requestData) }; try { const response = await axios.post(url, requestData, { headers }); return { success: true, data: response.data }; } catch (error) { return { success: false, error: error.response?.data || error.message }; } } // 生成数字签名 generateSignature(data) { // 排序数据 const sortedData = this.sortObject(data); const jsonString = JSON.stringify(sortedData); // 创建签名 const sign = crypto.createSign('RSA-SHA256');
        sign.update(jsonString, 'utf8'); return sign.sign(this.privateKey, 'base64'); } // 递归排序对象 sortObject(obj) { if (typeof obj !== 'object' || obj === null) return obj; if (Array.isArray(obj)) return obj.map(item => this.sortObject(item)); const sorted = {}; Object.keys(obj).sort().forEach(key => {
            sorted[key] = this.sortObject(obj[key]); }); return sorted; } // 生成32位随机字符串 generateChallenge() { return crypto.randomBytes(16).toString('hex'); } // 获取当前时间戳 getCurrentDateTime() { const now = new Date(); return now.getFullYear().toString() + (now.getMonth() + 1).toString().padStart(2, '0') +
               now.getDate().toString().padStart(2, '0') +
               now.getHours().toString().padStart(2, '0') +
               now.getMinutes().toString().padStart(2, '0') +
               now.getSeconds().toString().padStart(2, '0'); } } // 使用示例 const nagad = new NagadPayment({ merchantId: 'YOUR_MERCHANT_ID', privateKeyPath: './keys/private_key.pem', publicKeyPath: './keys/public_key.pem', sandbox: true }); // 创建支付 const result = await nagad.createPayment({ merchantPhone: '01XXXXXXXXX', amount: 100.50, orderId: 'ORDER_001', productName: '测试商品', callbackUrl: 'https://yoursite.com/nagad/callback', clientIp: '192.168.1.1' }); if (result.success) { console.log('支付链接:', result.data.redirectGatewayURL); } else { console.error('支付创建失败:', result.error); }

PHP示例

php
<?php class NagadPayment { private $merchantId; private $baseUrl; private $privateKey; public function __construct($config) { $this->merchantId = $config['merchant_id']; $this->baseUrl = $config['sandbox'] ? 'https://api-sandbox.mynagad.com/api/dfs' : 'https://api.mynagad.com/api/dfs'; $this->privateKey = file_get_contents($config['private_key_path']); } public function createPayment($paymentData) { $url = $this->baseUrl . '/check-out/initialize/' . $this->merchantId; $requestData = [ 'account_number' => $paymentData['merchant_phone'], 'amount' => number_format($paymentData['amount'], 2, '.', ''), 'currency' => 'BDT', 'challenge' => bin2hex(random_bytes(16)), 'datetime' => date('YmdHis'), 'order_id' => $paymentData['order_id'], 'product_name' => $paymentData['product_name'], 'callback_url' => $paymentData['callback_url'] ]; $headers = [ 'Content-Type: application/json', 'X-KM-Api-Version: v-0.2.0', 'X-KM-IP-V4: ' . ($_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'), 'X-KM-Client-Type: PC_WEB', 'X-KM-Signature: ' . $this->generateSignature($requestData) ]; $response = $this->makeRequest('POST', $url, $requestData, $headers); return $response; } private function generateSignature($data) { ksort($data); $jsonString = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $signature = ''; openssl_sign($jsonString, $signature, $this->privateKey, OPENSSL_ALGO_SHA256); return base64_encode($signature); } private function makeRequest($method, $url, $data, $headers) { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => ($method === 'POST'), CURLOPT_POSTFIELDS => ($method === 'POST') ? json_encode($data) : null ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return json_decode($response, true); } } // 使用示例 $nagad = new NagadPayment([ 'merchant_id' => 'YOUR_MERCHANT_ID', 'private_key_path' => './keys/private_key.pem', 'sandbox' => true ]); $result = $nagad->createPayment([ 'merchant_phone' => '01XXXXXXXXX', 'amount' => 100.50, 'order_id' => 'ORDER_001', 'product_name' => '测试商品', 'callback_url' => 'https://yoursite.com/nagad/callback' ]); if ($result['status'] === 'Success') { header('Location: ' . $result['redirectGatewayURL']); } else { echo '支付创建失败: ' . $result['message']; } ?>

🔒 安全配置要点

1. RSA密钥管理

bash
# 生成2048位RSA密钥对
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem

# 设置安全权限 chmod 600 private_key.pem
chmod 644 public_key.pem

2. IP白名单配置

javascript
// Nagad官方IP段 const NAGAD_IPS = [ '103.205.128.0/24', '103.205.129.0/24', '202.51.181.0/24' ]; // 验证回调IP function validateCallbackIP(clientIP) { return NAGAD_IPS.some(ip => isIPInRange(clientIP, ip)); }

3. 签名验证

javascript
// 验证回调签名 function verifyCallback(callbackData, receivedSignature) { const expectedSignature = generateSignature(callbackData); return expectedSignature === receivedSignature; } // 处理回调
app.post('/nagad/callback', (req, res) => { const signature = req.headers['x-km-signature']; if (!verifyCallback(req.body, signature)) { return res.status(400).json({ error: 'Invalid signature' }); } // 处理支付结果... });

❓ 常见问题解决

错误码说明

错误码 含义 解决方案
100 请求格式错误 检查JSON格式和必需参数
102 数字签名无效 检查私钥和签名算法
103 商户凭证无效 验证商户ID和密钥
200 余额不足 提醒客户充值
300 系统内部错误 稍后重试或联系技术支持

常见问题

Q: 如何获得测试环境凭证? A: 联系Nagad技术支持或我们的客服 @zfxt01

Q: 支付成功但未收到回调怎么办? A: 使用支付查询接口主动查询订单状态

Q: 签名验证总是失败? A: 检查数据排序、JSON格式和RSA密钥是否正确

Q: 生产环境如何切换? A: 更改baseUrl并使用正式商户凭证

技术支持

如果遇到集成问题,可通过以下方式获得帮助:


本教程涵盖了Nagad支付集成的核心要点,帮助开发者快速接入孟加拉国主流支付方式。如需更详细的技术支持,请联系我们的专业团队。

Share This Story, Choose Your Platform!