微信跨公众号支付

- 日理万妓 2024-02-17 17:35 105阅读 0赞

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

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

Center

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

  1. /**
  2. * 微信授权获取code
  3. * @param response
  4. * @throws IOException
  5. */
  6. @RequestMapping(value = "/getCode", produces = {"application/json;charset=UTF-8"}, method = RequestMethod.GET)
  7. public void getCode(HttpServletResponse response) throws IOException {
  8. response.sendRedirect(getCodeRequest());
  9. }
  10. 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";
  11. public static String getCodeRequest(){
  12. String result = null;
  13. GetCodeRequest = GetCodeRequest.replace("APPID", urlEnodeUTF8(WxpayConfig.appid));
  14. //授权回调地址weixin/t1/callBack处理code获取openId
  15. GetCodeRequest = GetCodeRequest.replace("REDIRECT_URI",urlEnodeUTF8("http://xxxxxx/weixin/t1/callBack"));
  16. //不弹出微信授权页面:scope=snsapi_base,弹出微信授权页面:scope=snsapi_userinfo
  17. GetCodeRequest = GetCodeRequest.replace("SCOPE", "snsapi_base");
  18. result = GetCodeRequest;
  19. return result;
  20. }

三、授权完成,授权回调函数获取code和openId

  1. /**
  2. 微信授权回调
  3. **/
  4. @RequestMapping(value = "/callBack", produces = {"application/json;charset=UTF-8"}, method = RequestMethod.GET)
  5. public String callBack(HttpServletRequest request) throws IOException {
  6. //獲取code
  7. String code = request.getParameter("code");
  8. String url = String.format(Constant.OPENID_RETREIVAL_URL, WxpayConfig.appid, WxpayConfig.appsecret, code);
  9. //获取openId信息
  10. JSONObject jsonObject = WeixinUtil.httpsRequest(url, "GET", null);
  11. if (jsonObject != null) {
  12. try {
  13. OpenIdBean openIdBean = (OpenIdBean) JSONObject.toBean(jsonObject, OpenIdBean.class);
  14. request.setAttribute("openId",openIdBean.getOpenid());
  15. }catch (Exception e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. //跳转到发起支付的页面
  20. return "weixin/test/index2";
  21. }

至此已经在A公众号中完全获取了B公众号的OpenId下面就可以进行支付了。

附index2页面

四、统一下单进行支付

  1. //公众号支付
  2. @RequestMapping(value = "/unifiedorder_jsapi", produces = {"application/json;charset=UTF-8"}, method = RequestMethod.GET)
  3. @ResponseBody
  4. public Object native_unifiedOrder2(HttpServletRequest request){
  5. //终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"
  6. String device_info = "WEB";
  7. //随机字符串,不长于32位
  8. String nonce_str = UUID.randomUUID().toString().replace("-","");
  9. //商品或支付单简要描述
  10. //String body = request.getParameter("body");
  11. //商品名称明细列表
  12. String detail = request.getParameter("detail");
  13. //商户系统内部的订单号
  14. String orderNos = request.getParameter("orderNos");
  15. //APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
  16. String spbill_create_ip = request.getParameter("spbill_create_ip");
  17. //交易类型 取值如下:JSAPI--公众号支付,NATIVE:扫码支付,APP
  18. String trade_type = "JSAPI";
  19. //用户openid
  20. String openid = request.getParameter("openId");
  21. //组装请求数据
  22. TreeMap<String, String> treeMap = new TreeMap<String, String>();
  23. treeMap.put("appid",WxpayConfig.appid);
  24. treeMap.put("mch_id", WxpayConfig.mch_id);
  25. treeMap.put("nonce_str", nonce_str);
  26. treeMap.put("notify_url",WxpayConfig.notify_url);
  27. treeMap.put("device_info",device_info);
  28. treeMap.put("body","asadsd");
  29. treeMap.put("detail","ssss");
  30. treeMap.put("spbill_create_ip","192.167.0.12");
  31. treeMap.put("trade_type", trade_type);
  32. treeMap.put("openid",openid);
  33. Map resMap = new HashMap();
  34. //创建TradingOrder订单与支付单关系表
  35. String out_trade_no = UUID.randomUUID().toString().replace("-", "");
  36. //转换订单号,主要是为了应对多单合并支付
  37. treeMap.put("out_trade_no", out_trade_no);
  38. //计算订单的实际支付金额
  39. //订单总金额,单位为分
  40. //付款金额必须为整数 不允许有小数点
  41. treeMap.put("total_fee", "1");
  42. String xml = WxUtil.getPackage(treeMap);
  43. // 创建HttpClientBuilder
  44. HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
  45. CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
  46. HttpPost httpPost = new HttpPost(WxpayConfig.unifiedorder);
  47. StringEntity entity;
  48. //预支付id
  49. String prepay_id ="";
  50. //当trade_type为NATIVE获取扫码支付连接
  51. String code_url = "";
  52. try {
  53. entity = new StringEntity(xml, "utf-8");
  54. httpPost.setEntity(entity);
  55. CloseableHttpResponse httpResponse;
  56. // post请求
  57. httpResponse = closeableHttpClient.execute(httpPost);
  58. HttpEntity httpEntity = httpResponse.getEntity();
  59. if (httpEntity != null) {
  60. // 打印响应内容
  61. String result = EntityUtils.toString(httpEntity, "UTF-8");
  62. // 过滤
  63. result = result.replaceAll("<![CDATA[|]]>", "");
  64. Map<String, String> map = XMLUtil.doXMLParse(result);
  65. if(map != null){
  66. prepay_id = (String) map.get("prepay_id");
  67. }
  68. }
  69. // 释放资源
  70. closeableHttpClient.close();
  71. } catch (Exception e) {
  72. e.printStackTrace();
  73. }
  74. //获取prepay_id后,拼接最后请求支付所需要的package
  75. if(prepay_id == null || "".equals(prepay_id) ){//请求数据出错
  76. resMap.put("payMsg",new HashMap());
  77. }else {
  78. TreeMap<String, String> finalpackage = new TreeMap<String, String>();
  79. String timestamp = WxUtil.getTimeStamp();
  80. String packages = "prepay_id="+prepay_id;
  81. finalpackage.put("appId", WxpayConfig.appid);
  82. finalpackage.put("timeStamp", timestamp);
  83. finalpackage.put("nonceStr", nonce_str);
  84. finalpackage.put("package", packages);
  85. finalpackage.put("signType", "MD5");
  86. String paySign = WxUtil.createSign(finalpackage);
  87. finalpackage.put("paySign",paySign);
  88. resMap.put("payMsg", finalpackage);
  89. }
  90. //请求数据无误,可生成预支付订单写入数据库
  91. return resMap;
  92. }

至此跨公众号支付就完成了,在上面的代码中用到了一些工具类,可根据自己去修改。也可以去下载 http://download.csdn.net/detail/yusewuhen/9561633

发表评论

表情:
评论列表 (有 0 条评论,105人围观)

还没有评论,来说两句吧...

相关阅读

    相关 公众支付

    先说下我的需求。我有两个公众号(不是订阅号,订阅号无法向公众号支付)分别为A和B,现在我关注公众号A,在公众号A中需要发起公众号B的支付,也就是说我在公众号A中向公众号B支付钱

    相关 公众支付

    最重要:公众号必须有支付权限 具体如何查看请百度 先配置一下 否则开发很蛋疼 楼主这几天都在蛋疼中 1.在公众号中获取 appid, mch