微信支付方案梳理

663 阅读8分钟

开发微信支付功能,涉及三种支付方式:

  • JSAPI 支付:微信内网页支付,需要开通微信服务号
  • 小程序支付:在小程序中支付,需要开通小程序
  • H5 支付:在手机浏览器(非微信网页)中网页支付

使用微信支付的前提必开通微信商户号,要使用到那种的支付方式要前需在商户平台开通(要审核)。

支付的钱最终都会到商户号里(一般由公司财务开通)。

// JSAPI支付和H5支付是微信支付中的两种支付方式,二者都是基于微信支付开放平台所提供的API接口实现的。不同的是,JSAPI支付适用于微信公众账号和微信小程序中支付,而H5支付则适用于微信外的移动端网页中支付。

JSAPI支付需要用户在微信公众账号或微信小程序中进行支付,用户需要先关注公众账号或小程序,然后在公众账号或小程序中进行支付操作。商户需要在代码中实现微信提供的JSAPI接口,通过网页调起微信支付的弹窗进行支付,并回调商家后台确认支付结果。JSAPI支付支持的支付方式包括微信支付、银行卡支付、支付宝红包等。

H5支付则是指用户在移动端网页中进行支付,不需要在微信公众号或小程序中进行操作。用户在商家的移动端页面上选择商品或服务后,可以直接通过微信支付的弹窗进行支付。商户需要在代码中实现微信提供的H5支付接口,并在微信商户平台中完成相关配置和授权。H5支付支持的支付方式包括微信支付、信用卡支付、银行卡支付、VISA、MasterCard、JCB等。

在实现方面,H5支付相比JSAPI支付更加简单,因为H5支付只需要在代码中实现微信提供的H5支付接口即可。而JSAPI支付则需要在商家的公众号或小程序中与微信服务端进行交互。在适用场景上,H5支付主要是用于移动端网页的支付场景,而JSAPI支付则适用于微信公众号和小程序的支付场景。

总的来说,H5支付和JSAPI支付都是微信支付中的重要支付方式,根据具体的场景和业务需求选择不同的支付方式可以更好地提升用户支付体验和商家的收益。 //

开发微信支付的过程中大大小小坑还是踩了不少,终于做完了,整理下开发流程。

参考:

//# WeixinJSBridge.invoke 、 wx.chooseWXPay(JSAPI支付)

支付方式: 方式一:微信支付【微信公众号】<——点击进入微信公众号官方文档 此支付方式需要在HTML页面中引入JS文件,即【 jweixin-1.6.0.js 】; 此JS文件链接支持http和https两种形式,引用时需要匹配当前项目的请求-响应协议(即http、https); 该JS文件支持使用AMD/CMD标准模块加载方式加载。

