1.大体流程
调用微信支付的大概流程可以说很简单
引导用户进入授权,根据用户的code来授权获取用户的基本信息,授权完成之后进入个人操作页面,
然后对支付的参数进行封装,传到前台,前台发起请求调用微信支付
2.使用流程
1.微信入口
@WebServlet("/wxLogin")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//第一步:引导用户进入授权页面同意授权,获取code
//授权页面地址
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+ WXAuthUtil.APPID
+ "&redirect_uri="+ URLEncoder.encode(WXAuthUtil.getBackUrl(),"UTF-8")
+ "&response_type=code"
+ "&scope=snsapi_userinfo"
+ "&state=STATE#wechat_redirect";
//重定向到授权页面
response.sendRedirect(url);
}
}
2.编写回调controller
@RequestMapping("/authback.do")
public void authCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
LOG.info("授权回调开始.......");
String redirectUrl = "";
// 第一步 获取微信用户基本信息 code
String code = request.getParameter("code");
if (StringUtils.isNotBlank(code)) {
//第二步:通过code换取网页授权access_token
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WXAuthUtil.APPID
+ "&secret=" + WXAuthUtil.APPSECRET
+ "&code=" + code
+ "&grant_type=authorization_code";
JSONObject jsonObject = WXAuthUtil.doGetJson(url);
String openid = jsonObject.getString("openid");
String access_token = jsonObject.getString("access_token");
String refresh_token = jsonObject.getString("refresh_token");
//第五步验证access_token是否失效;
String chickUrl = "https://api.weixin.qq.com/sns/auth?access_token=" + access_token + "&openid=" + openid;
JSONObject chickuserInfo = WXAuthUtil.doGetJson(chickUrl);
System.out.println(chickuserInfo.toString());
if (!"0".equals(chickuserInfo.getString("errcode"))) {
// 第三步:刷新access_token(如果需要)-----暂时没有使用
String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + openid + "&grant_type=refresh_token&refresh_token=" + refresh_token;
JSONObject refreshInfo = WXAuthUtil.doGetJson(chickUrl);
System.out.println(refreshInfo.toString());
access_token = refreshInfo.getString("access_token");
}
// 第四步:拉取用户信息(需scope为 snsapi_userinfo)
String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token
+ "&openid=" + openid
+ "&lang=zh_CN";
System.out.println("infoUrl:" + infoUrl);
JSONObject userInfo = WXAuthUtil.doGetJson(infoUrl);
/*
{ "openid":" OPENID",
" nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
**/
} else {
LOG.info("没有获取到code......");
LOG.info("重新登录");
redirectUrl = "/common/500";
}
redirectUrl = "xxxxxx";
//商户操作界面
//获取到用户信息后就可以进行重定向,
response.sendRedirect(redirectUrl);
}
请求工具类
public class WXAuthUtil {
public static String APPID;
public static String APPSECRET;
private static String TOKEN;
private static String backUrl;
//这边主要是获取公众号的一些信息配置
static {
String properValue = ProperUtil.getProperValue("weixin4j.properties", "weixin4j.account");
backUrl = ProperUtil.getProperValue("weixin4j.properties", "weixin4j.user.oauth.redirect.uri");
WXAuthUtil.setBackUrl(backUrl);
JSONObject jsonObject = JSON.parseObject(properValue);
WXAuthUtil.setAPPID(jsonObject.getString("id"));
WXAuthUtil.setAPPSECRET(jsonObject.getString("secret"));
}
public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException {
JSONObject jsonObject =null;
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet =new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity =response.getEntity();
if(entity!=null)
{
//把返回的结果转换为JSON对象
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSON.parseObject(result);
}
return jsonObject;
}
public static String getBackUrl() {
return backUrl;
}
public static void setBackUrl(String backUrl) {
WXAuthUtil.backUrl = backUrl;
}
public static String getAPPID() {
return APPID;
}
public static String getAPPSECRET() {
return APPSECRET;
}
public static String getTOKEN() {
return TOKEN;
}
public static void setAPPID(String APPID) {
WXAuthUtil.APPID = APPID;
}
public static void setAPPSECRET(String APPSECRET) {
WXAuthUtil.APPSECRET = APPSECRET;
}
public static void setTOKEN(String TOKEN) {
WXAuthUtil.TOKEN = TOKEN;
}
}
到这里基本上流程已经走到支付那块,前期就是微信让你认证一下,知道你是个人就好了,接下来就是大活了,需要调用支付了,H5页面自己做个按钮什么之类的
我这边后台支付用的是WeixinPayProxy 网上可以找一下maven引进来到pom,有这个那就相对来说easy多了。
先封装一个单例,其实我对java也不熟,自己乱搞呢,能用就行,怎样方便怎样整
public class WeixinPayProxySingle {
private static Log log = LogFactory.getLog(WeixinPayProxySingle.class);
private static String fileName = "weixin4j.properties";
private static String account = "weixin4j.account";
private static WeixinPayProxy instance;
private WeixinPayProxySingle() {
}
public static WeixinPayProxy getInstance() {
String properValue = ProperUtil.getProperValue(fileName, account);
if(StringUtils.isNotBlank(properValue)){
JSONObject account = JSON.parseObject(properValue);
if (instance == null) {
instance = new WeixinPayProxy(new WeixinPayAccount(account.getString("id"), account.getString("paySignKey"), account.getString("mchId")));
}
}else{
log.info("获取配置文件失败");
}
return instance;
}
}
3.接下来就是编写按钮事件controller
public void perPay(){
WeixinPayProxy weixinPayProxy = WeixinPayProxySingle.getInstance();
String openId = "o6dsctyXpndCV1L94u_ZixgzxB6Y"
String body = "";//支付描述,这个微信支付成功会有单子上面有就跟你支付成功会有条消息
String outTradeNo = "";//"mdsas1212";// "商户侧唯一订单号,如18789913341";
double totalFee = 0.01d;//金额,先写个一分,你想写一万也行
LOG.info("金额" + totalFee);
String notifyUrl = authUrl;//"支付完成后的回调地址,如http://wx.xxx.com/pay/notify";
String createIp = request.getRemoteAddr();//"发起支付时的客户端IP地址,如192.168.1.1";
String attach = "微信支付手机充值";//"支付时的附加信息,在回调时会原样带上,可为空";
LOG.info("用户openid:" + openId);
// 发起一个JS支付请求
MchPayRequest payRequest = weixinPayProxy.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
LOG.info("预支付订单号:" + payRequest.getPrePayId());
requert.getSeeion().setAttribute("jsapi",payRequest.toRequestString());//这个就厉害了,就是你前台需要的封装的参数,用这个吊起微信支付
}
到此处基本上支付就差不多了,别着急,刚开始前台用的是getBrandWCPayRequest 调用微信支付,妈的,坑的呀,,苹果手机直接缺失参数,$key0愣是找不出问题,后来改用chooseWXPay,用这个的话必须进行微信config操作,我下篇文章给大家整,目前getBrandWCPayRequest 的还没解决,有会的也可以给我说,但我用chooseWXPay终于支起来了