您的位置:首页 > 移动开发 > 微信开发

微信跨公众号支付

2016-06-28 11:33 351 查看
先说下我的需求。我有两个公众号(不是订阅号,订阅号无法向公众号支付)分别为A和B,现在我关注公众号A,在公众号A中需要发起公众号B的支付,也就是说我在公众号A中向公众号B支付钱(用户未关注B公众号)。

一、在公众号B中配置测试授权目录



二、使用微信OAuth2.0授权公众号B获取B公众号openId

/**
* 微信授权获取code
* @param response
* @throws IOException
*/
@RequestMapping(value = "/getCode", produces = {"application/json;charset=UTF-8"}, method = RequestMethod.GET)
public void getCode(HttpServletResponse response) throws IOException {
response.sendRedirect(getCodeRequest());
}
public static String  GetCodeRequest = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
public static String getCodeRequest(){
String result = null;
GetCodeRequest  = GetCodeRequest.replace("APPID", urlEnodeUTF8(WxpayConfig.appid));
//授权回调地址weixin/t1/callBack处理code获取openId
GetCodeRequest  = GetCodeRequest.replace("REDIRECT_URI",urlEnodeUTF8("http://xxxxxx/weixin/t1/callBack"));
//不弹出微信授权页面:scope=snsapi_base,弹出微信授权页面:scope=snsapi_userinfo
GetCodeRequest = GetCodeRequest.replace("SCOPE", "snsapi_base");
result = GetCodeRequest;
return result;
}
三、授权完成,授权回调函数获取code和openId
/**
微信授权回调
**/
@RequestMapping(value = "/callBack", produces = {"application/json;charset=UTF-8"}, method = RequestMethod.GET)
public String callBack(HttpServletRequest request) throws IOException {
//獲取code
String code = request.getParameter("code");
String url = String.format(Constant.OPENID_RETREIVAL_URL, WxpayConfig.appid, WxpayConfig.appsecret, code);
//获取openId信息
JSONObject jsonObject = WeixinUtil.httpsRequest(url, "GET", null);
if (jsonObject != null) {
try {
OpenIdBean openIdBean = (OpenIdBean) JSONObject.toBean(jsonObject, OpenIdBean.class);
request.setAttribute("openId",openIdBean.getOpenid());
}catch (Exception e) {
e.printStackTrace();
}
}
//跳转到发起支付的页面
return "weixin/test/index2";
}
至此已经在A公众号中完全获取了B公众号的OpenId下面就可以进行支付了。

附index2页面

四、统一下单进行支付

//公众号支付
@RequestMapping(value = "/unifiedorder_jsapi", produces = {"application/json;charset=UTF-8"}, method = RequestMethod.GET)
@ResponseBody
public Object native_unifiedOrder2(HttpServletRequest request){

//终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"
String device_info = "WEB";
//随机字符串,不长于32位
String nonce_str = UUID.randomUUID().toString().replace("-","");
//商品或支付单简要描述
//String body = request.getParameter("body");
//商品名称明细列表
String detail = request.getParameter("detail");
//商户系统内部的订单号
String orderNos = request.getParameter("orderNos");

//APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
String spbill_create_ip = request.getParameter("spbill_create_ip");
//交易类型 取值如下:JSAPI--公众号支付,NATIVE:扫码支付,APP
String trade_type = "JSAPI";
//用户openid
String openid = request.getParameter("openId");

//组装请求数据
TreeMap<String, String> treeMap = new TreeMap<String, String>();
treeMap.put("appid",WxpayConfig.appid);
treeMap.put("mch_id", WxpayConfig.mch_id);
treeMap.put("nonce_str", nonce_str);
treeMap.put("notify_url",WxpayConfig.notify_url);
treeMap.put("device_info",device_info);
treeMap.put("body","asadsd");
treeMap.put("detail","ssss");
treeMap.put("spbill_create_ip","192.167.0.12");
treeMap.put("trade_type", trade_type);
treeMap.put("openid",openid);

Map resMap = new HashMap();
//创建TradingOrder订单与支付单关系表
String out_trade_no = UUID.randomUUID().toString().replace("-", "");
//转换订单号,主要是为了应对多单合并支付
treeMap.put("out_trade_no", out_trade_no);
//计算订单的实际支付金额
//订单总金额,单位为分
//付款金额必须为整数 不允许有小数点
treeMap.put("total_fee", "1");

String xml = WxUtil.getPackage(treeMap);
// 创建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
HttpPost httpPost = new HttpPost(WxpayConfig.unifiedorder);

StringEntity entity;
//预支付id
String prepay_id ="";
//当trade_type为NATIVE获取扫码支付连接
String code_url = "";
try {
entity = new StringEntity(xml, "utf-8");
httpPost.setEntity(entity);
CloseableHttpResponse httpResponse;
// post请求
httpResponse = closeableHttpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
// 打印响应内容
String result = EntityUtils.toString(httpEntity, "UTF-8");
// 过滤
result = result.replaceAll("<![CDATA[|]]>", "");
Map<String, String> map = XMLUtil.doXMLParse(result);
if(map != null){
prepay_id  = (String) map.get("prepay_id");
}
}
// 释放资源
closeableHttpClient.close();
} catch (Exception e) {
e.printStackTrace();
}

//获取prepay_id后,拼接最后请求支付所需要的package
if(prepay_id == null || "".equals(prepay_id)  ){//请求数据出错
resMap.put("payMsg",new HashMap());

}else {
TreeMap<String, String> finalpackage = new TreeMap<String, String>();

String timestamp = WxUtil.getTimeStamp();
String packages = "prepay_id="+prepay_id;
finalpackage.put("appId", WxpayConfig.appid);
finalpackage.put("timeStamp", timestamp);
finalpackage.put("nonceStr", nonce_str);
finalpackage.put("package", packages);
finalpackage.put("signType", "MD5");

String paySign = WxUtil.createSign(finalpackage);
finalpackage.put("paySign",paySign);

resMap.put("payMsg", finalpackage);

}

//请求数据无误,可生成预支付订单写入数据库
return resMap;
}
至此跨公众号支付就完成了,在上面的代码中用到了一些工具类,可根据自己去修改。也可以去下载http://download.csdn.net/detail/yusewuhen/9561633
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  微信 支付 跨公众号