• node+vue.js实现支付宝支付(沙箱)完整版,亲测可用


    有写到,记录下支付宝支付的实现

    demo 请狠狠的戳这里 ¥  https://download.lllomh.com/cliect/#/product/J302659722615829

    微信支付请看这里  https://www.cnblogs.com/lllomh/p/14523711.html

    沙箱环境 (Beta) 是协助开发者进行接口功能开发及主要功能联调的辅助环境,模拟了开放平台部分产品的主要功能和主要逻辑。可用于在产品上线前了解环境、组合和调试各种接口。

    沙箱环境配置

    打开 支付宝开发者中心 并登录,点击 => 进入我的控制台(也可能登录之后自动进入), 不需要企业账户,个人的也可以

    1.jpg

    在开发者中心中点击开发服务下的研发服务,就进入沙箱环境页面了,

    2.jpg

    在沙箱应用可以看到基本配置。

    3.jpg

    密钥配置

    点击 RSA2(SHA256)密钥 设置,

    4.jpg

    点击 支付宝密钥生成器,下载对应版本的工具,下载完成后将工具安装在不包含空格的目录中,

    5.jpg

    然后点打开,点击生成密钥,即可生成商户应用私钥与商户应用公钥。然后点击复制公钥。

    8.jpg

    回到沙箱界面,选择公钥,并把刚刚复制的公钥粘贴进去;

    9.jpg

    然后就可以得到支付宝公钥了,代码中会用到。

    10.jpg

    1,封装配置

    alipayUtil.js

    const AlipaySdk = require('alipay-sdk').default; // 引入 SDK
    const alipaySdk =  new  AlipaySdk({
      appId: '2021000117615613', // 开放平台上创建应用时生成的 appId
      signType: 'RSA2', // 签名算法,默认 RSA2
      gateway: 'https://openapi.alipaydev.com/gateway.do', // 支付宝网关地址 ,沙箱环境下使用时需要修改
      alipayPublicKey: '', // 支付宝公钥,需要对结果验签时候必填
      privateKey: '', // 应用私钥字符串
    });
    module.exports = alipaySdk;
    
    //正式环境只要把上述换成正式的就可以了
    

    2,接口定义

    创建支付宝需要的表单表

        const formData = new AlipayFormData();
        formData.setMethod('get');

    把 通知加进去(如需要的话)

     formData.addField('notifyUrl', 'https://www.baidu.com'); // 支付成功回调地址,必须为可以直接访问的地址,不能带参数

    然后就是需要的订单参数

        formData.addField('bizContent', {
            outTradeNo: orderId, // 商户订单号,64个字符以内、可包含字母、数字、下划线,且不能重复
            productCode: 'FAST_INSTANT_TRADE_PAY', // 销售产品码,与支付宝签约的产品码名称,仅支持FAST_INSTANT_TRADE_PAY
            totalAmount: '0.01', // 订单总金额,单位为元,精确到小数点后两位
            subject: '商品', // 订单标题
            body: '商品详情', // 订单描述
    
        });

    后就是 成功回调: 这里我被坑了很久:

      formData.addField('returnUrl', 'https://opendocs.alipay.com');//加在这里才有效果,不是加在bizContent 里面

    最后提交官方,用官网文档的写法:

        const result =  alipaySdk.exec(  // result 为可以跳转到支付链接的 url
            'alipay.trade.page.pay', // 统一收单下单并支付页面接口
            {}, // api 请求的参数(包含“公共请求参数”和“业务参数”)
            { formData: formData },
        );

    订单查询(可用可不用):

    /**
     * 添加购物车提交订单支付宝支付后查询订单状态是否成功 */
    router.post('/api/member/queryOrderAlipay', (req, res) => {
      let orderId=req.body.orderId
      const formData = new AlipayFormData();
      formData.setMethod('get');
      formData.addField('bizContent', {
        orderId
      });
      // 通过该接口主动查询订单状态
      const result = alipaySdk.exec(
        'alipay.trade.query',
        {},
        { formData: formData },
      );
      axios({
        method: 'GET',
        url: result
      })
        .then(data => {
          let r = data.data.alipay_trade_query_response;
          if(r.code === '10000') { // 接口调用成功
            switch(r.trade_status) {
              case 'WAIT_BUYER_PAY':
                res.send(
                  {
                    "success": true,
                    "message": "success",
                    "code": 200,
                    "timestamp": (new Date()).getTime(),
                    "result": {
                      "status":0,
                      "massage":'交易创建,等待买家付款'
                    }
                  }
                )
                break;
              case 'TRADE_CLOSED':
                res.send(
                  {
                    "success": true,
                    "message": "success",
                    "code": 200,
                    "timestamp": (new Date()).getTime(),
                    "result": {
                      "status":1,
                      "massage":'未付款交易超时关闭,或支付完成后全额退款'
                    }
                  }
                )
                break;
              case 'TRADE_SUCCESS':
                res.send(
                  {
                    "success": true,
                    "message": "success",
                    "code": 200,
                    "timestamp": (new Date()).getTime(),
                    "result": {
                      "status":2,
                      "massage":'交易支付成功'
                    }
                  }
                )
                break;
              case 'TRADE_FINISHED':
                res.send(
                  {
                    "success": true,
                    "message": "success",
                    "code": 200,
                    "timestamp": (new Date()).getTime(),
                    "result": {
                      "status":3,
                      "massage":'交易结束,不可退款'
                    }
                  }
                )
                break;
            }
          } else if(r.code === '40004') {
            res.send('交易不存在');
          }
        })
        .catch(err => {
          res.json({
            msg: '查询失败',
            err
          });
        });
    
    })

    到这里就完成了,成功返回 支付支付的该地址前端只要拿到跳到这里地址去支付就可以了,成功后跳到回调成功页面

    ​接口演示

    前端直接请求 然后拿到地址:

            goPay() {
                let data = {
                    orderId: 't454545212121' //随机生成唯一的就行了这个 自己找吧
                }
                var instance = this.$axios.create({headers: {'content-type': 'application/x-www-form-urlencoded'}});
                 // 代理到  http://localhost:3000/api/pcpay
                instance.post(`http://localhost:3000/api/pcpay`, this.$qs.stringify(data)).then(res =>{
                    this.data=res;
                    window.open(res.data.result)
                });
    
            }

    最后用沙箱版本app扫码付款可以看到效果

    ​结果demo​​​​​

    希望多多支持,你的评论点赞都是我的动力,有问题可以留言,谢谢网友

  • 相关阅读:
    VS2008开发的MFC程序,静态连接的方法
    [delphi]参数带有默认值的函数
    __cplusplus的用处
    去掉输入法上的CH和EN
    Linux下Socket的简单使用及最简化封装
    VS2008 _CRT_SECURE_NO_WARNINGS 的问题
    VC:对话框中菜单的使用(WM_INITMENUPOPUP)
    VC:CFindReplaceDialog(非模态对话框、IsWindow()、m_fr、GetFindString())
    献给初学编程者
    VC:状态栏(AfxGetMainWnd()、GetDescendantWindow()、SetPaneInfo()、SetPaneText())
  • 原文地址:https://www.cnblogs.com/lllomh/p/14504040.html
Copyright © 2020-2023  润新知