let WeChatPay = function() { // 2、引入js后、获取公众号校验信息 let timestamp = '', nonceStr = '', signature = ''; let v = { // 用于换取微信校验信息的参数:要求不可以包含 “#” 号 url: location.split('#')[0] };

// 3、通过config接口注入权限验证配置(需要同步进行,在获取到校验信息后方可注入config,否则校验失败!)
wx.config({
	debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
	appId: '', // 必填,公众号的唯一标识
	timestamp: , // 必填,生成签名的时间戳
	nonceStr: '', // 必填,生成签名的随机串
	signature: '', // 必填,签名
	jsApiList: ["checkJsApi", "chooseWXPay", "updateAppMessageShareData", "updateTimelineShareData"] // 必填,需要使用的JS接口列表
});

axios.post('/wx/pay/orderPay_XXXX', data).then(res => {
	// 支付成功状态
	if (res.code == 200) {
		// 获取支付必备的参数
		let {
			nonceStr,
			package,
			signType,
			paySign
		} = res.data;
		// 4、通过ready接口处理成功验证
		wx.ready(function() {
			/* 微信支付 */
			wx.chooseWXPay({
				timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
				nonceStr: nonceStr, // 支付签名随机串,不长于 32 位
				package: package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
				signType: signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
				paySign: paySign, // 支付签名
				success: function(res) {
					// 前端判断返回方式,微信团队郑重提示:不保证绝对可靠,切记!
					if (res.errMsg == 'chooseWXPay:ok') {
						// 【支付成功】 
					} else if (res.errMsg == 'chooseWXPay:cancel') {
						// 【支付取消】:用户取消支付不会进入这个判断,而是进入complate和cancel函数
					} else {

					}
				},
				complete: function(res) {
					// 接口调用完成时执行的回调函数,无论成功或失败都会执行
					if (res.errMsg == 'chooseWXPay:ok') {
						// 【支付成功】:支付成功提示页面,点击完成按钮之后
						wx.closeWindow(); /* 关闭微信窗口,调用时需要在config中进行校验 */
					} else if (res.errMsg == 'chooseWXPay:cancel') {
						// 【支付取消】
					} else {

					}
					/**
					 * iOS和Android支付成功点击“完成”后都会进入success和complete函数,都返回'chooseWXPay:ok'
					 * (也有人说Android支付成功不进入success函数,)
					 * 原因是【iOS和Android返回数据不同。支付成功后Android返回 {"errMsg":"getBrandWCPayRequest:ok"},iOS返回{"err_Info":"success","errMsg":"chooseWXPay:ok"},故Android找不到success方法,导致失败】
					 * */
				},
				fail: function(err) {
					// 接口调用失败
				},
				cancel: function(err) {
					// 用户点击取消时的回调函数:用户取消支付后实际上进入cancel 和 complate函数
				}
			});
		});
	}
}).catch(err => {
	console.log('支付失败:', err);
});

} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 接口说明:【不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。】

success:接口调用成功时执行的回调函数。 fail:接口调用失败时执行的回调函数。 complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。 cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。 trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。 方式二:微信支付【 JSAPI 支付】(常用支付方式) function onBridgeReady() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": "appId", //公众号名称,由商户传入
"timeStamp": "timeStamp", //时间戳,自1970年以来的秒数
"nonceStr": "nonceStr", //随机串
"package": "package", "signType": "MD5", //微信签名方式:
"paySign": "paySign" //微信签名 }, function(res) { // 支付成功 if (res.err_msg == "get_brand_wcpay_request:ok") { // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } // 支付过程中用户取消 if (res.err_msg == "get_brand_wcpay_request:cancel") {

		}
		// 支付失败
		if (res.err_msg == "get_brand_wcpay_request:fail") {

		}
		/**
		 * 其它
		 * 1、请检查预支付会话标识prepay_id是否已失效
		 * 2、请求的appid与下单接口的appid是否一致
		 * */
		if (res.err_msg == "调用支付JSAPI缺少参数:total_fee") {

		}
	});

} // 检测支付环境中的 WeixinJSBridge if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } } else { onBridgeReady(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 JSAPI调起支付注意事项: 在微信浏览器里打开H5网页中执行JS调起支付; WeixinJSBridge是微信浏览器内置对象,在其他浏览器中无效; 调用支付传递的参数注意区分大小写。

WeixinJSBridge.invoke 、 wx.chooseWXPay 的区别 WeixinJSBridge.invoke()出现的版本更早 无需引用jssdk 无需wx.config方法注入 需要参数appId 使用回调 有详细的说明 而wx.choosewxpay()出现的版本比较晚 需要jssdk注入 不需要参数appId 使用回调 只有SUCCESS 和 FAIL没有具体的说明 WeixinJSBridge.invoke()是微信浏览器的内置方法 其实wx.choosewxpay()在引用的微信jssdk文件中 也调用了WeixinJSBridge.invoke() 是对WeixinJSBridge.invoke() 的再次封装 综上所诉 这是微信前后设计的不同方法的支付 还是weixinjsbridge更方便一些 有具体的失败回调

备注: pay.weixin.qq.com/wiki/doc/ap… ————————————————