0

0

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

高洛峰

高洛峰

发布时间:2017-01-10 09:59:12

|

2746人浏览过

|

来源于php中文网

原创

微信小程序 支付

微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取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 = ""
  formData += "" + appid + "" //appid 
  formData += "" + attach + "" //附加数据 
  formData += "" + body + ""
  formData += "" + mch_id + "" //商户号 
  formData += "" + nonce_str + "" //随机字符串,不长于32位。 
  formData += "" + notify_url + ""
  formData += "" + openid + ""
  formData += "" + bookingNo + ""
  formData += "61.50.221.43"
  formData += "" + total_fee + ""
  formData += "JSAPI"
  formData += "" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + ""
  formData += ""
  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("")
  return _tmp[0]

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

妙话AI
妙话AI

免费生成在抖音、小红书、朋友圈能火的图片

下载
//微信小程序支付封装,暂支持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("")
  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 = ""
  formData += "" + appid + "" //appid
  formData += "" + attach + "" //附加数据
  formData += "" + body + ""
  formData += "" + mch_id + "" //商户号
  formData += "" + nonce_str + "" //随机字符串,不长于32位。
  formData += "" + notify_url + ""
  formData += "" + openid + ""
  formData += "" + bookingNo + ""
  formData += "61.50.221.43"
  formData += "" + total_fee + ""
  formData += "JSAPI"
  formData += "" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + ""
  formData += ""
  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

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

更多微信小程序 支付简单实例及注意事项相关文章请关注PHP中文网!

相关文章

微信app下载
微信app下载

微信是一款手机通信软件,支持通过手机网络发送语音短信、视频、图片和文字。微信可以单聊及群聊,还能根据地理位置找到附近的人,带给大家全新的移动沟通体验,有需要的小伙伴快来保存下载体验吧!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

79

2026.01.09

c++框架学习教程汇总
c++框架学习教程汇总

本专题整合了c++框架学习教程汇总,阅读专题下面的文章了解更多详细内容。

46

2026.01.09

学python好用的网站推荐
学python好用的网站推荐

本专题整合了python学习教程汇总,阅读专题下面的文章了解更多详细内容。

121

2026.01.09

学python网站汇总
学python网站汇总

本专题整合了学python网站汇总,阅读专题下面的文章了解更多详细内容。

12

2026.01.09

python学习网站
python学习网站

本专题整合了python学习相关推荐汇总,阅读专题下面的文章了解更多详细内容。

15

2026.01.09

俄罗斯手机浏览器地址汇总
俄罗斯手机浏览器地址汇总

汇总俄罗斯Yandex手机浏览器官方网址入口,涵盖国际版与俄语版,适配移动端访问,一键直达搜索、地图、新闻等核心服务。

71

2026.01.09

漫蛙稳定版地址大全
漫蛙稳定版地址大全

漫蛙稳定版地址大全汇总最新可用入口,包含漫蛙manwa漫画防走失官网链接,确保用户随时畅读海量正版漫画资源,建议收藏备用,避免因域名变动无法访问。

370

2026.01.09

php学习网站大全
php学习网站大全

精选多个优质PHP入门学习网站,涵盖教程、实战与文档,适合零基础到进阶开发者,助你高效掌握PHP编程。

45

2026.01.09

php网站搭建教程大全
php网站搭建教程大全

本合集专为零基础用户打造,涵盖PHP网站搭建全流程,从环境配置到实战开发,免费、易懂、系统化,助你快速入门建站!

12

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.2万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号