企业付款到零钱文档;https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2

1,搞微信支付,先看流程图

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3,先看流程图,看懂,再看微信支付api

2.调用统一下单接口

const router = new Router()
const uuid = require('uuid')

router.post('wxpay', async (ctx, next) => {
//1.根据orderCode查询订单状态和付款金额,此处省略

const order = { //参数一定要按照acil码(也就是a,b,c,d)顺序来写,或者你需要按照acil码自己排序,否则会在支付时报签名错误
appid: '在微信中的应用appid,也在商户平台中',
body: '迪士尼',
mch_id: '微信平台中的商户编号',
nonce_str: (uuid.v4()).replace(/-/g, ''),
notify_url: '要回调的ulr,一定要是外网可访问的',
out_trade_no: orderInfo[0].orderCode,
spbill_create_ip: ctx.request.ip.replace(/::ffff:/g, ''),
total_fee: 1, //先1分钱
trade_type: 'APP' 
}
const objStr = objTostring(order)
const preSign = objStr + 'key=微信商户平台的key'
order.sign = endeurl.md5(preSign).toUpperCase()
const xml = objToXml(order)

//调用统一下单接口

const data = await request.postAsync({
url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
body: xml
})
const result = await parseStringAsync(data.body)

if (result.xml.result_code[0] == 'FAIL') {
throw {
message: 'orderStatus wrong'
}
}
//字符串必需按照顺序来
const paysign2 = {
appid: result.xml.appid[0],
noncestr: result.xml.nonce_str[0],
package: 'Sign=WXPay',
partnerid: result.xml.mch_id[0],
prepayid: result.xml.prepay_id[0],
timestamp: parseInt(Date.now() / 1000).toString() //注意:时间必需为秒
}
const payPrestr = objTostring(paysign2) + 'key=微信商户平台的key' //不知道的话,可以问老板
paysign2.sign = endeurl.md5(payPrestr).toUpperCase()

//二次签名,返回给app即可,由app端进行微信支付吊起
ctx.body = {
paysign2
}
})

3.工具类

const xml2js = require('xml2js')
const Parser = new xml2js.Parser()
exports.parseStringAsync = xml => {
return new Promise((resolve, reject) => {
Parser.parseString(xml, (err, result) => {
if (err) {
reject(err)
} else {
resolve(result)
}
})
})
}
exports.objTostring = obj => {
var preSign = '';
for (let key in obj) {
preSign += `${key}=${obj[key]}&`
}
return preSign
}

exports.objToXml = obj => {
let xml = '<xml>'
for (let key in obj) {
xml += `<${key}>${obj[key]}</${key}>`
}
xml += '</xml>'
return xml
}

3.微信回调你在第二步是的notify_url值

