Java开发微信Navicat支付完整版
一:准备工作
1:先去微信公众平台注册一个公众号,选择服务号
2:去微信商户平台注册一个商户号,用于收款
3:在商户号中配置对应的公众号的APPID
4:支付结果异步通知(需要重点注意)
注意:请先详细查看官方文档按步骤开发,一切以官方文档为主 微信Navicat支付官方文档
5:测试的时候一定要使用内网穿透软件,否则回调时会报错
二:开发代码
WeChatPayConfig:
publicclassWeChatPayConfig{ //公众号APPID privateStringAPPID=""; //商户号KEY privateStringKEY=""; //商户号ID privateStringMCHID=""; //支付完成后微信回调地址,需要外网能访问要是域名,不能是127.0.0.1跟localhost privateStringNOTIFY_URL=""; }
WeChatPayServcie:
publicinterfaceWeChatPayServcie{ //微信支付下单 publicMapgetWxpayUrl(Map sourceMap); //订单查询 publicStringorderQuery(Stringout_trade_no); }
@Service publicclassWeChatPayServiceImplimplementsWeChatPayServcie{ /** *微信支付请求 *@paramsourceMap *@return */ publicMapgetWxpayUrl(Map sourceMap){ SortedMap signParams=newTreeMap (); Stringnonce_str=UUID.randomUUID().toString().trim().replaceAll("-",""); signParams.put("appid",PayConfig.APPID); signParams.put("mch_id",PayConfig.MCHID); signParams.put("nonce_str",sourceMap.get("nonce_str")); signParams.put("product_id",sourceMap.get("prod_id")); signParams.put("body",sourceMap.get("body")); signParams.put("out_trade_no",sourceMap.get("out_trade_no")); signParams.put("total_fee",sourceMap.get("total_fee")); signParams.put("spbill_create_ip",WxUtil.getIp()); signParams.put("notify_url",PayConfig.NOTYFLY_URL); signParams.put("trade_type","NATIVE"); Stringsign=WxUtil.createSign(signParams,PayConfig.KEY); signParams.put("sign",sign); StringxmlPackage=WxUtil.parseMapXML(signParams); Map resultMap=newHashMap(); try{ Stringresult=HttpUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder",xmlPackage); resultMap=WxUtil.parseXmlMap(result); }catch(Exceptione){ e.printStackTrace(); } StringreturnCode=(String)resultMap.get("return_code"); StringreturnMsg=(String)resultMap.get("return_msg"); if(returnCode.equalsIgnoreCase("FAIL")){ thrownewRuntimeException(returnMsg); } Stringresult_code=(String)resultMap.get("result_code"); if(result_code.equalsIgnoreCase("FAIL")){ thrownewRuntimeException(resultMap.get("err_code_des")); } Stringcode_url=(String)resultMap.get("code_url"); Map map=newHashMap<>(); map.put("code_url",code_url); map.put("out_trade_no",sourceMap.get("out_trade_no")); returnmap; } /** *微信支付订单查询 *@paramout_trade_no *@return */ publicStringorderQuery(Stringout_trade_no){ Stringnonce_str=UUID.randomUUID().toString().trim().replaceAll("-",""); SortedMap signParams=newTreeMap<>(); signParams.put("appid",payConfig.getWeChatPorpetties().getAppId()); signParams.put("mch_id",payConfig.getWeChatPorpetties().getMchId()); signParams.put("out_trade_no",out_trade_no); signParams.put("nonce_str",nonce_str); Stringsign=WxUtil.createSign(signParams,payConfig.getWeChatPorpetties().getApiKey()); signParams.put("sign",sign); StringxmlPackage=WxUtil.parseMapXML(signParams); Map resultMap=newHashMap(); try{ Stringresult=HttpUtil.post("https://api.mch.weixin.qq.com/pay/orderquery",xmlPackage); resultMap=WxUtil.parseXmlMap(result); }catch(Exceptione){ e.printStackTrace(); thrownewRuntimeException("渠道网络异常"); } StringreturnCode=(String)resultMap.get("return_code"); StringreturnMsg=(String)resultMap.get("return_msg"); if(returnCode.equalsIgnoreCase(PayContants.FAIL)){ thrownewRuntimeException(returnMsg); } Stringresult_code=(String)resultMap.get("result_code"); if(result_code.equalsIgnoreCase(PayContants.FAIL)){ thrownewRuntimeException(resultMap.get("err_code_des")); } Stringtrade_state=(String)resultMap.get("trade_state"); returntrade_state; } }
WeChatPayController:
/** *微信支付接口 */ @Controller publicclassWxPayController{ @Autowired WeChatPayServcieweChatPayServcie; /** *微信支付下单 *payID可以不用传自己生成32位以内的随机数就好,要保证不重复 *totalFee金额一定要做判断,判断这笔支付金额与数据库是否一致 */ @RequestMapping("pay") @ResponseBody publicMaptoWxpay(HttpServletRequesthttpRequest,StringpayId,StringtotalFee,Stringbody){ System.out.println("开始微信支付..."); Map map=newHashMap<>(); Stringnonce_str=UUID.randomUUID().toString().trim().replaceAll("-",""); //生成一笔支付记录 //拼接支付参数 Map paramMap=newHashMap<>(); paramMap.put("nonce_str",nonce_str); paramMap.put("prod_id",payId); paramMap.put("body",body); paramMap.put("total_fee",totalFee); paramMap.put("out_trade_no",payId); //发送支付请求并获取返回参数与二维码,用于支付与调用查询接口 Map returnMap=weChatPayServcie.getWxpayUrl(paramMap); httpRequest.setAttribute("out_trade_no",payId); httpRequest.setAttribute("total_fee",totalFee); //code_url就是二维码URL,可以把这个URL放到草料二维码中生成微信二维码 httpRequest.setAttribute("code_url",returnMap.get("code_url")); map.put("out_trade_no",payId); map.put("total_fee",String.valueOf(bigDecimal)); map.put("code_url",returnMap.get("code_url")); returnmap; } /** *查询微信订单 *ot_trade_no是支付 */ @RequestMapping("query") @ResponseBody publicRoot orderQuery(Stringout_trade_no){ returnweixinPayServcie.orderQuery(queryCallbackForm.getOut_trade_no()); } /** *微信支付回调,这个地址就是Config中的NOTYFLY_URL */ @RequestMapping("callback") publicvoidnotify_url(HttpServletRequestrequest,HttpServletResponseresponse)throwsDocumentException,ServletException,IOException,Throwable{ System.out.print("微信支付回调获取数据开始..."); StringinputLine; StringnotityXml=""; try{ while((inputLine=request.getReader().readLine())!=null){ notityXml+=inputLine; } request.getReader().close(); }catch(Exceptione){ WxUtil.sendXmlMessage(request,response,PayContants.FAIL); thrownewRuntimeException("回调数据xml获取失败!"); } if(StringUtils.isEmpty(notityXml)){ WxUtil.sendXmlMessage(request,response,PayContants.FAIL); thrownewRuntimeException("回调数据xml为空!"); } Map resultMap=XMLParse.parseXmlMap(notityXml); StringreturnCode=(String)resultMap.get("return_code"); StringreturnMsg=(String)resultMap.get("return_msg"); if(returnCode.equalsIgnoreCase(PayContants.FAIL)){ WxUtil.sendXmlMessage(request,response,PayContants.FAIL); thrownewRuntimeException(returnMsg); } StringresultCode=(String)resultMap.get("result_code"); if(resultCode.equalsIgnoreCase(PayContants.FAIL)){ WxUtil.sendXmlMessage(request,response,PayContants.FAIL); thrownewRuntimeException(resultMap.get("err_code_des")); } SortedMap paramMap=newTreeMap<>(); paramMap.put("appid",resultMap.get("appid")); paramMap.put("mch_id",resultMap.get("mch_id")); paramMap.put("nonce_str",resultMap.get("nonce_str")); paramMap.put("body",resultMap.get("body")); paramMap.put("openid",resultMap.get("openid")); paramMap.put("is_subscribe",resultMap.get("is_subscribe")); paramMap.put("trade_type",resultMap.get("trade_type")); paramMap.put("bank_type",resultMap.get("bank_type")); paramMap.put("total_fee",resultMap.get("total_fee")); paramMap.put("fee_type",resultMap.get("fee_type")); paramMap.put("cash_fee",resultMap.get("cash_fee")); paramMap.put("transaction_id",resultMap.get("transaction_id")); paramMap.put("out_trade_no",resultMap.get("out_trade_no")); paramMap.put("time_end",resultMap.get("time_end")); paramMap.put("return_code",resultMap.get("return_code")); paramMap.put("return_msg",resultMap.get("return_msg")); paramMap.put("result_code",resultMap.get("result_code")); Stringout_trade_no=(String)resultMap.get("out_trade_no"); Stringsign=SignUtil.createSign(paramMap,WxPayConfig.KEY); StringmySign=(String)resultMap.get("sign"); //回调一定要验证签名以防数据被篡改 if(sign.equals(mySign)){ System.out.println("回调签名验证成功!"); //修改业务逻辑,将那笔支付状态改为已支付 } WxUtil.sendXmlMessage(request,response,PayContants.SUCCESS); }else{ WxUtil.sendXmlMessage(request,response,PayContants.FAIL); thrownewRuntimeException("签名不一致!"); } } }
WxUtil:
packagecom.ys.commons.utils.pay; importjava.io.BufferedWriter; importjava.io.IOException; importjava.io.OutputStream; importjava.io.OutputStreamWriter; importjava.net.InetAddress; importjava.net.UnknownHostException; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; //微信工具类 publicclassWxUtil{ //获取当前IP publicstaticStringgetIp(){ try{ Stringspbill_create_ip=InetAddress.getLocalHost().getHostAddress(); returnspbill_create_ip; }catch(UnknownHostExceptionvar2){ var2.printStackTrace(); return"获取IP失败..."; } } //输出xml格式 publicstaticvoidsendXmlMessage(HttpServletRequestrequest,HttpServletResponseresponse,Stringcontent){ try{ StringcontentXml=""; OutputStreamos=response.getOutputStream(); BufferedWriterresBr=newBufferedWriter(newOutputStreamWriter(os)); resBr.write(contentXml); resBr.flush(); resBr.close(); }catch(IOExceptionvar6){ var6.printStackTrace(); } } //生成sign签名 publicstaticStringcreateSign(SortedMap packageParams,StringKEY){ StringBuffersb=newStringBuffer(); Set >es=packageParams.entrySet(); Iteratorit=es.iterator(); while(it.hasNext()){ Entry entry=(Entry)it.next(); Stringk=(String)entry.getKey(); Stringv=(String)entry.getValue(); if(null!=v&&!"".equals(v)&&!"sign".equals(k)&&!"key".equals(k)){ sb.append(k+"="+v+"&"); } } sb.append("key="+KEY); Stringsign=MD5Util.MD5Encode(sb.toString(),"UTF-8").toUpperCase(); returnsign; } //将map转为xml publicstaticStringparseMapXML(SortedMap map){ StringxmlResult=""; StringBuffersb=newStringBuffer(); sb.append(" "); Iteratorvar3=map.keySet().iterator(); while(var3.hasNext()){ Stringkey=(String)var3.next(); Stringvalue=""; sb.append("<"+key+">"+value+""+key+">"); System.out.println(); } sb.append(" "); xmlResult=sb.toString(); returnxmlResult; } //将xml转为map publicstaticMapparseXmlMap(Stringxml)throwsDocumentException{ Documentdocument=DocumentHelper.parseText(xml); Elementroot=document.getRootElement(); List elementList=root.elements(); Map map=newHashMap(); Iteratorvar5=elementList.iterator(); while(var5.hasNext()){ Elemente=(Element)var5.next(); map.put(e.getName(),e.getText()); } returnmap; } }
发送请求需要推荐一个非常好用的工具,里面各种常用的工具都封装好了hutool,如果想直接复制代码使用也需要引入此工具的maven库
注意:此工具只支持JDK1.7以上至此代码已经完成,有意见建议的都可以留言,后续会更新最完整最新版的PayPal支付,同时有需要的也可以看看博主的支付宝PC支付
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。