微信JSAPI支付v3流程(uniapp和node版)

一、微信JSAPI支付

请提前准备好接入前的准备文档获取相关的配置数据,否则下面需要的数据你可能会比较懵!
并且需要提前了解微信JSAPI支付文档

二、获取用户openid

获取openid方法例子

三、h5调起支付

1.第一种通过WeixinJSBridge调起微信支付服务

参数获取请看本文JSAPI支付签名

WeixinJSBridge.invoke(
	'getBrandWCPayRequest', 
	{
		appId:'xxxxxxxx',//公众号ID,由商户传入
		timeStamp:'xxxxxxxx',//时间戳,自1970年以来的秒数
		nonceStr:'xxxxxxxx',//随机串
		package:'xxxxxxxx', // 统一支付接口返回的prepay_id参数值
		signType:"RSA",//微信签名方式:
		paySign:'xxxxxxxx',//微信签名
	},
	(res) =>{
		if (res.err_msg == "get_brand_wcpay_request:ok") {
			//支付成功
		}
	}
);

2.第二种通过js-sdk中的wx.chooseWXPay调起微信支付服务

首先需要阅读js-sdk文档,js-sdk文档
通过js-sdk获取支付的能力

npm install weixin-js-sdk

下文中的getJssdk获取请看本文JS-SDK权限签名的方法

import wx from 'weixin-js-sdk';
import {getJssdk} from "@/api/wx.js";
export const setJsSdk = async ()=>{
	let params = {
		url:location.href.split('#')[0]
	}
	//JS-SDK使用权限签名
	let res = await getJssdk(params);
	let data = res.data;
	wx.config({
		debug: false,
		appId: appid, // 必填,公众号的唯一标识
		jsApiList:[
		  'chooseWXPay',//发起微信支付
		],
		timestamp:data.timestamp,//生成签名的时间戳
		nonceStr:data.nonceStr,//生成签名的随机串
		signature:data.signature,//签名
	});
	wx.error(e => {
	    console.log('wx sdk errors:', e);
	});
}

调用wx.chooseWXPay进行支付调起
参数获取请看本文JSAPI支付签名

wx.chooseWXPay({
  timestamp: xxxxxxxx, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
  nonceStr: 'xxxxxxxx', // 支付签名随机串,不长于 32 位
  package: 'xxxxxxxx', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
  signType: 'xxxxxxxx', // 微信支付V3的传入RSA,微信支付V2的传入格式与V2统一下单的签名格式保持一致
  paySign: 'xxxxxxxx', // 支付签名
  success: function (res) {
    // 支付成功后的回调函数
  }
});

四、node对接对应的相关接口

1.JS-SDK权限签名

对应上面目录三-2的getJssdk接口使用
需提前准备
appid:appid凭证
appSecret:密钥

const crypto = require("crypto");
const axios = require("axios");
const appid = "xxxxxxxx";
const appSecret = 'xxxxxxxx';

