评论

传统原生支付用云开发实现(非云支付)

云开发实现小程序支付。 有用记得点赞哦。

本文的代码已过时,请勿照抄。建议改用云支付。

本文的代码被论坛自动过滤了所有XML的标签,所以照抄是会出错的。需要代码的话,看以前的老版本:

https://developers.weixin.qq.com/community/develop/doc/000620ec5acb482103b7bf41d51804?jumpto=comment&commentid=000ea67d7b4da8d6c47acd1e05b8


代码前提:只需要替换两个与自己相关的参数key和mch_id

1、小程序开通微信支付成功,去公众平台(https://mp.weixin.qq.com/);

成功后可以知道自己的mch_id,即商户号。

2、去这里:商户平台(https://pay.weixin.qq.com/),获取key = API密钥,如果是退款的话,还需要下载API证书。

以下代码仅包含统一下单,以及小程序端拉起支付的代码。

小程序端:

  testWxCloudPay: function () {
    wx.cloud.callFunction({
      name: 'getPay',
      // data: {body:"body",attach:"attach",total_fee:1}, // 可传入相关参数。
      success: res => {
        console.log(res.result)
        if (!res.result.appId) return
        wx.requestPayment({
          ...res.result,
          success: res => {
            console.log(res)
          }
        })
      }
    })
  },

云函数getPay:

const key = "ABC...XYZ" //换成你的商户key,32位
const mch_id = "1413092000" //换成你的商户号

//以下全部照抄即可
const cloud = require('wx-server-sdk')
const rp = require('request-promise')
const crypto = require('crypto')
cloud.init()

function getSign(args) {
  let sa = []
  for (let k in args) sa.push(k + '=' + args[k])
  sa.push('key=' + key)
  return crypto.createHash('md5').update(sa.join('&'), 'utf8').digest('hex').toUpperCase()
}

function getXml(args) {
  let sa = []
  for (let k in args) sa.push('<' + k + '>' + args[k] + '')
  sa.push('' + getSign(args) + '')
  return '' + sa.join('') + ''
}

exports.main = async(event, context) => {
  const wxContext = cloud.getWXContext()
  const appId = appid = wxContext.APPID
  const openid = wxContext.OPENID
  const attach = 'attach'
  const body = 'body'
  const total_fee = 1
  const notify_url = "https://mysite.com/notify"
  const spbill_create_ip = "118.89.40.200"
  const nonceStr = nonce_str = Math.random().toString(36).substr(2, 15)
  const timeStamp = parseInt(Date.now() / 1000) + ''
  const out_trade_no = "otn" + nonce_str + timeStamp
  const trade_type = "JSAPI"
  const xmlArgs = {
    appid,
    openid,
    attach,
    body,
    mch_id,
    nonce_str,
    notify_url,
    out_trade_no,
    spbill_create_ip,
    total_fee,
    trade_type
  }
  let xml = (await rp({
    url: "https://api.mch.weixin.qq.com/pay/unifiedorder",
    method: 'POST',
    body: getXml(xmlArgs)
  })).toString("utf-8")
  if (xml.indexOf('prepay_id') < 0) return xml
  let prepay_id = xml.split("")[0]
  let payArgs = {
    appId,
    nonceStr,
    package: ('prepay_id=' + prepay_id),
    signType: 'MD5',
    timeStamp
  }
  return { 
    ...payArgs,
    paySign: getSign(payArgs)
  }
}

packge.json:

{
  "name": "getPay",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "zfe",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "latest",
    "crypto": "^1.0.1",
    "request-promise": "^4.2.2"
  }
}

附:完整代码片段:如果你觉得在这上面花的时间超过一天了,就去下载代码片段吧。

最后一次编辑于  2020-10-20  
点赞 15
收藏
评论

24 个评论

  • 张
    2020-04-16

    正好用到,试试,先谢过。

    2020-04-16
    赞同
    回复
  • 阿乐
    阿乐
    2020-03-18

    参数都核对过了。总是提示这个。

    2020-03-18
    赞同
    回复 10
    • 老张
      老张
      2020-03-18
      没法判断,自己log出来慢慢对比。
      2020-03-18
      回复
    • 阿乐
      阿乐
      2020-03-19回复老张
      KEY重新设置后可以了。
      2020-03-19
      回复
    • 老张
      老张
      2020-03-19回复阿乐
      代码有用记得点赞。
      2020-03-19
      1
      回复
    • 小明James
      小明James
      2020-03-20
      一样的错误,重新设置KEY后就可以了,之前是自动生成的32位KEY,不知道和这个有没有关系
      2020-03-20
      回复
    • 袁述~
      袁述~
      2020-04-14
      一样的错误,真的要去重新设置key才行吗?
      2020-04-14
      回复
    查看更多(5)
  • 阿乐
    阿乐
    2020-03-18

    总是提示签名失败

    2020-03-18
    赞同
    回复 3
    • 想的枯燥生活
      想的枯燥生活
      2020-04-14
      啊啊啊请问最后怎么解决的呀
      2020-04-14
      回复
    • 劉囍朙
      劉囍朙
      2020-05-07
      请问怎么解决的呢
      2020-05-07
      回复
    • 木叶随风落
      木叶随风落
      2020-06-11
      更换位置就好了
      2020-06-11
      回复
  • moonsam®
    moonsam®
    2020-03-17

    error message Cannot find module 'wx-server-sdk' 怎么一直报这个错误....

    2020-03-17
    赞同
    回复 1
    • 老张
      老张
      2020-03-17
      你是第一个云函数就来拷贝我的代码啊,步太大,扯着蛋了。先自己写一个云函数。
      2020-03-17
      回复
  • 龙马
    龙马
    2020-03-10
    老张,怎么样可以联系到你呢,我把你这个代码拿过去,点击支付,没什么反应,也不报错,现在不知道问题在哪,支付已经开通,商户号和key都是自己的,就是没反应,能帮我分析下问题吗
    2020-03-10
    赞同
    回复 4
    • 龙马
      龙马
      2020-03-10
      那个key必须大写才可以吗
      2020-03-10
      回复
    • 老张
      老张
      2020-03-10回复龙马
      只能自己添加断点调试呗。至少会调试代码吧?
      2020-03-10
      回复
    • 老张
      老张
      2020-03-10回复龙马
      代码拷贝过程中出错了,已改正了,你再试试。
      2020-03-10
      回复
    • 龙马
      龙马
      2020-03-11回复老张
      好的,谢谢
      2020-03-11
      回复
  • Blingbiubiubiu~
    Blingbiubiubiu~
    2020-02-22

    老张可以合作下支付吗

    2020-02-22
    赞同
    回复 1
    • 老张
      老张
      2020-02-22
      怎么合作?
      2020-02-22
      回复
  • 龙马(上海龙亳健康科技)
    龙马(上海龙亳健康科技)
    2020-02-19

    请问这个付款金额是1吗,还是小程序支付界面输入的金额

    2020-02-19
    赞同
    回复 5
  • 初晨
    初晨
    2020-01-12

    有没有轮询查微信支付结果的案例云函数的。。

    2020-01-12
    赞同
    回复 5
    • 老张
      老张
      2020-01-13
      这个自己写吧,简单。
      2020-01-13
      回复
    • 初晨
      初晨
      2020-01-13回复老张
      可是有个问题是云函数超时时间最多100秒,你轮训的时长最多也就100秒。但是用户如果100秒内没有支付咋整?110秒却支付了,我问一下,这样子。咋处理?
      2020-01-13
      1
      回复
    • 老张
      老张
      2020-01-14回复初晨
      可以设个定时器云函数。
      2020-01-14
      1
      回复
    • 初晨
      初晨
      2020-01-14回复老张
      定时器函数?我上面说的就是定时器啊,你不会说的是那个触发器那玩意把?那玩意停不了,只能手动在开发工具停
      2020-01-14
      回复
    • 老张
      老张
      2020-01-14回复初晨
      也是。那就写在小程序端,反正支付也是在小程序端发起,支付完成后轮询几次查账单。
      2020-01-14
      1
      回复
  • 关家宝
    关家宝
    2019-12-14

    云开发怎么做退款呀

    2019-12-14
    赞同
    回复 1
    • 老张
      老张
      2019-12-15
      还没碰到,回头研究。
      2019-12-15
      回复
  • 罗梅光
    罗梅光
    2019-12-13

    厉害,就是 notify_url 需要自己服务器没啥解决方法。

    2019-12-13
    赞同
    回复 7
    • 初晨
      初晨
      2020-01-12
      最可怕的还是云函数里计时器轮询都搞不定,
      2020-01-12
      回复
    • 罗梅光
      罗梅光
      2020-01-13
      notify_url 已经搞定,随便填就可以。
      2020-01-13
      回复
    • 罗梅光
      罗梅光
      2020-01-13回复初晨
      轮询?定时器吗?
      2020-01-13
      回复
    • 拎包哥
      拎包哥
      2020-03-16回复罗梅光
      请问notify_url是一个不存在的网址也可以吗
      2020-03-16
      回复
    • 罗梅光
      罗梅光
      2020-03-17回复拎包哥
      可以
      2020-03-17
      回复
    查看更多(2)

正在加载...

登录 后发表内容