微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取prepay_id之后我们在调用微信的支付即可。

今天我们来封装一般node的支付接口!!!

首先调用统一下单接口我们需要知道一些信息

var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp()var deferred = Q.defer()  var appid = config.appId  var nonce_str = this.createNonceStr()  var timeStamp = this.createTimeStamp()  var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"  var formData = "<xml>"  formData += "<appid>" + appid + "</appid>" //appid  formData += "<attach>" + attach + "</attach>" //附加数据  formData += "<body>" + body + "</body>"  formData += "<mch_id>" + mch_id + "</mch_id>" //商户号  formData += "<nonce_str>" + nonce_str + "</nonce_str>" //随机字符串,不长于32位。  formData += "<notify_url>" + notify_url + "</notify_url>"  formData += "<openid>" + openid + "</openid>"  formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"  formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"  formData += "<total_fee>" + total_fee + "</total_fee>"  formData += "<trade_type>JSAPI</trade_type>"  formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"  formData += "</xml>"  var self = thisrequest({  url: url,  method: 'POST',  body: formData  }, function(err, response, body) {  if (!err && response.statusCode == 200) {  var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8")) var tmp = prepay_id.split('[')  var tmp1 = tmp[2].split(']')  //签名  var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp)  var args = {  appId: appid,  timeStamp: timeStamp,  nonceStr: nonce_str,  signType: "MD5",  package: tmp1[0],  paySign: _paySignjs  }deferred.resolve(args)  } else {  console.log(body)  } })  return deferred.promise  

这个是一个统一下单接口的代码,我们需要appid小程序公众号id,mch_id商户号id,openid小程序的唯一标实,key支付用的密码,剩下的参数都是订单的信息和价格之类的,本人require进q模块使用promise,这个因人而异,可以根据自己需要来。我们需要请求https://api.mch.weixin.qq.com/pay/unifiedorder接口

注意:这里我们传递的formdata是一个xml而不是json

然后我们需要签名方法,这里我们需要封装两个方法,一个是签名方法调用统一下单接口会用到,另一个是调用小程序支付用到

统一下单接口sign:

var ret = {  appid: appid,  attach: attach,  body: body,  mch_id: mch_id,  nonce_str: nonce_str,  notify_url: notify_url,  openid: openid,  out_trade_no: out_trade_no,  spbill_create_ip: spbill_create_ip,  total_fee: total_fee,  trade_type: trade_type  }  var string = this.raw(ret)  string = string + '&key=' + key  var crypto = require('crypto')  var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  return sign.toUpperCase() 

支付sign:

var ret = {  appId: appid,  nonceStr: nonceStr,  package: package,  signType: signType,  timeStamp: timeStamp  }  var string = this.raw(ret)  string = string + '&key=' + key  var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  return sign.toUpperCase()  

注意加密的时候我们获取的是string而不是一个json,所以我们需要吧json转换成string,代码如下:

var keys = Object.keys(args)  keys = keys.sort()  var newArgs = {}  keys.forEach(function(key) {  newArgs[key] = args[key]  })  var string = ''  for (var k in newArgs) {  string += '&' + k + '=' + newArgs[k]  }  string = string.substr(1)  return string  

统一下单接口返回的是带有prepay_id的xml,所以我们需要一个方法进行解析,代码如下:

var tmp = xml.split("<" + node_name + ">")  var _tmp = tmp[1].split("</" + node_name + ">")  return _tmp[0]  

最后我们只需要把这些连接到一起就是可以获取所有微信支付所需参数,代码如下:

//微信小程序支付封装,暂支持md5加密,不支持sha1
/**
***create order by jianchep 2016/11/22     **/
var config = require('../config/weapp.js')
var Q = require("q")
var request = require("request")
var crypto = require('crypto')
var ejs = require('ejs')
var fs = require('fs')
var key = config.key
module.exports = {// 获取prepay_id
  getXMLNodeValue: function(node_name, xml) {  var tmp = xml.split("<" + node_name + ">")  var _tmp = tmp[1].split("</" + node_name + ">")  return _tmp[0]  },// object-->string
  raw: function(args) {  var keys = Object.keys(args)  keys = keys.sort()  var newArgs = {}  keys.forEach(function(key) {  newArgs[key] = args[key]  })  var string = ''  for (var k in newArgs) {  string += '&' + k + '=' + newArgs[k]  }  string = string.substr(1)  return string  },  // 随机字符串产生函数
  createNonceStr: function() {  return Math.random().toString(36).substr(2, 15)  },  // 时间戳产生函数
  createTimeStamp: function() {  return parseInt(new Date().getTime() / 1000) + ''  },// 支付md5加密获取sign
  paysignjs: function(appid, nonceStr, package, signType, timeStamp) {  var ret = {  appId: appid,  nonceStr: nonceStr,  package: package,  signType: signType,  timeStamp: timeStamp  }  var string = this.raw(ret)  string = string + '&key=' + key  var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  return sign.toUpperCase()  },// 统一下单接口加密获取sign
  paysignjsapi: function(appid, attach, body, mch_id, nonce_str, notify_url, openid, out_trade_no, spbill_create_ip, total_fee, trade_type) {  var ret = {  appid: appid,  attach: attach,  body: body,  mch_id: mch_id,  nonce_str: nonce_str,  notify_url: notify_url,  openid: openid,  out_trade_no: out_trade_no,  spbill_create_ip: spbill_create_ip,  total_fee: total_fee,  trade_type: trade_type  }  var string = this.raw(ret)  string = string + '&key=' + key  var crypto = require('crypto')  var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  return sign.toUpperCase()  },// 下单接口
  order: function(attach, body, mch_id, openid, total_fee, notify_url) {var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp()var deferred = Q.defer()  var appid = config.appId  var nonce_str = this.createNonceStr()  var timeStamp = this.createTimeStamp()  var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"  var formData = "<xml>"  formData += "<appid>" + appid + "</appid>" //appid  formData += "<attach>" + attach + "</attach>" //附加数据  formData += "<body>" + body + "</body>"  formData += "<mch_id>" + mch_id + "</mch_id>" //商户号  formData += "<nonce_str>" + nonce_str + "</nonce_str>" //随机字符串,不长于32位。  formData += "<notify_url>" + notify_url + "</notify_url>"  formData += "<openid>" + openid + "</openid>"  formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"  formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"  formData += "<total_fee>" + total_fee + "</total_fee>"  formData += "<trade_type>JSAPI</trade_type>"  formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"  formData += "</xml>"  var self = thisrequest({  url: url,  method: 'POST',  body: formData  }, function(err, response, body) {  if (!err && response.statusCode == 200) {  var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8")) var tmp = prepay_id.split('[')  var tmp1 = tmp[2].split(']')  //签名  var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp)  var args = {  appId: appid,  timeStamp: timeStamp,  nonceStr: nonce_str,  signType: "MD5",  package: tmp1[0],  paySign: _paySignjs  }deferred.resolve(args)  } else {  console.log(body)  } })  return deferred.promise  }
}

之后我们封装下单接口:

unifiedorder: function (req, res) {var body = "测试支付"  var openid = "openid"var total_fee = 1var notify_url = "http://localhost/notify"var mch_id = config.shopIdvar attach = "测试"  wxpay.order(attach, body, mch_id, openid, total_fee, notify_url).then(function(data){  console.log('data--->', data, 123123)res.json(data)})  },

然后我们只需要在小程序里面调用这个接口,就会获取到所有的支付需要信息,再掉微信支付即可。

这里说几个小程序支付的坑:

1.统一下单接口是xml(这个不只是小程序,公众号也是),返回值也是xml格式需要自己获取prepay_id,

2.签名算法要带上key,最后要转换成大些

3.微信支付的sign算法也要带上appid(这个不科学,深坑)

4.签名算法一定不要用json拼接key

转载于:https://www.cnblogs.com/jcscript/p/6126722.html

微信小程序篇(微信小程序的支付)相关推荐

  1. 第 7 节:前端面试指南 — 微信小程序篇(附面试题答案)

    这周很多读者朋友都在「微信小程序」的视频了. 前 6 期没看的同学,建议先看完再来看这一期的,传送门: 第 1 期:「简历篇」含简历模板文件 第 2 期:「HTML篇」含面试题&答案 第 3 ...

  2. 从0开发《工程测绘大师》小程序之什么是微信小程序篇(一)

    我们今天来讲讲如何从0开发<工程测绘大师>小程序之什么是微信小程序篇.先来说说什么是微信小程序,什么是微信小程序?为什么会有微信小程序诞生?它到底解决了什么痛点?与传统的网页开发和APP相 ...

  3. 多平台多渠道账号体系绑定第一篇-微信小程序篇

    先奉上本篇实现效果 多平台多渠道账号体系绑定第一篇-微信小程序篇 近来,在对接三方平台时,欲将多方开放平台统一整合入笔者的框架内. 如下为大致思路设计图 由于需对接多方平台关联账号体系,思来之后,将设 ...

  4. 微信小程序篇】四. 案例:根据单号查询快递编号

    快递查询(2020-1-7亲测) 项目准备 创建项目demo4-expressQuery(因为练习取过这个名所以案例里面是demo-expressQuery ) 操作步骤同demo3 不过second ...

  5. 基于EMQX云服务器的环境调节系统(微信小程序篇)

    前面我们已经完成了服务器的部署以及硬件数据上云,现在是应用程序篇,微信小程序连接EMQX,我这个是根据官网给的demo进行改造升级的 在微信小程序中打造mqtt连接测试工具 根据这篇文章说微信小程序如 ...

  6. 视频教程-30小时微信小程序从入门到精通课程-基础篇-微信开发

    30小时微信小程序从入门到精通课程-基础篇 8年IT开发经验,6年IT教育经验,喜欢把复杂逻辑用简单的表述传达给学生,传授编程知识,讲述生活故事 曹圣捷 ¥12.00 立即订阅 扫码下载「CSDN程序 ...

  7. 视频教程-微信小程序开发教程(第1篇)-微信开发

    微信小程序开发教程(第1篇) 微信企业号星级会员.10多年软件从业经历,国家级软件项目负责人,主要从事软件研发.软件企业员工技能培训.已经取得计算机技术与软件资格考试(软考)--"信息系统项 ...

  8. 入门微信小程序[第六篇]微信小程序 -- 大樱桃的安排

    经过一番努力,我的直接上司"大樱桃"终于满意了并且交给了我第一个小程序项目. 小乖猴助手 老沙很高兴,终于可以实际的编码了,对于一个100%的码农来说,这是何等的愉悦. 这是一个家 ...

  9. 【微信小程序】微信小程序基础知识篇

    开发文档 小程序简介 | 微信开放文档 1.微信小程序的环境准备 1.1注册账号 1.2获取APPID 是开发者唯一的身份认证,应用要发布要上线必须提供APPID 1.3开发工具 由于微信小程序自带开 ...

最新文章

  1. 递归/回溯:Combination Sum II数组之和
  2. 两台电脑之间用网线之间传文件
  3. Petalinux 2018.2 for Xilinx
  4. web测试点总结---UI、兼容、功能、交互、安全、性能、接口测试
  5. 元类编程--property动态属性
  6. FNV哈希算法【转】
  7. 爬虫基本功之学点JS(一)
  8. c语言数组元素前移后移,如何将一个数组的元素循环左移?
  9. python 将图像变为矢量图(可字符和序列化)
  10. 端口扫描工具是什么?端口扫描工具有什么用
  11. jnhs中国的省市县区邮编坐标mysql数据表
  12. HEVC函数入门(22)——变换量化
  13. 以下是两段c语言代码 函数arith(),第二章习题-ddg.doc
  14. 适合所有手环的app_Redmi Watch体验:手环终结者?
  15. 论文笔记 Object-Aware Instance Labeling for Weakly Supervised Object Detection - ICCV 2019
  16. DoT/DoH/DoQ 之 CoreDNS配置
  17. ECharts之类型3D(map,bar3D,scatter3D)
  18. web-前端之后台管理系统模板首页
  19. 你可以跑不赢刘翔,但一定要跑赢CPI
  20. 1631 小鲨鱼在51nod小学 暴力

热门文章

  1. 32位地址的寻址方式
  2. smarty模板引擎_6-Smarty的内置函数
  3. 使用hibernate自动生成数据库表
  4. 实现DFS之“骨头的诱惑”
  5. golang中的对称加密
  6. golang中小数除以大数为0的坑
  7. 深入理解阻塞socket和非阻塞socket
  8. 常考数据结构与算法:最小的k个数
  9. linux:配置jdk环境变量
  10. c一:指针引用(int * p )和指针(int * q)的区别