//获取js-sdk参数
const getJssdk = (params)=>{

//-----------------------------------------------------------------------------
// 这两个接口获取的临时数据必须进行定时任务每个小时更新一次缓存起来
// 由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
	//获取access_token
    let result1 = await axios(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${appSecret}`);
    let access_token = result1.data.access_token;
    //获取jsapi_ticket 是公众号用于调用微信JS接口的临时票据
    let result2 = await axios(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`);
    let jsapi_ticket = result2.data.ticket;
//-----------------------------------------------------------------------------

	let timestamp = new Date().getTime();//时间戳
	let url = params.url;//当前网页的URL,不包含#及其后面部分
	let nonceStr = 'xxxxxxxxxxxxxxxxxxxx';//随机字符串
	let string1 = `jsapi_ticket=${jsapi_ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;
	let signature = jiamiSha1(string1);//sha1加密
	//返回数据给客户端
	return {
		code:0,
		message:'',
		data:{
			timestamp,
			nonceStr,
			signature
		}
	}
}
//sha1加密
function jiamiSha1(str){
    // 需要加密的字符串
    let sf = crypto.createHash('sha1');//使用加密算法
    sf.update(str);//进行加密
    let content = sf.digest("hex");//以二进制数据为字符串形式展示
    return content;
};
module.exports = getJssdk;

2.JSAPI支付签名

JSAPI支付签名下单文档-https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml
需提前准备
appid:appid凭证
mchid:商户号
serial_no:商户序列号
pem:证书私钥

const axios = require("axios");
const crypto = require("crypto");
const pem = require("./apiclient_key.js");
const appid = "xxxxxxxxxxxxx";//appid
const mchid = 'xxxxxxxxxxxxx';//商户号
const serial_no = 'xxxxxxxxxxxxx';//商户序列号

// jsapi下单
/*
data:{
	out_trade_no:'商户订单号',
	description:'说明'
	attach:'携带回调参数'
	notify_url:'通知地址',
	total:'分',
	openid:'用户openid',
}
*/
function paysgin(data){
	return new Promise(async(resolve,reject)=>{
		let url = '/v3/pay/transactions/jsapi';
		let params = {
			"mchid": mchid,//直连商户号
			"out_trade_no": data.out_trade_no,//商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
			"appid": appid,//应用ID
			"description": data.description,//商品描述
			"attach":JSON.stringify(data.attach),//附加数据
			"notify_url": data.notify_url,//通知地址
			"amount": {
				"total": data.total,//总金额,单位为分
				"currency": "CNY"
			},
			"payer": {
				"openid": data.openid//用户标识
			}
		}
		//获取prepay_id
		let result = await axios({
			url:"https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi",
            method:"post",
            headers:{
                "Authorization":sgin('POST',url,params)
            },
            data:params 
           });
		// 配置调起支付参数
		let prepay_id = result.data.prepay_id;
		let timestamp = parseInt(new Date().getTime()/1000).toString();
		let nonce_str = new Date().getTime().toString();
		let jiamiPaySign = appid + "\n" + timestamp + "\n" + nonce_str + "\n"  + `prepay_id=${prepay_id}` + "\n";
		let signaturePaySign = sha256(jiamiPaySign);
		//-----------------------------------------------------
		// 保存支付参数到数据库
		//-----------------------------------------------------
		resolve({
			code:0,
			msg:'',
			data:{
				appId:appid,//公众号ID,由商户传入
				timeStamp:timestamp,//时间戳,自1970年以来的秒数
				nonceStr:nonce_str,//随机串
				package:`prepay_id=${prepay_id}`,
				signType:"RSA",//微信签名方式:
				paySign:signaturePaySign,//微信签名
			}
		});
	})
}
//RSA-SHA256加密
function sha256(str){
	let privateKey  = pem;
	let sign = crypto.createSign('RSA-SHA256');
	sign.update(Buffer.from(str, 'utf-8'));
	let signature = sign.sign(privateKey, 'base64');
	return signature;
}
//签名
function sgin(method,url,params=""){
	let timestamp = parseInt(new Date().getTime()/1000);
	let nonce_str = new Date().getTime();
	params = JSON.parse(JSON.stringify(params));
	let message = method + "\n"
				+ url + "\n"
				+ timestamp + "\n"
				+ nonce_str + "\n"
				+ JSON.stringify(params) + "\n";
	let signature = sha256(message);
	let auth = `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",serial_no="${serial_no}",nonce_str="${nonce_str}",timestamp="${timestamp}",signature="${signature}"`;
	return auth;
}
module.exports = paysgin

3.支付成功的回调

支付结果通知文档-https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
在上面2.JSAPI支付签名后把参数给前端,发起支付后,支付成功会通知调用notify_url地址进行接收参数。
需要准备
key:APIv3密钥(微信商户平台—>账户设置—>API安全—>设置APIv3密钥)

//event.body 是 回调回来的数据
let body = JSON.parse(event.body);
console.log('body : ', body.resource)
const key = "xxxxxxxxxxxxxxx";
const ciphertext = body.resource.ciphertext;
const nonce = body.resource.nonce;
const associated_data = body.resource.associated_data;
//解密
let data = JSON.parse(decodeByAES(ciphertext,key,nonce,associated_data));
data.attach = JSON.parse(decodeURIComponent(data.attach));
data.success_time = decodeURIComponent(data.success_time.replace(/\+/g, '%20').replace(/T/g,' '));
console.log("解密",data)

//-----------------------------------------------------
// 进行相关回调通知,数据库操作,消息提醒等等。。。
//-----------------------------------------------------

