前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序支付

微信小程序支付

作者头像
4O4
发布2022-04-25 17:27:52
1.2K0
发布2022-04-25 17:27:52
举报
文章被收录于专栏:404404

微信小程序支付

  1. 首先申请微信支付商户号并关联微信小程序
  1. 准备订单参数
代码语言:javascript
复制
// Order.js 架构
const mongoose = require('mongoose');

const Order = new mongoose.Schema({
  openid: {             // 用户唯一标识
    type: String
  },
  prepay_id: {          // 预支付会话标识
    type: String
  },
  out_trade_no: {       // 商户订单号
    type: String
  },
  transaction_id: {     // 微信订单号
    type: String
  },
  status: {             // 订单状态
    type: Number
  },
  goods: [{             // 商品信息
    good_id: {
      type: Number
    },
    title: {
      type: String
    },
    num: {
      type: Number
    },
    price: {
      type: Number
    },
    img: {
      type: String
    }
  }],
  create_time: {         // 订单创建时间
    type: String
  },
  pay_time: {            // 订单支付时间
    type: String
  }
});

module.exports = mongoose.model('Order', Order);
  1. 引入 md5 加密
代码语言:javascript
复制
yarn add md5

const md5 = require('md5')
  1. 准备必要参数,绑定下单事件
代码语言:javascript
复制
data: {
  appid: 'wx080a191278b69c58',
  body: '纵翔商城-购物结算',
  mch_id: '1560000000',
	nonce_str: Math.random().toString(36).slice(-8),
  notify_url: 'https://api.domain.com:3000/pay/callback',
  openid: this.getOpenIdByLocal(),
  out_trade_no: 'wx_' + nonce_str + '_' + String(Math.round(new Date())),
  spbill_create_ip: '47.102.154.110',
  total_fee: 0,
  trade_type: 'JSAPI'
}

<view class="tui-pr25">
  <tui-button type="danger" shape="circle" @click="btnPay">确认支付</tui-button>
</view>
  1. 生成 paySign
代码语言:javascript
复制
/*
* 封装参与签名算法参数ASCII码排序
* https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
*/
const utils = {
	payParamsSort(str) {
		var strArr = str.split('.');
		var newStr = Array.prototype.sort.call(strArr, function(a, b) {
			for (var i = 0; i < a.length; i++) {
				if (a.charCodeAt(i) == b.charCodeAt(i)) continue;
				return a.charCodeAt(i) - b.charCodeAt(i);
			}
		});
		return newStr;
	}
}

module.exports = {
	payParamsSort: utils.payParamsSort
}
  1. 支付流程
代码语言:javascript
复制
// 获取当前用户openid
getOpenIdByLocal() {
  return uni.getStorageSync('uid');
}

// 将订单提交到商户后台
generateOrders(order) {
  uni.request({
    url: this.baseUrl + '/pay/order', //仅为示例,并非真实接口地址。
    method: 'POST',
    data: {
      order: order
    },
    success: (res) => {
      if(res.status === 200 && res.data.msg == 'ok') {
      	console.log('generate order success');
      }
    }
  });
}

// 支付
btnPay() {
  let keyStr = Object.keys(this.obj);
  let a = '';
  keyStr.forEach((k) => {
    a += (k + '.')
  })		
  let sort = payParamsSort(a.substring(0, a.length - 1));			
  let o = {};
  sort.forEach((s) => {
    o[s] = this.obj[s];
  })				
  let stringA = '';			
  Object.keys(o).forEach((key) => {
    stringA += key + '=' + o[key] + '&';
  });
  console.log(stringA.substring(0, stringA.length - 1));		
  const key = this.key;		
  const stringSignTemp = stringA.substring(0, stringA.length - 1) + "&key=" + key;		
  const sign = md5(stringSignTemp).toUpperCase();					
  this.obj.sign = sign;				

  // 统一下单(预支付)
  uni.request({
    method: 'POST',
    url: this.baseUrl + '/pay/unifiedorder',
    data: this.obj,
    header: {
      'Content-Type': 'application/json'
    },
    success: (res) => {
      console.log(res);

      // 生成商户订单
      const order = {};
      order.openid = this.getOpenIdByLocal();
      order.prepay_id = res.data.result.xml.prepay_id;
      order.out_trade_no = this.obj.out_trade_no;
      order.transaction_id = '';
      order.status = 1;
      order.goods = [];
      order.create_time = String(Math.round(new Date() / 1000));
      order.pay_time = '';
      this.generateOrders(order);

      // 申请支付
      const payObj = {
        appId: 'wx080a191278b69c58',
        timeStamp: String(Math.round(new Date() / 1000)),
        nonceStr: 'zephyr',
        package: 'prepay_id=' + res.data.result.xml.prepay_id,
        signType: 'MD5',
      };
      let keyStr2 = Object.keys(payObj);
      let a = '';
      keyStr2.forEach((k) => {
        a += (k + '.')
      })	
      let sort = payParamsSort(a.substring(0, a.length - 1));		
      let o = {};	
      sort.forEach((s) => {
        o[s] = payObj[s];
      })			
      let stringA = '';
      Object.keys(o).forEach((key) => {
        stringA += key + '=' + o[key] + '&';
      });
      const key = this.key;
      const stringSignTemp = stringA.substring(0, stringA.length - 1) + "&key=" + key; //注:key为商户平台设置的密钥key
      const sign = md5(stringSignTemp).toUpperCase();

      // 小程序调起支付API
      wx.requestPayment({
        'timeStamp': payObj.timeStamp,
        'nonceStr': payObj.nonceStr,
        'package': payObj.package,
        'signType': payObj.signType,
        'paySign': sign,
        'success':function (res) {
          console.log(res);
        },
        'fail':function (res) {
          console.log(res);
        },
        'complete':function (res) {
          console.log(res);
        }
      })
    },
    fail: (err) => {
      console.log(err);
    }
  });
}
  1. 预支付时将订单信息提交到商户后台
代码语言:javascript
复制
// 新增order
async addOrder(ctx, next) {
  const orderItem = new Order(ctx.request.body.order);
  try {
    const res = await orderItem.save();
    ctx.body = {
      code: 1,
      msg: 'ok',
      result: res
    }
  } catch (err) {
    console.log(err);
    ctx.body = {
      code: 0,
      msg: err.message || '服务器错误'
    }
  }
}
  1. 测试支付

订单通知、查询订单、退款等功能开发中...

DONE !

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 微信小程序支付
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档