>위챗 애플릿 >미니 프로그램 개발 >WeChat Mini 프로그램 결제 간단한 예시 및 주의사항

WeChat Mini 프로그램 결제 간단한 예시 및 주의사항

高洛峰
高洛峰원래의
2017-01-10 09:59:122456검색

WeChat 미니 프로그램 결제

WeChat 미니 프로그램 결제는 WeChat 공식 계정 결제와 유사하지만, WeChat의 통합 주문 인터페이스만 호출하면 됩니다. prepay_id 이후 WeChat 결제를 호출할 수 있습니다.

오늘은 일반 노드의 결제 인터페이스를 요약해 보겠습니다! ! !

먼저 통합 주문 인터페이스를 호출하려면 몇 가지 정보를 알아야 합니다.

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, &#39;61.50.221.43&#39;, total_fee, &#39;JSAPI&#39;) + "</sign>"
  formData += "</xml>"
  var self = this
  request({ 
   url: url, 
   method: &#39;POST&#39;, 
   body: formData 
  }, function(err, response, body) { 
   if (!err && response.statusCode == 200) { 
    var prepay_id = self.getXMLNodeValue(&#39;prepay_id&#39;, body.toString("utf-8")) 
    var tmp = prepay_id.split(&#39;[&#39;) 
    var tmp1 = tmp[2].split(&#39;]&#39;) 
    //签名 
    var _paySignjs = self.paysignjs(appid, nonce_str, &#39;prepay_id=&#39; + tmp1[0], &#39;MD5&#39;, 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 애플릿의 유일한 매개변수는 키 결제를 위한 비밀번호입니다. 나머지 매개변수는 주문 정보와 가격입니다. Promise를 사용하려면 q 모듈을 입력해야 합니다. 이는 사람마다 다르며 필요에 따라 설정할 수 있습니다. . https://api.mch.weixin.qq.com/pay/unifiedorder 인터페이스를 요청해야 합니다

참고: 여기서 전달하는 양식 데이터는 json 대신 xml입니다

그런 다음 서명 메서드가 필요합니다. 여기서는 두 가지 메서드를 캡슐화해야 합니다. 하나는 통합 주문 인터페이스를 호출하는 데 사용되는 서명 메서드이고, 다른 하나는 결제용 미니 프로그램

통합 주문 인터페이스 서명을 호출하는 데 사용됩니다.

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 + &#39;&key=&#39; + key 
  var crypto = require(&#39;crypto&#39;) 
  var sign = crypto.createHash(&#39;md5&#39;).update(string, &#39;utf8&#39;).digest(&#39;hex&#39;) 
  return sign.toUpperCase()

결제 기호:

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

암호화할 때 json 대신 문자열을 얻으므로 json을 문자열의 경우 코드는 다음과 같습니다.

var keys = Object.keys(args)
  keys = keys.sort()
  var newArgs = {}
  keys.forEach(function(key) {
    newArgs[key] = args[key]
  })
  var string = &#39;&#39;
  for (var k in newArgs) {
    string += &#39;&&#39; + k + &#39;=&#39; + 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]

마지막으로 WeChat 결제에 필요한 모든 매개변수를 얻으려면 이들을 연결하기만 하면 됩니다.

//微信小程序支付封装,暂支持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 = &#39;&#39;
  for (var k in newArgs) {
    string += &#39;&&#39; + k + &#39;=&#39; + 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 + &#39;&key=&#39; + key
  var sign = crypto.createHash(&#39;md5&#39;).update(string, &#39;utf8&#39;).digest(&#39;hex&#39;)
  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(&#39;data--->&#39;, data, 123123)
    res.json(data)
   })
 },

그런 다음 미니 프로그램에서 이 인터페이스만 호출하면 모든 지불금을 받게 됩니다. 정보를 제공한 후 WeChat을 통해 결제할 수 있습니다.

다음은 미니 프로그램 결제의 몇 가지 함정입니다.

1. 통합 주문 인터페이스는 xml이며(미니 프로그램뿐만 아니라 공식 계정에도 해당) 반환 값은 다음과 같습니다. 또한 xml 형식이며 prepay_id를 직접 가져와야 합니다.

2. 서명 알고리즘이 키를 가져와야 하며 최종적으로 더 큰 값으로 변환해야 합니다

3. WeChat 결제의 서명 알고리즘도 appid를 가져와야 합니다(이것은 비과학적이고 깊은 구덩이입니다)

4. 서명 알고리즘은 json을 사용하여 키를 연결해서는 안 됩니다

읽어주셔서 감사합니다. 모든 사람에게 도움이 되기를 바랍니다. 이 사이트를 지원해 주셔서 감사합니다!

더 많은 WeChat 애플릿 결제 간단한 예시와 주의사항은 PHP 중국어 홈페이지를 참고해주세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.