decodeByAES解密回调的加密参数

const crypto = require("crypto");

function decodeByAES(cipherText,key,iv,add){
    let rst = '';
    cipherText = Buffer.from(cipherText, 'base64');
    let authTag = cipherText.slice(cipherText.length - 16);
    let data = cipherText.slice(0, cipherText.length - 16);
    let decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(authTag);
    decipher.setAAD(Buffer.from(add));
    rst = decipher.update(data, 'binary', 'utf8');
    try {
      rst += decipher.final('utf-8');
    } catch (e) {
      think.logger.error(e.toString());
    }
    return rst;
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 微信JSAPI支付是一种使用微信内置浏览器或微信客户端内的网页进行支付的方式。流程如下: 1. 用户在商户的网站或应用内点击支付按钮,触发支付请求。 2. 商户服务器收到支付请求后,向微信支付服务器发起下单请求,并将支付信息传递给微信支付服务器。 3. 微信支付服务器收到下单请求后,会根据商户提交的信息生成支付二维码或支付链接。 4. 商户服务器收到微信支付服务器的响应后,将支付二维码或支付链接发送给用户浏览器。 5. 用户浏览器打开支付二维码或支付链接,跳转到微信内置浏览器或微信客户端进行支付。 6. 用户在微信内置浏览器或微信客户端内输入支付密码或通过其他认证方式进行支付。 7. 微信支付服务器收到用户的支付信息后,会向商户服务器发送支付通知。 8. 商户服务器收到支付通知后,会对订单进行处理,并向用户 ### 回答2: 微信JSAPI支付是指通过微信公众号或小程序内的网页调用微信支付接口实现支付功能的流程。 1. 用户点击支付按钮后,公众号或小程序调用微信支付接口向微信服务器发起支付请求。 2. 微信服务器返回预支付交易会话标识prepay\_id给公众号或小程序。 3. 公众号或小程序将prepay\_id和其他支付参数通过JSAPI方式传递给前端页面。 4. 前端页面通过微信JSAPI提供的支付接口,调用微信客户端进行支付。 5. 用户在微信客户端确认支付后,微信服务器会将支付结果通知给公众号或小程序服务器。 6. 公众号或小程序服务器接收到支付结果通知后,进行订单处理,更新订单状态。 7. 公众号或小程序服务器向微信服务器返回处理结果,微信服务器会将处理结果通知给微信客户端。 8. 微信客户端收到支付结果通知后,提示支付成功或失败,并跳转至指定页面。 整个过程中,涉及到的主要步骤有:发起支付请求、获取预支付交易会话标识、传递参数给前端、调用微信客户端支付、接收支付结果通知、处理订单、返回处理结果给微信服务器、微信客户端显示支付结果。 微信JSAPI支付能够为公众号或小程序提供方便、安全的支付体验,使用户能够快速完成支付操作,同时也提供了支付结果的即时通知和订单处理的接口,方便商户进行后续操作。 ### 回答3: 微信JSAPI支付流程是指通过微信公众号或小程序内页面上的网页进行支付流程。具体流程如下: 1. 用户在微信公众号或小程序内选择商品并确认下单。 2. 商户服务器将订单信息提交给微信服务器,包括商品描述、订单号、金额等信息,并生成预支付交易会话标识prepay_id。 3. 商户服务器将prepay_id返回给前端页面。 4. 前端页面调用微信JSAPI的支付接口,传入prepay_id以及其他支付相关参数(如时间戳、随机字符串等)。 5. 微信服务器校验参数,并生成支付签名。 6. 微信服务器将支付签名返回给前端页面。 7. 前端页面调用微信JSAPI的支付接口,传入支付签名以及其他支付相关参数。 8. 用户在微信客户端确认支付并输入支付密码。 9. 微信服务器接收支付结果,并返回给商户服务器。 10. 商户服务器校验支付结果,更新订单状态,并返回相应的支付结果给用户。 需要注意的是,为了确保支付的安全性,商户服务器需要对支付结果进行校验,并对订单状态进行更新,以防止重复支付支付金额被修改等情况的发生。 以上就是微信JSAPI支付的主要流程微信JSAPI支付相对于其他支付方式来说,使用便捷,支持在微信内进行快速支付,适用于微信公众号和小程序等场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值