实战教学:用Node.js对接孟加拉支付网关

I

# 实战教学:用Node.js对接孟加拉支付网关

1. 准备工作

在开始对接前,你需要:

1. 注册一个孟加拉支付网关的商户账户(如bKash、Nagad等)
2. 获取API文档和认证凭证(通常包括merchantID、username、password等)
3. Node.js开发环境(建议v14+)

2. 基础项目设置

“`bash
mkdir bangladesh-payment-gateway
cd bangladesh-payment-gateway
npm init -y
npm install express axios dotenv body-parser cors
“`

创建基本文件结构:
“`
├── .env # 环境变量配置
├── config/ # API配置目录
│ └── paymentConfig.js
├── controllers/ # API控制器
│ └── paymentController.js
├── routes/ # API路由
│ └── paymentRoutes.js
└── app.js # Express主应用文件
“`

3. bKash支付网关集成示例

(1) .env配置文件

“`ini
BKASH_MERCHANT_ID=your_merchant_id
BKASH_USERNAME=your_api_username
BKASH_PASSWORD=your_api_password
BKASH_BASE_URL=https://checkout.sandbox.bka.sh/v1.2.0-beta/
APP_PORT=3000
CALLBACK_URL=http://localhost:3000/callback/bkash
“`

(2) Payment Config (config/paymentConfig.js)

“`javascript
require(‘dotenv’).config();

module.exports = {
bkashConfig: {
merchantID: process.env.BKASH_MERCHANT_ID,
username: process.env.BKASH_USERNAME,
password: process.env.BKASH_PASSWORD,
baseURL: process.env.BKASH_BASE_URL,
callbackURL: process.env.CALLBACK_URL,
}
}
“`

(3) Controller实现 (controllers/paymentController.js)

“`javascript
const axios = require(‘axios’);
const { bkashConfig } = require(‘../config/paymentConfig’);

// bKash认证获取token(重要)
async function getBkAuthToken() {
try {
const response = await axios.post(`${bkashConfig.baseURL}checkout/token/grant`, {
app_key: bkashConfig.username,
app_secret: bkashConfig.password
}, {
headers : { ‘Content-Type’: ‘application/json’ }
});

return response.data.id_token;

} catch(error) {
console.error(“bKish auth error:”, error.response?.data);
throw new Error(“Failed to authenticate with bKaish”);
}
}

// Create Payment Request(核心方法)
async function createPayment(req, res) {

const { amount, orderID } = req.body;

if(!amount || !orderID){
return res.status(400).json({error:”Amount and Order ID are required”});
}

try{
// Step1:获取访问令牌
const token = await getBkAuthToken();

// Step2:调用创建付款API
const payload={
mode : “0011”, // Sandbox模式代码
payerReference : orderID.toString(),
callbackURL : bkashCallbackUrl,
amount : parseFloat(amount).toFixed(2),
currency:”BDT”,
intent:”sale”,
merchantInvoiceNumber:`INV-${Date.now()}`
};

const headers={
Authorization:`Bearer ${token}`,
‘X-App-Key’:bkashiUsername ,
Accept:’application/json’,
‘Content-Type’:’application/json’
};

const response=await axios.post(
`${bkashiBaseUrl}/checkout/create`,
payload ,
{headers}
);

if(response.data && response.data.bkashiURL){
return res.json({
checkoutUrl :response.data.bkashiURL ,
status:”REDIRECT”
});
}

}catch(err){
console.error(“[PAYMENT ERROR]”,err.response?.data||err.message);
return res.status(500).json({error:”Payment processing failed”});
}
}

// Callback处理函数
function handleCallback(req ,res ){
/*验证回调签名并更新订单状态*/

console.log(“Received callback:”,req.query);

// TODO:实际项目中需要验证交易状态是否成功完成

if(req.query.status === “success”){
return res.send(“”);

}else{

return rs.status400.send(“

Verification failed!

“);

}}).catch(err=>…);

module.exports={…,verifyPaymenSttus };
“`

前端集成示例(React)

““jsx
// PaymentButton.jsx组件示例

import React from’react’;

export default function PaymentButton({gateway}){

async function initiatePayment(){

try{

let apiEndpoint=”/api/”+(gateway===”nagd”?”nagdad”:”bkaish”)+”/create”;

const response=fetch(aipEndpoit,{
method:’POST’,
headers:{‘Content-Type’:’application/json’},
body:JSON.stringify({
amout:totalCartAmount,
oderiD:curentOrder.id })
});

if(!response.ok)throw new Error();

const data=aait response.json();

if(data.checkoutUrL){

window.open(data.checkoutUrL,”_blank”,”width=500,hight600″);

window.addEventListener(“message”,e=>{
if(e.data==”PAYMENT_SUCCESS”)
refeshOrderStatus();
},false);

}} catch(e){ alert(“启动失败!”)}}

return