微信小程序 支付简单实例及注意事项

微信小程序 支付

微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取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 = this
  request({
   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 = this
  request({
   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 = 1
  var notify_url = "http://localhost/notify"
  var mch_id = config.shopId
  var 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

感谢阅读,希望能帮助到大家,谢谢大家对本站 的支持!

(0)

相关推荐

  • 微信小程序 支付功能实现PHP实例详解

    微信小程序 支付功能实现PHP实例详解 前端代码: wx.request({ url: 'https://www.yourhost.com/weixin/WeiActivity/payJoinfee',//改成你自己的链接 header: { 'Content-Type': 'application/x-www-form-urlencoded' }, method:'POST', success: function(res) { console.log(res.data); console.lo

  • 微信小程序-详解微信登陆、微信支付、模板消息

    微信公众平台近日悄然开始内测微信小程序(微信公众号)功能,引来无数开发者和普通用户关注,微信支付的能力,是随着小程序的发布一并推出的,具有介绍如下: wx.login(OBJECT) 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要依赖会话密钥完成. OBJECT参数说明: success返回参数说明: 示例代码: //app.js App({ onLaunch: functio

  • 微信小程序 在线支付功能的实现

    微信小程序 在线支付功能 最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过程如出一辙,下面我就具体说一下小程序里微信支付的开发流程和注意点. 1.开通微信支付和微信商户号 这个过程就和开通服务号的微信支付过程一样,没有什么可以说的. 2.获得用户的openid 首页我们需要在小程序的客户端js中获取当前用户的openid,通过调用wx.login方法可

  • 微信小程序支付之c#后台实现方法

    微信小程序支付c#后台实现 今天为大家带来比较简单的支付后台处理 首先下载官方的c#模板(WxPayAPI),将模板(WxPayAPI)添加到服务器上,然后在WxPayAPI项目目录中添加两个"一般处理程序" (改名为GetOpenid.ashx.pay.ashx) 之后打开business目录下的JsApiPay.cs,在JsApiPay.cs中修改如下两处 然后在GetOpenid.ashx中加入代码如下: public class GetOpenid : IHttpHandler

  • PHP:微信小程序 微信支付服务端集成实例详解及源码下载

    微信小程序 微信支付服务端集 理论上集成微信支付的全部工作可以在小程序端完成,因为小程序js有访问网络的能力,但是为了安全,不暴露敏感key,而且可以使用官方提供的现成php demo更省力,于是在服务端完成签名与发起请求,小程序端只做一个wx.requestPayment(OBJECT)接口的对接. 整体集成过程与JSAPI.APP类似,先统一下单,然后拿返回的结果来请求支付. 一共三步: 1.小程序端通过wx.login的返回的code换取openid 2.服务端向微信统一下单 3.小程序端

  • 微信小程序微信支付接入开发实例详解

    本文主要讲述微信小程序接入微信支付开发过程中遇到的坑,分为两大块,小程序端和后台接口封装.本文主要内容如下: 一.后台接口封装: 二.小程序端整合: 三.总结 一.后台接口封装 本文介绍基于ThinkPHP5进行接口封装,具体步骤如下: 1.微信支付官方文档提供了PHP脚本微信支付的样例,下载下来: 2.样例已经封装好了每个类,我们只需要加上命名空间即可,在TP5的extend目录下新建一个目录wxpay,把样例中的类复制到该目录下,然后加上命名空间即可: 样例改造结果 其中最主要的一个类即Wx

  • 微信小程序 支付功能开发错误总结

    微信小程序 支付功能开发错误总结 微信小程序支付终于踩完坑了,发现里面坑挺大的,现在发个贴,希望以后入坑的同学可以看一下 : https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=2 业务流程在这里大家看文档的时候可以看到.第一个坑,获取用户的openid,参数一定要拼在url连接上,否则会报{"errcode":40013,"errmsg":"invali

  • 微信小程序 支付简单实例及注意事项

    微信小程序 支付 微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取prepay_id之后我们在调用微信的支付即可. 今天我们来封装一般node的支付接口!!! 首先调用统一下单接口我们需要知道一些信息 var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp() var deferred = Q.defer() var appid = conf

  • 微信小程序 购物车简单实例

    微信小程序,这里实现购物车功能的小demo,有需要此功能的朋友可以参考下. 摘要: 加减商品数量,汇总价格,全选与全不选 设计思路: 一.从网络上传入以下Json数据格式的数组 1.购物车id:cid 2.标题title 3.数量num 4.图片地址 5.价格price 6.小计 7.是否选中selected 二.点击复选框toggle操作 如已经选中的,经点击变成未选中,反之而反之 点击依据index作为标识,而不用cid,方便遍历 三.全选操作 首次点击即为全部选中,再次点击为全不选,全选按

  • 微信小程序 canvas开发实例及注意事项

    微信小程序 wxcanvas 测试手机为IPHONE6,开发者工具版本0.10.102800.开发者工具0.11.112301版本也一样 微信小程序里的canvas 非 h5 canvas有很多不一样的地方,以下把微信小程序的canvas叫做wxcanvas 下面全是我一点点测试出的干货,耐心看: 1.wxcanvas,不像h5canvas那样有width和height属性和width和height的style样式.他只有style样式,可以理解为他就是个框吧: 2.wxcanvas不要当成真的

  • 微信小程序 支付后台java实现实例

    微信小程序 支付后台java实现实例 前言: 前些天使用 LeanCloud 云引擎写了个小程序的支付相关 以前只做过 APP 支付 这次在小程序支付爬了两天的坑 把代码也分享出来 支付流程: 1.小程序前端获取微信 openId 以及订单号 传给后台 2,后台根据 openId 和订单号进行签名 post 微信统一下单接口 3.后台获取微信返回的xml字符串 解析 二次签名以后返回给前端 4.前端调起支付微信支付 API 先看支付函数: //获取支付信息 @EngineFunction("ge

  • 微信小程序实现简单手写签名组件的方法实例

    目录 背景: 需求: 效果 一.思路 二.实现 1. 页面与样式 2. 初始化 3. 点击时 4. 签名时 三.总结 背景: 在做项目过程中,需要在微信小程序中实现手写签名组件.在网上找了微信小程序手写签名实现,但是都是不太理想.在实际运用中,会因为实时计算较多的贝塞尔曲线而产生卡顿.效果不理想.所以退一步,不需要笔锋以及笔迹模拟效果.只需要简单的手写签名实现. 需求: 可以实现用户在微信小程序上手写签名. 需要组件化. 效果 一.思路 在微信小程序中,我们使用canvas组件实现.将用户的输入

  • 微信小程序Redux绑定实例详解

    微信小程序Redux绑定实例详解 安装 clone或者下载代码库到本地: git clone https://github.com/charleyw/wechat-weapp-redux 将dist/wechat-weapp-redux.js(或者拷贝minify的也可以)文件直接拷贝到小程序的工程中,例如(下面假设我们把第三方包都安装在libs目录下): cd wechat-weapp-redux cp -r dist/wechat-weapp-redux.js <小程序根目录>/libs

  • 微信小程序实现简单input正则表达式验证功能示例

    本文实例讲述了微信小程序实现简单input正则表达式验证功能.分享给大家供大家参考,具体如下: 1.效果展示 2.关键代码 index.wxml文件 <input placeholder="输入内容" bindinput="check"></input> <view>输入结果:{{result}}</view> index.js文件 Page({ data:{ result:'' }, check:function(e

  • 微信小程序支付及退款流程详解

    首先说明一下,微信小程序支付的主要逻辑集中在后端,前端只需携带支付所需的数据请求后端接口然后根据返回结果做相应成功失败处理即可.我在后端使用的是php,当然在这篇博客里我不打算贴一堆代码来说明支付的具体实现,而主要会侧重于整个支付的流程和一些细节方面的东西.所以使用其他后端语言的朋友有需要也是可以看一下的.很多时候开发的需求和相应问题的解决真的要跳出语言语法层面,去从系统和流程的角度考虑.好的,也不说什么废话了.进入正题. 一. 支付 支付主要分为几个步骤: 前端携带支付需要的数据(商品id,购

随机推荐