Egg 中实现支付宝支付
Posted aiguangyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Egg 中实现支付宝支付相关的知识,希望对你有一定的参考价值。
1. 接入支付宝应用
1. 必须注册企业支付宝账户,如果已有企业支付宝账户忽略此步骤;
2. 在支付宝开放平台,申请应用、填写名称、上传应用图标,在功能列表中选择或添加想要的支付功能类型;
3. 打开支付宝文档中心,下载对应系统的签名工具,签名工具下载存放电脑上的路径不能有中文和空格。点击RSA签名验签工具,在软件打开的对话框中点击“生成密钥”,此时就会生成商户的应用公钥和应用私钥,并自动生成保存有应用公钥和应用私钥的文件。复制应用公钥到申请的应用中设置应用公钥,设置保存后就会生成一个支付宝公钥;
4. 同意协议,提交审核,大约一个工作日以后就会通过审核。
参考文档:https://opendocs.alipay.com/open/203/107084/
2. 项目中使用支付宝支付
在通过审核的应用中获取app_id、应用私钥、支付宝公钥,以便在开发中使用。
首先配置支付宝支付需要的相关信息,主要涉及到app_id、应用私钥、支付宝公钥、支付成功的跳转地址、支付成功的异步通知地址、配置指定的端口号、忽略CRSF验证。
// config/config.default.js
'use strict';
module.exports = appInfo => {
const config = exports = {};
// 安全验证机制
exports.security = {
csrf: {
// 当支付宝异步通知当前服务器时忽略csrf验证
ignore: ctx => {
if (ctx.request.url == "/aliPay/aliPayNotify") {
return true;
}
return false;
},
}
}
// 支付宝支付的配置
exports.aliPayOptions = {
app_id: '申请的app_id',
appPrivKeyFile: "应用私钥",
alipayPubKeyFile: "支付宝公钥"
}
// 支付宝支付回调地址
exports.aliPayBasicParams={
// 支付成功返回地址
return_url: 'http://xxx.xxx.xx.xx:8000/aliPay/aliPayReturn',
// 支付成功异步通知地址
notify_url:'http://xxx.xxx.xx.xx:8000/aliPay/aliPayNotify'
}
// 配置默认启动的端口
config.cluster = {
listen: {
path: '',
port: 8000,
hostname: '0.0.0.0',
}
};
return config
};
定义支付宝支付相关路由,主要有执行支付的路由、支付成功后的跳转路由、支付成功后的异步通知路由。
// app/router/default.js
'use strict';
module.exports = app => {
const {router,controller } = app;
// 解析XML的中间件
const xmlParseMiddleware = app.middleware.xmlParse();
// 调用支付
router.get('/aliPay/pay',controller.default.aliPay.pay);
// 支付回调
router.get('/aliPay/aliPayReturn',controller.default.aliPay.aliPayReturn);
// 支付通知(关闭CSRF验证)
router.post('/aliPay/aliPayNotify',xmlParseMiddleware, controller.default.aliPay.aliPayNotify);
}
由于支付成功以后,支付宝的服务器会异步通知当前服务器,而传递的数据是XML形式的,所以上面的路由中引入了一个用于XML解析的中间件,以下是此中间件的代码。
// app/middleware/xmlParse.js
// cnpm install koa-xml-body --save
module.exports = require('koa-xml-body');
在控制器中实现上面路由地址中所对应的相关方法。
// app/controller/default/aliPay.js
'use strict';
const Controller = require('egg').Controller;
class AliPayController extends Controller {
// 调用支付
async pay() {
let date = (new Date()).getTime();
// 此处为模拟数据
let data = {
subject: '商品',
out_trade_no: date.toString(),
total_amount: '0.1'
}
let url = await this.service.aliPay.doPay(data);
this.ctx.redirect(url);
}
// 支付回调
async aliPayReturn() {
this.ctx.body = '支付成功';
// 提示支付状态
// 跳转订单页面
}
// 支付通知(必须正式上线)
async aliPayNotify() {
// 接收阿里服务器POST提交的XML数据
let params = this.ctx.request.body;
let result = await this.service.aliPay.aliPayNotify(params);
if (result.code == 0) {
if(params.trade_status == 'TRADE_SUCCESS') {
// 更新订单信息
}
}
}
}
module.exports = AliPayController;
控制器中调用的服务代码实现。
// app/service/aliPay.js
'use strict';
const Service = require('egg').Service;
// cnpm install alipay-mobile --save
// https://github.com/Luncher/alipay
const AliPay = require('alipay-mobile').default
class AliPayService extends Service {
// 执行支付
async doPay(orderData) {
return new Promise((resolve,reject)=>{
// 实例化支付宝支付
let service = new AliPay(this.config.aliPayOptions);
// 获取返回支付地址
let result = service.createPageOrderURL(orderData,this.config.aliPayBasicParams);
resolve(result.data);
});
}
// 异步通知
aliPayNotify(params){
// 实例化支付宝支付
const service = new AliPay(this.config.aliPayOptions);
return service.makeNotifyResponse(params);
}
}
module.exports = AliPayService;
以上是关于Egg 中实现支付宝支付的主要内容,如果未能解决你的问题,请参考以下文章