WxPayAppController.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. package com.supplier.controller;
  2. import com.supplier.model.*;
  3. import com.supplier.service.PersonalServce;
  4. import com.supplier.service.SupplierReleaseService;
  5. import com.supplier.service.WxPayService;
  6. import com.supplier.util.ParsingToken;
  7. import com.supplier.util.SnowflakeUtil;
  8. import com.supplier.util.WXPayUtil;
  9. import com.supplier.vx.WxLogin;
  10. import com.supplier.vx.pay.HttpUtil;
  11. import com.supplier.util.PayToolUtil;
  12. import com.supplier.vx.pay.WxPayUtils;
  13. import com.supplier.vx.pay.doXMLParse;
  14. import org.jdom2.JDOMException;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.web.bind.annotation.GetMapping;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.ResponseBody;
  19. import org.springframework.web.bind.annotation.RestController;
  20. import javax.servlet.http.HttpServletRequest;
  21. import javax.servlet.http.HttpServletResponse;
  22. import java.io.*;
  23. import java.math.BigDecimal;
  24. import java.util.*;
  25. /**
  26. * app支付
  27. */
  28. @RestController
  29. @RequestMapping("appPay")
  30. public class WxPayAppController extends WxPayUtils {
  31. private SnowflakeUtil snowflakeUtil = new SnowflakeUtil(1, 1, 1);
  32. @Autowired
  33. private WxPayService wxPayService;
  34. @Autowired
  35. private SupplierReleaseService supplierReleaseService;
  36. @Autowired
  37. private WXLoginController wxLoginController;
  38. @Autowired
  39. private PersonalServce personalServce;
  40. @Autowired
  41. private WxLogin wxLogin;
  42. /**
  43. * app预支付
  44. * @param price 金额
  45. * @return 返回结果
  46. */
  47. @RequestMapping("wxPayApp")
  48. @ResponseBody
  49. public Map<String, Object> wxPayApp(String price, String attach){
  50. Map<String, Object> map = new HashMap<>();
  51. try{
  52. if(price.equals("0")){
  53. map.put("errMsg", "付款金额错误");
  54. map.put("msg", "500");
  55. return map;
  56. }
  57. //拼接参数
  58. WXPayUtil wxPayUtil = new WXPayUtil(); //微信工具类
  59. PayToolUtil payToolUtil = new PayToolUtil();//数据转换工具类
  60. String outTradeNo = wxPayUtil.getOrderNo();
  61. String nonce_str = wxPayUtil.generateNonceStr();
  62. SortedMap<String, String> packageParams = new TreeMap<String, String>();
  63. //获取订单金额
  64. SupplierRelease supplierRelease = new SupplierRelease().setUuid(attach);
  65. List<SupplierRelease> list = supplierReleaseService.getSupplierRelease(supplierRelease);
  66. packageParams.put("appid", APPID);//app_id---需要申请
  67. packageParams.put("attach", attach);//报价单编号
  68. packageParams.put("body", "途丫-" + outTradeNo);//商品参数信息
  69. packageParams.put("fee_type", "CNY");//货币类型
  70. packageParams.put("mch_id", MCHID);//微信商户账号--需要申请
  71. packageParams.put("nonce_str", nonce_str);//32位不重复的编号
  72. packageParams.put("notify_url", NOTIFY_URL);//回调页面--这个是回调接口
  73. packageParams.put("out_trade_no", outTradeNo);//订单编号
  74. packageParams.put("spbill_create_ip", CREATE_IP);//金额
  75. packageParams.put("total_fee", wxPayUtil.getMoney(list.get(0).getPriceAll()));//金额
  76. packageParams.put("trade_type", "APP");//支付类型
  77. // 签名
  78. String sign = payToolUtil.createSign("UTF-8", packageParams, KEY);
  79. packageParams.put("sign", sign);
  80. // 将请求参数转换为xml格式的string
  81. String requestXML = payToolUtil.getRequestXml(packageParams);
  82. // 调用微信支付统一下单接口
  83. String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
  84. //xml返回结果转换
  85. Map<String, String> mapVal = wxPayUtil.xmlToMap(resXml);
  86. if(null == mapVal.get("prepay_id")){
  87. throw new Exception("获取预支付id失败");
  88. }
  89. Map<String, Object> mapVal1 = new HashMap<>();
  90. String time = String.valueOf(wxPayUtil.getCurrentTimestamp());
  91. mapVal1.put("outTradeNo", outTradeNo);//自生成订单号
  92. mapVal1.put("prepayId", mapVal.get("prepay_id"));//微信订单号
  93. mapVal1.put("nonceStr", nonce_str); //不重复编号
  94. mapVal1.put("time", time); //不重复编号
  95. mapVal1.put("sign", wxPayUtil.singGenerate(packageParams, mapVal.get("prepay_id"), KEY, time, nonce_str)); //签名
  96. map.put("msg", "200");
  97. map.put("data", mapVal1);
  98. WxPay wxPay1 = wxPayService.getRefundVal(attach);//获取付该报价单付款的信息
  99. // if(null != wxPay1){
  100. // throw new Exception("请勿重复支付");
  101. // }
  102. //生成uuid
  103. // String uuid = UUID.randomUUID().toString().replace("-", "");
  104. // WxPay wxPay = new WxPay()
  105. // .setUuid(uuid)
  106. // .setMchId(MCHID)
  107. // .setReleaseUuid(attach)
  108. // .setCodeUrl((String) map.get("code_url"))
  109. // .setOutTradeNo(outTradeNo)
  110. // .setTotalFee(price)
  111. // .setBody("途丫-" + outTradeNo);
  112. // wxPayService.pay(wxPay);
  113. }catch (Exception e){
  114. e.printStackTrace();
  115. map.put("msg", "500");
  116. map.put("errMsg", "服务器请求异常,请稍后再试");
  117. }
  118. return map;
  119. }
  120. /**
  121. * app支付回调
  122. * @param request 参数
  123. * @param response 参数
  124. * @return 返回结果
  125. */
  126. @RequestMapping("appNotify")
  127. @ResponseBody
  128. public String appNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
  129. //读取参数
  130. InputStream inputStream ;
  131. StringBuffer sb = null;
  132. try {
  133. sb = new StringBuffer();
  134. inputStream = request.getInputStream();
  135. String s ;
  136. BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
  137. while ((s = in.readLine()) != null){
  138. sb.append(s);
  139. }
  140. in.close();
  141. inputStream.close();
  142. } catch (IOException e) {
  143. e.printStackTrace();
  144. }
  145. //解析xml成map
  146. Map<String, String> mapVal = new HashMap<String, String>();
  147. WXPayUtil wxPayUtil = new WXPayUtil(); //微信工具类
  148. try {
  149. mapVal = wxPayUtil.xmlToMap(sb.toString());
  150. } catch (JDOMException e) {
  151. e.printStackTrace();
  152. } catch (IOException e) {
  153. e.printStackTrace();
  154. }
  155. //过滤空 设置 TreeMap
  156. SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
  157. Iterator it = mapVal.keySet().iterator();
  158. while (it.hasNext()) {
  159. String parameter = (String) it.next();
  160. String parameterValue = mapVal.get(parameter);
  161. String v = "";
  162. if(null != parameterValue) {
  163. v = parameterValue.trim();
  164. }
  165. packageParams.put(parameter, v);
  166. }
  167. //判断签名是否正确
  168. if(PayToolUtil.isTenpaySign("UTF-8", packageParams, KEY)) {
  169. //业务处理
  170. String resXml = "";
  171. if("SUCCESS".equals((String)packageParams.get("result_code"))){
  172. //生成uuid
  173. String uuid = UUID.randomUUID().toString().replace("-", "");
  174. WxPay wxPay = new WxPay()
  175. .setUuid(uuid)
  176. .setReleaseUuid((String)packageParams.get("attach"))
  177. .setFeeType((String)packageParams.get("fee_type"))
  178. .setMchId((String)packageParams.get("mch_id"))
  179. .setNonceStr((String)packageParams.get("nonce_str"))
  180. .setOutTradeNo((String)packageParams.get("out_trade_no"))
  181. .setTotalFee((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "")
  182. .setTradeType((String)packageParams.get("trade_type"))
  183. .setPrepayId((String)packageParams.get("transaction_id"))
  184. .setOpenId((String)packageParams.get("openid"))
  185. .setTimeEnd((String)packageParams.get("time_end"))
  186. .setPayType("微信支付");
  187. //如果自定义参数是gysTopUp则代表的是供应商充值余额
  188. if(((String) packageParams.get("attach")).indexOf("gysTopUp") != -1){
  189. WxPay buySupplier = new WxPay()
  190. .setCode(((String) packageParams.get("attach")).split(",")[2])
  191. .setUuid(((String) packageParams.get("attach")).split(",")[1])
  192. .setTotalFee((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "")
  193. .setPayType("微信支付");
  194. //充值信息入库
  195. WxPay wxPayBuy = new WxPay()
  196. .setCode(((String) packageParams.get("attach")).split(",")[2])
  197. .setUuid(((String) packageParams.get("attach")).split(",")[1])
  198. .setPayType("微信支付")
  199. .setTotalFee((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "");
  200. wxPayService.buySupplierBalance(wxPayBuy);//充值记录
  201. wxPayService.updateBuySupplier(buySupplier); //金额录入
  202. } else if(((String) packageParams.get("attach")).indexOf("gysOfferNum") != -1){ //报价单次数购买
  203. BuyOfferNum buyOfferNum = new BuyOfferNum()
  204. .setCode(((String) packageParams.get("attach")).split(",")[2])
  205. .setUuid(((String) packageParams.get("attach")).split(",")[1])
  206. .setPayAmount((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "")
  207. .setOfferNum(((String) packageParams.get("attach")).split(",")[3])
  208. .setPayType("微信支付");
  209. //购买次数信息入库
  210. BuyOfferNum buyOfferNumAdd = new BuyOfferNum()
  211. .setUuid(((String) packageParams.get("attach")).split(",")[1])
  212. .setOfferNum(((String) packageParams.get("attach")).split(",")[3])
  213. .setCode(((String) packageParams.get("attach")).split(",")[2])
  214. .setPayType("微信支付")
  215. .setPayAmount((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "");
  216. personalServce.addBuyOfferNum(buyOfferNumAdd); //充值记录
  217. wxPayService.updateBuyOfferNum(buyOfferNum);//次数录入
  218. } else { //报价单购买
  219. wxPayService.pay(wxPay);
  220. //修改报价单信息
  221. SupplierRelease supplierRelease = new SupplierRelease().setUuid((String)packageParams.get("attach"));
  222. List<SupplierRelease> list = supplierReleaseService.getSupplierRelease(supplierRelease);
  223. List<SupplierRelease> list1 = supplierReleaseService.getSupplierReleaseType(list.get(0).getDemandUuid());
  224. for(SupplierRelease supplierRelease1 : list1){
  225. //修改定制单状态判断是否是当前报价单的供应商
  226. SupplierRelease supplierRelease2 = new SupplierRelease()
  227. .setCode(supplierRelease1.getCode())
  228. .setDemandUuid(supplierRelease1.getDemandUuid());
  229. if(supplierRelease1.getCode().equals(list.get(0).getCode())){
  230. //修改状态为已付费
  231. supplierRelease2.setOrderType("2");
  232. supplierReleaseService.updatePrivateType(supplierRelease2);
  233. //用户购买报价单后将100%的资金转入供应商余额
  234. Map<String, Object> mapCommis = supplierReleaseService.getSitesInfo();//查询系统配置
  235. BigDecimal bigDecimal = new BigDecimal(wxPay.getTotalFee());//支付金额
  236. BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(mapCommis.get("percentage_fee")));//平台手续费
  237. BigDecimal poundage = bigDecimal.multiply(bigDecimal1);//手续费
  238. //实际金额 - 手续费 = 供应商收入
  239. poundage = bigDecimal.subtract(poundage);
  240. Supplier supplier = new Supplier()
  241. .setCode(list.get(0).getCode())
  242. .setBalanceOf(String.valueOf(poundage));
  243. wxPayService.addSupplierBalanceOf(supplier);
  244. } else {
  245. supplierRelease2.setOrderType("9");
  246. supplierReleaseService.updatePrivateType(supplierRelease2);//修改状态
  247. supplierReleaseService.updateSupplierOffer(supplierRelease2);//返回报价单次数
  248. }
  249. }
  250. }
  251. resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
  252. + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
  253. } else {
  254. resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
  255. + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
  256. return ("fail");
  257. }
  258. try {
  259. BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
  260. out.write(resXml.getBytes());
  261. out.flush();
  262. out.close();
  263. } catch (IOException e) {
  264. e.printStackTrace();
  265. }
  266. } else {
  267. throw new Exception("签名验证失败");
  268. }
  269. return ("success");
  270. }
  271. /**
  272. * 供应商充值小程序
  273. * @param price 金额
  274. */
  275. @GetMapping("wxpaySupplierBalanceJSAPI")
  276. public Map<String, Object> wxpaySupplierBalanceJSAPI(String price, String code, HttpServletRequest request) throws IOException {
  277. //当前时间
  278. String currTime = PayToolUtil.getCurrTime();
  279. String strTime = currTime.substring(8, currTime.length());
  280. String strRandom = String.valueOf(PayToolUtil.buildRandom(4));
  281. String nonce_str = strTime + strRandom;
  282. //获取token
  283. Map<String, Object> userMap = ParsingToken.tokenParsing(request);
  284. //订单号
  285. WXPayUtil wxPayUtil = new WXPayUtil(); //微信工具类
  286. PayToolUtil payToolUtil = new PayToolUtil();//数据转换工具类
  287. String out_trade_no = wxPayUtil.getOrderNo();
  288. SortedMap<String, String> packageParams = new TreeMap<String, String>();
  289. String uuid = snowflakeUtil.nextId() + "";//不重复编号
  290. packageParams.put("appid", wxLogin.getAppIdJSAPI());//公众账号ID
  291. packageParams.put("attach", "gysTopUp" + "," + uuid + "," + userMap.get("code"));//自定义信息
  292. packageParams.put("mch_id", MCHID);//商户号
  293. packageParams.put("body", "途丫-" + out_trade_no);//商品描述
  294. packageParams.put("out_trade_no", out_trade_no);//商户订单号
  295. packageParams.put("nonce_str", nonce_str);//随机字符串
  296. packageParams.put("total_fee", wxPayUtil.getMoney(price)); //订单金额
  297. packageParams.put("spbill_create_ip", CREATE_IP);//终端IP APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
  298. packageParams.put("notify_url", NOTIFY_URL);//通知地址 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数
  299. packageParams.put("trade_type", "JSAPI");
  300. Map<String, Object> mapUser = wxLoginController.wxLoginJSAPI(code);
  301. packageParams.put("openid", (String) mapUser.get("openId"));//支付者
  302. // 签名
  303. String sign = payToolUtil.createSign("UTF-8", packageParams, KEY);
  304. packageParams.put("sign", sign);
  305. // 将请求参数转换为xml格式的string
  306. String requestXML = payToolUtil.getRequestXml(packageParams);
  307. // 调用微信支付统一下单接口
  308. String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
  309. // 解析微信支付结果
  310. Map map = null;
  311. try {
  312. map = doXMLParse.doXMLParse(resXml);
  313. } catch (JDOMException e) {
  314. e.printStackTrace();
  315. } catch (IOException e) {
  316. e.printStackTrace();
  317. }
  318. //返回前端生成二维码
  319. Map<String, Object> resultMap = new HashMap<>();
  320. String time = String.valueOf(wxPayUtil.getCurrentTimestamp());
  321. resultMap.put("outTradeNo", out_trade_no);//自生成订单号
  322. resultMap.put("prepayId", map.get("prepay_id"));//微信订单号
  323. resultMap.put("nonceStr", nonce_str); //不重复编号
  324. resultMap.put("time", time); //不重复编号
  325. resultMap.put("sign", wxPayUtil.singGenerate(packageParams, (String) map.get("prepay_id"), KEY, time, nonce_str)); //签名
  326. resultMap.put("key", KEY);
  327. Map<String, Object> returnMap = new HashMap<>();//返回结果
  328. returnMap.put("data", resultMap);
  329. returnMap.put("msg", "200");
  330. return returnMap;
  331. }
  332. /**
  333. * 供应商购买次数 小程序
  334. * @param offerNum 次数
  335. * @param request 参数
  336. * @return 返回结果
  337. */
  338. @GetMapping("wxpaySupplierOfferNumJSAPI")
  339. public Map<String, Object> wxpaySupplierOfferNumJSAPI(String offerNum, String code, HttpServletRequest request) throws IOException {
  340. //当前时间
  341. String currTime = PayToolUtil.getCurrTime();
  342. String strTime = currTime.substring(8, currTime.length());
  343. String strRandom = String.valueOf(PayToolUtil.buildRandom(4));
  344. String nonce_str = strTime + strRandom;
  345. //获取token
  346. Map<String, Object> userMap = ParsingToken.tokenParsing(request);
  347. Map<String, Object> map1 = personalServce.getByNumber();//获取报价单单价
  348. Map<String, Object> map2 = (Map<String, Object>) map1.get("data");
  349. String price = (Integer.parseInt(offerNum) * Double.parseDouble(String.valueOf(map2.get("power_unit")))) + ""; //购买次数 * 报价单单价
  350. //订单号
  351. WXPayUtil wxPayUtil = new WXPayUtil(); //微信工具类
  352. PayToolUtil payToolUtil = new PayToolUtil();//数据转换工具类
  353. String out_trade_no = wxPayUtil.getOrderNo();
  354. SortedMap<String, String> packageParams = new TreeMap<String, String>();
  355. String uuid = snowflakeUtil.nextId() + "";//不重复编号
  356. packageParams.put("appid", wxLogin.getAppIdJSAPI());//公众账号ID
  357. packageParams.put("attach", "gysOfferNum" + "," + uuid + "," + userMap.get("code") + "," + offerNum);//自定义信息
  358. packageParams.put("mch_id", MCHID);//商户号
  359. packageParams.put("body", "途丫-" + out_trade_no);//商品描述
  360. packageParams.put("out_trade_no", out_trade_no);//商户订单号
  361. packageParams.put("nonce_str", nonce_str);//随机字符串
  362. packageParams.put("total_fee", wxPayUtil.getMoney(price)); //订单金额信息
  363. packageParams.put("spbill_create_ip", CREATE_IP);//终端IP APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
  364. packageParams.put("notify_url", NOTIFY_URL);//通知地址 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数
  365. packageParams.put("trade_type", "JSAPI");//小程序支付
  366. Map<String, Object> mapUser = wxLoginController.wxLoginJSAPI(code);
  367. packageParams.put("openid", (String) mapUser.get("openId"));//支付者
  368. // 签名
  369. String sign = payToolUtil.createSign("UTF-8", packageParams, KEY);
  370. packageParams.put("sign", sign);
  371. // 将请求参数转换为xml格式的string
  372. String requestXML = payToolUtil.getRequestXml(packageParams);
  373. // 调用微信支付统一下单接口
  374. String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
  375. System.out.println(resXml);
  376. // 解析微信支付结果
  377. Map map = null;
  378. try {
  379. map = doXMLParse.doXMLParse(resXml);
  380. } catch (JDOMException e) {
  381. e.printStackTrace();
  382. } catch (IOException e) {
  383. e.printStackTrace();
  384. }
  385. //返回前端生成二维码
  386. Map<String, Object> resultMap = new HashMap<>();
  387. String time = String.valueOf(wxPayUtil.getCurrentTimestamp());
  388. resultMap.put("outTradeNo", out_trade_no);//自生成订单号
  389. resultMap.put("prepayId", map.get("prepay_id"));//微信订单号
  390. resultMap.put("nonceStr", nonce_str); //不重复编号
  391. resultMap.put("time", time); //不重复编号
  392. resultMap.put("sign", wxPayUtil.singGenerate(packageParams, (String) map.get("prepay_id"), KEY, time, nonce_str)); //签名
  393. resultMap.put("key", KEY);
  394. Map<String, Object> returnMap = new HashMap<>();//返回结果
  395. returnMap.put("data", resultMap);
  396. returnMap.put("msg", "200");
  397. return returnMap;
  398. }
  399. }