使⽤alipay-sdk-nodejs 让node 应⽤接⼊⽀付宝付款
1. 开发构思我们的总体需求是让 node js 应⽤接⼊⽀付宝,完成⽤户付款,具体流程是:当⽤户在商户应⽤点击付款后,页⾯跳转到⽀付宝界⾯,这时会出现两种情况:⼿机⽤户唤醒⽀付宝应⽤PC 唤醒⽀付宝收银台⽤户在⽀付宝页⾯进⾏付款,并完成付款⽀付宝检测⽤户完成付款后向商户应⽤发送⼀个 POST 请求作为⽀付完成的异步回调商户应⽤对回调信息进⾏验证后,对订单状态进⾏变更
⽤户返回商户应⽤,刷新订单界⾯,显⽰该订单已⽀付
2. 前期准备
我们以 Koa 为例,简单演⽰⼀下接⼊⽀付宝的具体流程,⾸先安装 Koa 本体以及所需的中间件:
之后需要安装阿⾥官⽅提供的 nodejs 端的⽀付宝 sdk:
当所有的开发依赖准备完成之后,我们可以直接申请应⽤,同时也可以到⽀付宝开放平台上使⽤ 来模拟真实应⽤。在此我们以沙箱环境进⾏开发演⽰,在沙箱界⾯需要记住 APPID:
同时点击下⽅的 RSA2 密钥,并下载密钥⽣成⼯具,分别⽣成私钥和公钥。我们要将⽣成的 应⽤私钥 记录下来,存放到 private-key.pem ⽂件中;之后再将 “应⽤公钥” 填写到页⾯中,从⽽会⽣成⼀个 ⽀付宝公钥 ,记录该公钥到 public-key.pem ⽂件中,前期准备⼯作完成。如果还不清楚以上流程,参考 。
npm install koa koa-router koa-static koa-bodyparser -S
npm install alipay-node-sdk -S
我们来整理⼀下⽂件,将密钥⽂件整理在⼀起,这样前期准备⼯作就完成了:
3. 部署应⽤
3.1 alipay-node-sdk 的使⽤
当⽤户点击付款信按钮,会触发我们服务器上的⼀个路由条件,在这个路由中,我们的服务器主动向⽀付宝服务器发送了⼀个请求,请求中携带着该条⽀付的信息(如订单号、商品价格等),同时还携带了私钥信息,当⽀付宝服务器收到该条请求后,会向我们的服务器返回⼀个付款 url,我们的服务器再将该条 url 信息转发到前端页⾯上,由前端页⾯完成跳转逻辑。⽽使⽤ alipay-node-sdk 就简化了我们的服务器向⽀付宝服务器发送请求信息的这⼀过程,它会将必要的参数与加密信息处理好,我们只需要传⼊业务参数就可以了。
构建 Sdk 实例当我们引⼊ alipay-node-sdk 时⾸先要对其进⾏实例化以及全局参数的设置:()
<() ⽅法可以帮我们简便的发送⼀个业务请求,在 中我们可以查看到所有的业务请求列表,我们以发送⼀个 为例:
这是 alipay-sdk-nodejs 官⽅提供的演⽰ demo 这就引出了我们接下来需要⽤到的两个接⼝::⽤于返回⼿机端的⽀付唤起地址:⽤于返回 PC 端的⽀付宝收银台地址
.├── package .json
├── package -lock .json
├── serve .js // 主服务
└── static
├── index .html // 客户端
└── pem // 密钥存放⽂件夹
├── private -key .pem
└── public -key .
pem const AlipaySdk = require ('alipay-sdk').default ;
const alipaySdk = new AlipaySdk ({
appId : '2016**********710', // 之前我们所记录的沙箱环境的 sdk
privateKey : fs .readFileSync ('./static/pem/private-key.pem', 'ascii'), // 传⼊私钥
gateway : "openapi.alipaydev/gateway.do" // 沙箱环境的请求⽹关与正式环境不⼀样,需要在此更改,如果是使⽤正式环境则去掉此处的设置 });const
result = await alipaySdk .exec ('ade.close', {
notifyUrl : 'notify_url',
appAuthToken : '',
// 通过 bizContent 传递请求参数
bizContent : {
tradeNo : '',
outTradeNo : '',
operatorId : '',
},
});
// 从官⽅⽂档看到,result 包含 tradeNo 、outTradeNo 2 个 key
console .log ('tradeNo: %s, outTradeNo: %s', result .tradeNo , result .outTradeNo );
AlipayFormData.addField()
如果我们按照上述的⽅式去请求 ade.wap.pay 以及 ade.page.pay 两个接⼝的话是会
返回错误信息的。因为这两个接⼝属于页⾯类接⼝,页⾯类接⼝默认返回的数据为 html 代码⽚段。这类接⼝我们需要创建⼀个 FormData 去请求,⽽不能直接使⽤() 传⼊业务参数。Sdk 提供了⼀个 AlipayFormData 可以⽅便我们的创建,这⾥我们以 ade.page.pay 接⼝为⽰例:
在这⾥要特别注意,⽀付宝在⽤户付款完成后,会向我们的服务器发送⼀条 POST ⽅式 的异步回调,这个回调地址必须是外⽹可以访问到的,也就是说这⼀过程我们必须在线上开发。
3.2 Demo
介绍完了alipay-node-sdk 的使⽤,那么接下来就上⼀个完整的⽰例进⾏整体的演⽰,由于上⾯已经演⽰了如何请求
注意项⽬必须在线上开发!否则只会跳转到⽀付宝界⾯⽽接收不到⽀付宝的异步回调!
整体⽬录:serve.js
/
/ TypeScript // import AlipayFormData from 'alipay-sdk/lib/form';
// js const AlipayFormData = require ('alipay-sdk/lib/form').default
const formData = new AlipayFormData ();
// 调⽤ setMethod 并传⼊ get
,会返回可以跳转到⽀付页⾯的 url ,否则返回的是⼀个表单的 html ⽚段
formData .setMethod ('get');
formData .
addField ('notifyUrl', 'www/notify'); // 当⽀付完成后,⽀付宝主动向我们的服务器发送回调的地址
formData .addField ('returnUrl', 'www/return'); // 当⽀付完成后,当前页⾯跳转的地址
formData .addField ('bizContent', {
outTradeNo : 'out_trade_no',
productCode : 'FAST_INSTANT_TRADE_PAY',
totalAmount : '0.01',
subject : '商品',
body : '商品详情',
});
const result = await alipaySdk .exec (
'ade.page.pay',
{},
{ formData : formData },
);
// result 为可以跳转到⽀付链接的 url
console .log (result );
├── package.json
├── package-lock.json
├── serve.js
└── static
├── index.html
└── pem
├── private-key.pem
└── public-key.pem
const Koa = require ('koa')
const Koa =require('koa')
const Router =require('koa-router')
const static=require('koa-static')
const path =require('path')
const fs =require('fs')
const AlipaySdk =require('alipay-sdk').default;
const AlipayFormData =require('alipay-sdk/lib/form').default
const bodyParser =require('koa-bodyparser')
const app =new Koa()
const router =new Router()
const staticPath ='./static'
app.use(static(
path.join(__dirname, staticPath)
))
app.use(bodyParser())
<('/pay',async(ctx, next)=>{
const alipaySdk =new AlipaySdk({
appId:'20161*******6710',
privateKey: fs.readFileSync('./static/pem/private-key.pem','ascii'),
gateway:"openapi.alipaydev/gateway.do"
});
const formData =new AlipayFormData()
formData.setMethod("get")义乌进货网
formData.addField("notifyUrl","online_serve_url/paycallback")// 回调地址必须为当前服务的线上地址! formData.addField("returnUrl","online_serve_url/success")
formData.addField("bizContent",{
body:"测试商品",
subject:"⼥装",
亲子关系证明怎么开赚钱好方法outTradeNo:new Date().valueOf(),
totalAmount:"88.88",
quitUrl:"www.taobao/product/113714.html",
productCode:"QUICK_WAP_WAY"
})
const result =("ade.wap.pay",{},{
formData: formData,
validateSign:true
})
ctx.body = result
})
男艺人服兵役死亡router.post('/paycallback',async(ctx, next)=>{
let postData = quest.body;
console.log("触发付款");
ade_status ==="TRADE_SUCCESS"){
let data = quest.body // 订单信息张超爱情公寓
// ========= 由请求体内的订单信息,在这⾥进⾏数据库中订单状态的更改 ============
怎么改家里的wifi密码console.log("⽀付完成!");
}
})
<('/success',async(ctx, next)=>{
ctx.body ="⽀付成功"
})
app.utes())
app.listen(9090)
index.html:PS:接收到⽀付宝的异步回调之后,还需要进⾏异步回调的验签,以保证回调是由⽀付宝发送的,这个⽬前还没有研究出来,等研究
出来再更新吧。<!DOCTYPE html>
<html lang ="zh-CN ">
<head >
<meta charset ="UTF-8">
<meta name ="viewport " content ="width=device-width, initial-scale=1.0">
<meta http-equiv ="X-UA-Compatible " content ="ie=edge ">
<title >Document </title >
<script src ="cdn.bootcss/axios/0.19.0-beta.1/axios.min.js "></script >
<script src ="gw.alipayobjects/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js "></script >
<script >
window .onload = function () {
let oPay = document .querySelector ("#pay")
oPay .addEventListener ('click', function () {
axios .get ('47.106.226.190:9090/pay').then (res => {
window .open (res .data );
})
})
}
</script >
</head >
<body >
<button id ="pay ">创建付款</button >
<div id ="form "></div >
</body >
</html >
发布评论