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 中实现支付宝支付的主要内容,如果未能解决你的问题,请参考以下文章

Egg 中实现微信支付

Egg 中实现微信支付

TP5 中实现支付宝支付 利用model层调用支付宝类库

uni-app中实现微信|支付宝支付

如何在 chrome 扩展中实现支付

如何在 ASP.NET 中实现支付网关 [关闭]