获取openid
1 第一步:用户同意授权,获取code
2 第二步:通过code换取网页授权access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
5 附:检验授权凭证(access_token)是否有效
微信公众平台官方文档——微信网页授权
微信支付
用户点击一个支付按钮–>{后台一大推处理}–>用户看到了一个输入密码的界面,包含金额等一些信息–>用户输入密码后出来一个支付成功的页面(这部分流程都是微信自己完成的,我们什么都不用做)–>返回系统自己的页面
开发流程
1)获取用户授权(即获取openid)
2)调用统一下单接口获取预支付id
3)H5调起微信支付的内置JS
4)支付完成后,微信回调URL的处理
- pom.xml
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>3.3.0</version>
</dependency>
- 配置
package com.chuai.ecshop.wxConfig;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.Data;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("wechat")
@Data
public class WxConfig {
private String appid;
private String appSecret;
private String mchId;
private String mchKey;
private String keyPath;
@Bean
public WxMpInMemoryConfigStorage initStorage(){
WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
config.setAppId(appid);
config.setSecret(appSecret);
return config;
}
@Bean
public WxMpService initWxMpService(){
WxMpService wxMpService= new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(initStorage());
return wxMpService;
}
@Bean
public WxPayService initWxPayService(){
WxPayService wxPayService= new WxPayServiceImpl();
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(appid);
payConfig.setMchId(mchId);
payConfig.setMchKey(mchKey);
payConfig.setKeyPath(keyPath);
wxPayService.setConfig(payConfig);
return wxPayService;
}
}
- 控制器
package com.chuai.ecshop.web;
import com.chuai.ecshop.pojo.Order;
import com.chuai.ecshop.service.OrderService;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.net.URLEncoder;
@Controller
@Slf4j
public class WXMpController {
@Autowired
WxMpService wxMpService;
@Autowired
WxPayService wxPayService;
@Autowired
OrderService orderService;
/**
*
String baseUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=xxxxxxxxxxx&" +
"redirect_uri=http%3a%2f%2fxxxxxxxxxxx%2fsell%2fwechat&" +
"response_type=code&scope=snsapi_userinfo&state=chuai#wechat_redirect";
* 1、引导用户进入授权页面同意授权,获取code
* @return
*/
@RequestMapping("/wechat/authorize")
public String getWxMpCode(String returnUrl){
if(returnUrl!=null) {
returnUrl = URLEncoder.encode(returnUrl);
}
String baseUrl = wxMpService.oauth2buildAuthorizationUrl(
"http://www.chuai.com/sell/wechat",
WxConsts.OAuth2Scope.SNSAPI_USERINFO,
returnUrl);
log.info("baseUrl打印:{}",baseUrl);
return "redirect:"+baseUrl;
}
/**
* 获取用户信息 openid 、accessToken等
* @param code
* @param state
* @return
*/
@RequestMapping("/wechat")
public String getUser(String code, String state){
WxMpOAuth2AccessToken accessToken = new WxMpOAuth2AccessToken();
try {
accessToken = wxMpService.oauth2getAccessToken(code);
} catch (WxErrorException e) {
e.printStackTrace();
}
String openId = accessToken.getOpenId();
log.info("授权成功:"+openId);
return "redirect:"+state+"?openid="+openId;
}
/**
* 唤醒支付
* @param orderId
* @param openid
* @return
*/
@RequestMapping("/pay/create")
public String parCreate(Model m , String orderId, String openid,String returnUrl){
log.info("进入pay/create方法。。。{}",wxPayService);
Order order = orderService.findOrderById(openid, orderId);
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setOpenid(openid);
orderRequest.setBody("腾讯充值中心-QQ会员充值");
orderRequest.setOutTradeNo(order.getOId());
orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(order.getOAccount().toString()));//元转成分
orderRequest.setSpbillCreateIp("127.0.0.1");
orderRequest.setNotifyUrl("http://www.chuai.com/sell/notify/order");
orderRequest.setTradeType("JSAPI");
try {
WxPayMpOrderResult wxPayMpOrderResult = wxPayService.createOrder(orderRequest);
m.addAttribute("wxPayMpOrderResult",wxPayMpOrderResult);
m.addAttribute("returnUrl",returnUrl);
} catch (WxPayException e) {
log.info("微信支付失败!订单号:{},原因:{}",orderId,e.getMessage());
e.printStackTrace();
return "fail";
}
return "payIndex";
}
@RequestMapping("/notify/order")
public String parseOrderNotifyResult(@RequestBody String xmlData) throws WxPayException {
log.info("进入回调通知方法。。。。。{}",xmlData);
final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
// TODO 根据自己业务场景需要构造返回对象
return WxPayNotifyResponse.success("成功");
}
}
- 支付页面HTML
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>支付页面</title>
<script>
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":"${wxPayMpOrderResult.appId}", //公众号名称,由商户传入
"timeStamp":"${wxPayMpOrderResult.timeStamp}", //时间戳,自1970年以来的秒数
"nonceStr":"${wxPayMpOrderResult.nonceStr}", //随机串
"package":"${wxPayMpOrderResult.packageValue}",
"signType":"MD5", //微信签名方式:
"paySign":"${wxPayMpOrderResult.paySign}" //微信签名
},
function(res){
// if(res.err_msg == "get_brand_wcpay_request:ok" ){
window.location.href="${returnUrl}";
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// }
});
}
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();
}
</script>
</head>
<body>
</body>
</html>