收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
let currentUrl = encodeURIComponent(window.location.href)
window.location.href = ‘https://open.weixin.qq.com/connect/oauth2/authorize?appid=我是appid&redirect_uri=’+currentUrl+‘&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect’
} else {
let code = this.GetQueryString(‘code’)
// 此处调用后端方法,通过 code 换取 openid
}
}
>
> 补充:授权链接中的 scope 参数分为 snsapi\_base、snsapi\_userinfo,snsapi\_base 可以获得用户的唯一标识 openid,snsapi\_userinfo 则在此基础上获得用户资料「昵称、头像等」
>
>
>
上述方法中 **ua.match(/MicroMessenger/i)** 是用来判断是否是微信环境的, **GetQueryString** 方法用来获取微信中的 code,如果当前浏览器 url 并没有附带 code 参数,那么就会调用微信的 authorize 方法进行授权,授权后获得 code,该方法具体如下:
GetQueryString (name) {
let url = new RegExp(‘(^|&)’ + name + ‘=([^&]*)(&|$)’)
let newUrl = window.location.search.substr(1).match(url)
if (newUrl != null) {
return unescape(newUrl[2])
} else {
return false
}
},
#### 2、换取openid
拿到 code 后,下一步就是调用后端接口换取 openid 了, 简单看一下换取 openid 的后端方法:
try {
String url = “https://api.weixin.qq.com/sns/oauth2/access_token?appid=我是appid&secret=我是secret&grant_type=authorization_code”+
“&code=” + loginRequest.getCode();
String body = RestTemplateUtils.get(url,new JSONObject());
JSONObject jsonObject = JSONObject.parseObject(body);
Integer errcode = jsonObject.getInteger(“errcode”);
if (errcode == null || errcode == 0) {
String openId = jsonObject.getString(“openid”);
//将此次登录的openId,暂且放入user的域里面,支付的时候会用到
System.out.println(“openId:”+openId);
loginRequest.setOpenId(openId);
return ResultUtil.success(userService.login(loginRequest));
}else{
logger.error(“[微信第三方登录] 异常”);
抛出自定义异常
throw new CommonException(“微信第三方登录异常”,”“);
}
} catch (Exception e) {
logger.error(”[微信第三方登录] 异常", e);
抛出自定义异常
throw new CommonException(“微信第三方登录异常”,“”);
}
简单说一下该方法,前端传递 code 致后端方法,后端拿到 code 后,调用 access\_token 接口获取 openid,同时完成登录操作。
至此,已经成功登录并拿到用户 openid 了,接下来就是调用支付接口。
#### 3、预支付接口
上边已经提到了,内部浏览器支付是交由前端发起的,但是又依赖于后端的 预支付接口,所以先来看一下后端预支付接口:
/**
* 生成订单「微信内部浏览器」
* @return
*/
@Transactional
public Object wxPrepay(Orders orders,String openId) {
Object result = null;
try {
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setOutTradeNo(orders.getOrderId());
orderRequest.setOpenid(openId);
orderRequest.setBody(“我是商品描述信息");
orderRequest.setTotalFee(orders.getAmount().multiply(new BigDecimal(“100”)).intValue());
orderRequest.setSpbillCreateIp(DispatchParams.getInstance().getWechatSpbillCreateIp());
orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
result = wxPayService.createOrder(orderRequest);
if (result instanceof WxPayMpOrderResult) {
String prepayId = ((WxPayMpOrderResult)result).getPackageValue();
String paySign = ((WxPayMpOrderResult) result).getPaySign();
prepayId = prepayId.replace(“prepay_id=”, “”);
orders.setPrepayId(prepayId);
orders.setSign(paySign);
ordersDao.updateOrders(orders);
}
} catch (WxPayException e) {
logger.error(“[微信支付] 异常”, e);
抛出自定义全局异常
throw new CommonException(WechatStatusEn.WECHAT_CREATE_CODE_ERROR.getErrorMsg()+“':微信支付异常”, WechatStatusEn.WECHAT_CREATE_CODE_ERROR.getErrorCode());
} catch (Exception e) {
logger.error(“[预付款异常]”, e);
抛出自定义全局异常
throw new CommonException(WechatStatusEn.WECHAT_CREATE_CODE_ERROR.getErrorMsg()+“':预付款异常”, WechatStatusEn.WECHAT_CREATE_CODE_ERROR.getErrorCode());
}
return result;
}
简单说一下预支付方法,首先是根据自己情况创建订单记录,然后就是通过 openid 调用 wxPayService.createOrder 方法「WxJava」获取预支付id,该方法返回的实体为 WxPayMpOrderResult,实体参数为前端调起微信支付的必要参数,具体如下:
private String appId;
private String timeStamp;
private String nonceStr;
@XStreamAlias(“package”)
private String packageValue;
private String signType;
private String paySign;
为啥获得的预支付id没有用到呀?上方返回的参数并没有看到呀!
其实不然,属性 packageValue 的值为 **prepay\_id=预支付id** ,该参数是必须的。
#### 4、前端调用,发起支付
至此,后端基本完成了,我们将参数传递给前端调用,直接模拟返回后的数据:
假设下方是调用接口返回的数据
console.log(“我是后端返回的数据 - res:"+JSON.stringify(res))
const payParam = {
appId: res.appId,
nonceStr: res.nonceStr,
package: res.packageValue,
timeStamp: res.timeStamp,
signType: res.signType,
paySign: res.paySign,
}
if (typeof WeixinJSBridge === ‘undefined’) {
if (document.addEventListener) {
document.addEventListener(‘WeixinJSBridgeReady’, this.onBridgeReady(payParam), false)
} else if (document.attachEvent) {
document.attachEvent(‘WeixinJSBridgeReady’, this.onBridgeReady(payParam))
document.attachEvent(‘onWeixinJSBridgeReady’, this.onBridgeReady(payParam))
}
} else {
this.onBridgeReady(payParam)
}
发起支付的 onBridgeReady 方法:
onBridgeReady(res){
alert(“发起请求:”+JSON.stringify(res));
WeixinJSBridge.invoke(
‘getBrandWCPayRequest’, {
“appId”:res.appId, //公众号名称,由商户传入
“timeStamp”:res.timeStamp, //时间戳,自1970年以来的秒数
“nonceStr”:res.nonceStr, //随机串
“package”:res.package, // prepay_id=xxx
“signType”:res.signType, //微信签名方式:
“paySign”:res.paySign //微信签名
},
function(res){
alert(JSON.stringify(“我是支付返回的信息:\n”+res));
alert(“我是支付返回的信息:\n”+res.err_msg);
if(res.err_msg == “get_brand_wcpay_request:ok” ){
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
alert(“支付成功了”);
}
}
);
}
#### 5、效果截图
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=http%3A%2F%2Fniceyoo.gitee.io%2Fblog%2F%2Fimg%2F2020_01_27%2F1580096633880_4eaf832f-0537-4c6a-a3a7-7a2c86120791.png&pos_id=img-24ocwX5E-1715646009667)
**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/a040ad1879eeb3c8808ae368e1ae00f0.png)
![img](https://img-blog.csdnimg.cn/img_convert/cb18306f09aeda53c394c4ba1210b4a0.png)
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
646009669)]
[外链图片转存中...(img-KPvzAWZd-1715646009670)]
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**