router.post('wxNotify', async (ctx, next) => {

//获取微信返回的参数值,查询订单状态

const data = ctx.params
var payQuery = {
appid: data.xml.appid[0],
mch_id: data.xml.mch_id[0],
nonce_str: data.xml.nonce_str[0],
out_trade_no: data.xml.out_trade_no[0],
transaction_id: data.xml.transaction_id[0]
}
let payQueryString = objTostring(payQuery) + 'key=微信商户平台的key'
payQuery.sign = endeurl.md5(payQueryString).toUpperCase()
//查询订单是否支付成功
const data1 = await request.postAsync({
url: 'https://api.mch.weixin.qq.com/pay/orderquery',
body: services.pay.objToXml(payQuery)
})

const result = await parseStringAsync(data1.body)

if (result.xml.return_code[0] && result.xml.return_code[0] == 'SUCCESS' && result.xml.trade_state[0] == 'SUCCESS' ) {

//告诉微信,你收到支付结果通知了

const resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" +

"<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "
ctx.body = {
resXml
}

//从result中比较价格和你订单中的金额是否一致,,进行后台业务处理,此处省略

})

总结:

1.参数一定要按照acil码(也就是a,b,c,d)顺序来写,或者你需要按照acil码自己排序(Object.keys(json)),否则会在支付时报签名错误

2.时间戳单位为秒,北京时间,别玩坏了,国外时间不能在国内不能玩

3.如果在支付时,报签名错误,先检查参数是否排序/参数值正确,如果还不行,请重置商户平台的key,再者不行,给微信支付技术支持发邮件,人家会在2小时内回复的

4.node微信app支付,就是以上代码两部分,剩下的就是app的事了

二、补充微信小程序支付统一下单,回调和app支付一致,不再重复

router.post('xcxPay', async (ctx, next) => {
//1.根据orderCode查询订单状态和付款金额
const userId = ctx.user.userid
const orderInfo = await model.order.find({
'orderStatus.status': {
$in: [1, 9]
}
}, {
_id: 0,
orderCode: 1,
transCode: 1,
orderProducts: 1,
siteId: 1,
virtualProducts: 1,
CNYCharge: 1
})
if (!orderInfo || orderInfo.length < 1) {
throw {
status: 20001,
message: 'paying orderInfo not exists',
router: ctx._url
}
log(222, '订单状态错误', orderInfo)
return
}
const userOpenId = await model.user.findOne({
_id: userId
}, {
_id: 0,
openIds: 1
})
if (!userOpenId || (userOpenId && !userOpenId.openIds && !userOpenId.openIds.wcx)) {
throw {
status: 20001,
message: 'wcx openid is not find !',
router: ctx._url
}
return
}
let amount = orderInfo[0].CNYCharge

//字符串必需按照顺序来,比app支付参数稍有不同
const order = {
appid: '小程序appid',
body: '糖葫芦',
mch_id: '商户号',
nonce_str: (uuid.v4()).replace(/-/g, ''),
notify_url: `${config.apiUrl}/notify_url`,
openid: userOpenId && userOpenId.openIds && userOpenId.openIds.wcx || '', //小程序支付必须
out_trade_no: orderInfo[0].orderCode,
spbill_create_ip: ctx.request.ip.replace(/::ffff:/g, ''),
total_fee: Number(amount) * 100,
trade_type: 'JSAPI' //小程序支付必须
}
const objStr = services.pay.objTostring(order)
const preSign = objStr + 'key=商户平台key'
order.sign = endeurl.md5(preSign).toUpperCase()
const xml = services.pay.objToXml(order)
const data = await request.postAsync({
url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
body: xml
})
const result = await services.pay.parseStringAsync(data.body)
if (result.xml.result_code[0] == 'FAIL') {
throw {
message: 'orderStatus wrong'
}
}

const paysign2 = {
appId: result.xml.appid[0],
nonceStr: result.xml.nonce_str[0],
package: `prepay_id=${result.xml.prepay_id[0]}`,
signType: 'MD5',
timeStamp: parseInt(Date.now() / 1000).toString()
}
const payPrestr = services.pay.objTostring(paysign2) + 'key=商户平台key,同app支付'
paysign2.paySign = md5(payPrestr).toUpperCase()
ctx.body = {
paysign2
}
})

nodejs+koa2微信app支付,小程序支付的更多相关文章

  1. 微信支付之扫码、APP、小程序支付接入详解

    做电商平台的小伙伴都知道,支付服务是必不可少的一部分,今天我们开始就说说支付服务的接入及实现.目前在国内,几乎90%中小公司的支付系统都离不开微信支付和支付宝支付.那么大家要思考了,为什么微信支付和支 ...

  2. 微信h5支付/jsapi支付/小程序支付

    一. 介绍------------------------------------------------------------------ 微信支付官方开发文档:  https://pay.wei ...

  3. 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  4. Java实现微信小程序支付(完整版)

    在开发微信小程序支付的功能前,我们先熟悉下微信小程序支付的业务流程图: 不熟悉流程的建议还是仔细阅读微信官方的开发者文档. 一,准备工作 事先需要申请企业版小程序,并开通“微信支付”(即商户功能).并 ...

  5. uni-app - 支付(app支付、小程序支付、h5(微信端)支付)

    App支付.小程序支付.h5(微信端)支付 APP支付(内置) appPay.js /** * 5+App支付,仅支持支付宝以及微信支付 * * 支付宝Sdk集成,微信sdk未集成 * * @para ...

  6. 微信小程序支付步骤

    http://blog.csdn.net/wangsf789/article/details/53419781 最近开发微信小程序进入到支付阶段,一直以来从事App开发,所以支付流程还是熟记于心的.但 ...

  7. Java 后端微信小程序支付demo (网上说的坑里面基本上都有)

    Java 后端微信小程序支付 一.遇到的问题 1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试 2.签名错误 3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候 ...

  8. php对接微信小程序支付

    前言:这里我就假装你已经注册了微信小程序,并且基本的配置都已经好了.注: 个人注册小程序不支持微信支付,所以我还是假装你是企业或者个体工商户的微信小程序,其他的商户号注册,二者绑定,授权,支付开通,就 ...

  9. 微信小程序支付接入注意点

    一.微信支付后台服务器部署 服务器采用ubuntu16.04 + php7.0 + apache2.0. 微信支付后台服务使用了curl 和 samplexml ,因此php.ini配置中必须开启这两 ...

随机推荐

  1. sass基础—属性嵌套以及跳出嵌套 @at-root

    /*注意:定义的变量若是没有使用则不会编译到css文件中.*//*1)sass的局部变量*/$font:14px;//定义$font:12px !default; //没有default时是重新赋值, ...

  2. Appium 如何模拟按键

    from appium.webdriver import Remote driver.keyevent(4) python中点击返回键是这样写的 附录 keycode 电话键 KEYCODE_CALL ...

  3. 火狐浏览器无故卡死,未响应或者占大量cpu资源解决方案

    这是火狐社区的文章,对火狐浏览器无故卡死,未响应或者占大量cpu资源有详细的说明和解决,记录下!!! ++++++++++++++++++++++++++++++++ Firefox 挂起 如果您的 ...

  4. windows解压.tar00文件

    通常是单个文件太大分拆出来的,例如data.tar00, data.tar01, data.tar02等 cmd命令行进入几个tar0x文件所在目录,执行: copy /b data.tar0* da ...

  5. MySQL应用异常问题解决

    MySQL错误:Every derived table must have its own alias 派生表都必须有自己的别名 一般在多表查询时,会出现此错误. 因为,进行嵌套查询的时候子查询出来的 ...

  6. $_FILES["file"]["error"]是错误代码

    $_FILES["file"]["error"]是错误代码,0表示没有错误,下面几种对应不同的错误1 : 上传的文件超过了 php.ini 中 upload_m ...

  7. sdoi2017苹果树

    题解: 非常奇妙的一题.. 没有免费操作我都不会$nk$....考试打个暴力就可以走人了 树上有依赖背包问题的正确做法是(为啥我之前学的不是这样的啊) 按照后续遍历做背包 做到一个点的时候 枚举它选不 ...

  8. Nginx配置多个基于域名的虚拟主机+实验环境搭建+测试

    标签:Linux 域名 Nginx 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://xpleaf.blog.51cto.com/9 ...

  9. js,JQuery 生成二维码

    代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  10. 51Nod 部分题目 の 口胡&一句话题解

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod-One-Sentence.html 51Nod1404 先列出式子,然后搞成一个组合数.然后 luca ...