前言:node对接支付宝沙箱的心得,express,koa2都能使用。

支付宝沙箱位置在:支付宝开放平台控制台>开发工具推荐> 沙箱

后端部分(express/koa2)

引入alipay-sdk

npm install alipay-sdk -S
// alipay.js
const AlipaySdk = require("alipay-sdk").default;

const alipaySdk = new AlipaySdk({
    // AppId
    appId: "",
    // 签名算法
    signType: "RSA2",
    // 支付宝网关
    gateway: "",
    // 支付宝公钥
    alipayPublicKey:"",
    // 应用私钥
    privateKey:"",
});
module.exports = alipaySdk;

获取AppId

在这里插入图片描述

获取支付宝网关

在这里插入图片描述

  • 支付宝公钥
    在这里插入图片描述
    没有的话可以选择使用系统默认秘钥生成,也可以选择自定义秘钥生成
    自定义秘钥:
    1)下载秘钥工具
    通用工具>支付宝开放平台秘钥工具>秘钥工具下载
    在这里插入图片描述
    2)打开秘钥工具,生成秘钥(公钥和私钥)
    在这里插入图片描述
    3)生成支付宝公钥
    将生成的秘钥中的应用公钥复制到 开放平台>沙箱应用>接口加密方式
    在这里插入图片描述
  • 应用私钥
    将生成的应用私钥格式转换
    在这里插入图片描述

具体使用:发起支付

// router.js

// 引入支付宝配置文件
const alipaySdk = require("alipay.js存放路径");
const AlipayFormData = require('alipay-sdk/lib/form').default;

router.post('/api/payment',function(req,res,next){
    //订单号
    let orderId = req.body.orderId;
    //商品总价
    let price = req.body.price;
    //购买商品的名称
    let name = req.body.name;
    // 开始对接支付宝API
    const formData = new AlipayFormData();
    //调用setMethod 并传入get,会返回可以跳转到支付页面的url,
    formData.setMethod("get");
    // 支付时信息
    const bizContent = {
        out_trade_no: orderId, //订单号
        product_code: "FAST_INSTANT_TRADE_PAY",
        total_amount: price, //总价格
        subject: name, //商品名称
        body: "商品详情", //商品描述
    };
    formData.addField("bizContent", bizContent);

    //支付成功或失败的返回链接(前端页面)
    formData.addField("returnUrl", "http://localhost:8080/payment");

    // 返回promise
    const result = alipaySdk.exec(
        // "alipay.trade.page.pay",
        "alipay.trade.wap.pay", 
        {},
        { formData: formData }
    ).catch(error => console.error('caught error!', error));

    //对接支付宝成功,支付宝返回的数据
    result.then((resp) => {
        res.send({
            data: {
                code: 200,
                success: true,
                msg: "支付中",
                paymentUrl: resp,
            },
        });
    });
})

具体API前往官网查看

在这里插入图片描述

类型方法
pc网页支付alipay.trade.page.pay
手机网站支付接口2.0alipay.trade.wap.pay
统一收单交易关闭接口alipay.trade.close
统一收单交易查询alipay.trade.query

formData.setMethod(“get”)为返回链接,没有就是以表单形式。

发起支付后需要查看该订单支付状态,使用同一收单交易查询

// router.js

// 引入axios
const axios = require("axios");

//支付交易查询
router.post('/api/paymentQuery', function (req, res, next) {
  //订单号
  let out_trade_no = req.body.out_trade_no;
  let trade_no = req.body.trade_no;
  // 支付宝配置
  const formData = new AlipayFormData();
  //调用setMethod 并传入get,会返回可以跳转到支付页面的url,
  formData.setMethod("get");
  // 支付时信息
  const bizContent = {
    out_trade_no,
    trade_no
  };
  formData.addField("bizContent", bizContent);

  // 返回promise
  const result = alipaySdk.exec(
    "alipay.trade.query",
    {},
    { formData: formData }
  ).catch(error => console.error('caught error!', error));
  //对接支付宝API
  result.then(resData => {
    axios({
      method: "GET",
      url: resData
    }).then(resdata => {
      let respondeCode = resdata.data.alipay_trade_query_response;
      if (respondeCode.code == 10000) {
        switch (respondeCode.trade_status) {
          case 'WAIT_BUYER_PAY':
            res.send({
              code: 10001,
              message: "支付宝有交易记录,没付款"
            })
            break;
          case 'TRADE_FINISHED':
            // 完成交易的逻辑
            res.send({
              code: 10002,
              message: "交易完成(交易结束,不可退款)"
            })
            break;
          case 'TRADE_SUCCESS':
           // 完成交易的逻辑
            res.send({
              code: 10002,
              message: "交易完成"
            })
            break;
          case 'TRADE_CLOSED':
            // 交易关闭的逻辑
            res.send({
              code: 10003,
              message: "交易关闭"
            })
            break;
        }
      } else if (respondeCode.code == 40004) {
        return res.send({
          code: 40004,
          message: "交易不存在"
        })
      }
    }).catch(err => {
      return res.send({
        code: 50000,
        msg: "交易失败",
        data: err
      })
    })
  })
})

前端部分

// payment.vue

created() {
    this.getPayData();
  },
  methods: {
    getPayData() {
      let data = {
        out_trade_no: this.$route.query.out_trade_no,
        trade_no: this.$route.query.trade_no,
      };
      axios({
        url: "/api/paymentQuery",
        method: "post",
        Headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        // qs:增加安全性的序列化
        data: qs.stringify(data),
      }).then((res) => {
        // 逻辑
      });
    },
  },

运行截图

  • 支付宝移动网站支付
    在这里插入图片描述
  • pc网站支付
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/c8025911bbe94f1f84cba24419a64290.png

账号密码为沙箱账号的买方信息

在这里插入图片描述

  • 扫码支付
    使用的是沙箱工具>支付宝客户端沙箱版
    在这里插入图片描述
    使用账号密码登录,账号密码为买方信息。
    登录成功后可以使用扫码支付

可能遇到问题

  1. [Warning] page interface through formdata is deprecated. Use sdk.pageExec instead
    caught error! Error: error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag。
    1)应用私钥没有转换格式
    2)支付宝公钥/应用私钥等信息错了
    在这里插入图片描述
  2. 沙箱账号没有充值按钮
    解决:回退旧版本
  3. 支付宝客户端沙箱版无法登录
    解决(我成功的例子,对于其他人可能不成功):使用uc浏览器下载。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