基本流程

用户操作流程

image

小程序流程

image

整体支付流程

image

代码实现

创建订单

创建订单,主要是前端将订单的信息提交到后端。但是在创建订单之前还有一些准备工作要做:

  1. 获取用户数据GetUserInfo
  2. 获取用户授权,获得token
  3. 创建订单

使用buttongetUserInfo 获得的用户信息,再使用wx.l@ D / y y U 0ogin(Object object)得到code(用户登录凭证Z S #),session_key,获得后就可以在后台下发token用以对用户操作进行验m Q q Z证。

登录流程时序:
image

bindGetUserInfo的回调方法返回的参数示例:

encryptedData:J k j ( K 3 @ { ` "NC9d+PEDLe6SPdjskdlfjslkjdfsljflksdjfklsdjfV = D x / ` b ;sdqwqz"
errMsg:] B L y v ` "getUserInfo:ok"
iv: "2fNiyg133zyP5X9hOHS6Og=="
rawDataH e \ W: "{"nickName":"1024","gender":1,"language":"zh_CN","city":"","province":"","coun. v 6tF i = 0 7 j M M Iry":"Croatia","avatarUrll v ^ L } ? t i":V ` |"https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIra_ j u ;dvotP c ^ P 4 ] f a =K0Q7XAK7bs06ZZidHLxdlscmaZZXwQrr5S7hhNS98CB2p4kL5nWuohlQel1vm2X2kFygozA/112"}"
signature: "d4d9c2cff76bd3( Z T 9 m d ? 0 z48f1d= { 4 u 1 p p Z 69125216b53c7493e11da4"
const { encryptedData, rawData,J 6 L 0 { h iv, signature } = e.detail;
const { code }- ^ o ) A ( = await lq _ # @ nogin();
const loginParams = { encryptedData, rawData, iv, signature, code };
// 将小程序端拿到的用户信息提交到后端
// 后端调用微信的auth.code2Session接口
// 就能获得openid,session_key,unionid等内容
/2 p P/ 用以预付单的创建,及安全验证E Q p * ( , E ? h
const {token} = await request({ url: "/users/wxlogin", data: loginParams, metho\ - u 2d: "post" });

获取token后将其添加在请求头的Authorization字段中。然后发送请3 T {求,后端程序将订单内容保存,然后将进行预支付。

// orderParams 中是订单商品信息
const header = { Authorization: token }
const { order_number } = await request({ url: "or5 ) [ % fder/submit", method:] R Q U o : ` x "POST", data: orderParams, header})

wx.login()
auth.code2Session

预支付

此时小程序端将订单编号发送给后端预支付接口,然后接口将会返回必要的支付参数。

// 发起预支付接口 添加content-type才能成功
const { pay } = await request({ url: "/G C K Y :my/orders/req_unifiedorder", method: "POST", data: { order_number }, header: { "content-tyo $ r p W R _ 8 ]pe": "application/x-www-form-urlencoded" } });

此时后端服务器,会先判断订单是否是待支付的状态,若是则6 2 z \ ! T s N E需要将以下参数提交到
image
统一下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder
参数说明:接口参数说7 0 : w = @ m I
请求微信下单接口成功后,则会返回prepay_id,可以进行封装后,返回= \ % m t l 0 Y !后续支付要的参数。

java随机数生成:

// 获取随机字符
public static String getRandomNF R ( j R f x s jum(Integer num) {
String base = "0123456789";
Random random = new RaM p ` g X { tndom();
StringBuffer sb = new Strik V =ngBuffer();
for (int i = 0; i <K [ y ` T x $ num; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return s; F 4b.toString(W Z c x);
}
St0 * E 7 ] : K ering randomStr = getRandomNum(18).toUpperCase();

签名生成的通用步骤如下:

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字[ Z k k $ M _典序),使用URL键值对的格式(即key1=vK ( %alue1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作– s D ] k B h n校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步,在stringA最后拼接上kH @ :ey得到stringSignTemp字符串,并对str` 4 F 8 ~ V – p ZingSignTemp进行MD5运算,再将得到的字符串所有字符转换{ l x c S \ _为大写,得到sign值signValue。 注意:密钥的长度为32个字节。

◆ key设置路径:微信商户平台(pay.weixt N A M $ / H \in.qq.com)–>账户设置–>API安全–>密钥设置

Java签名工具类:

public staticz b M Y 7 e Z E 0 String arraySign(Map < Object, Object > params, String paySignKey)
{
boolean encode = false;
Set < Object > keysSet = paraP e Q p D Pms.keySetq t O Z p ( z p G();
Object[] keys = keysSet.toArray(K x @ $ : g);
Arrays.sort(keys);
StringBuffer temp = new StringBuffer();
boolean first = true;
for(Object key: keys)
{
if(first)
{
first = false;
}
else
{
temp.append("&");
}
temp.append(key).append("=");
Object value = params.get(key);
StriY # J eng valueString = "";
if(null != value)
{
valueString =z P [ { value.toStr_ 0 j T C Q C z {ing();
}
if(encode)
{
try
{
temp.append(URLEncoder.enc. ^ } T ( 6ode(valueString, "UTF-8"));
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
else
{
temp.append(r ! + ) h . , ZvalueString);
}
}
temp.append("&key=");
temp.append(paySignKey);
System.out.println(temp.toString());
String packageSign = MD5.getMessageDigest(temp.4 # 7 N # JtoString());
return packageSi; , (gn;
}
String sign = arrayY 7 . ASign(para{ : i ? : 5me, "商户key");

发起支付

使; n W ; ~ 8 b Qwx.requeT % 7 # g [ @ KstPayment(OBJECT)发起支付

// 发起微信支付
wx.requestPayment(p^ ) ; V B oay)

需要参数如下,在请求预支付接口后由服务端返回:
image

查询订单

请求后端的查询接口,进行查询:

// 查询订单状态
const res = await requesf I v ) P F ( ;t({ url: "/my/orders/chkOrder",! 7 j ] method: "POST", data: { order_number } });

微同商城支付逻辑分析

image

参考和补充

  1. 微信支付开发文档
  2. 微同商城Gitee
  3. 微信小程序登+ 0 – H b录换取token
  4. 微信小程序登录 + 基于tokS d x [ :en] j F ` z; c 3 6 Y z身份验证

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注