微信支付,需要通过微信支付验证
目前,支付仅限服务号,
做微信支付开发,主要看开发文档
统一下单,
订单查询
退款等
1.发起支付,都是通过h5发起的,首先获取prepay_id
发起支付,需要统一下单的prepay_id
SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); parameters.put("appid", ConfigUtil.APPID); parameters.put("mch_id", ConfigUtil.MCH_ID); parameters.put("nonce_str", PayCommonUtil.CreateNoncestr()); parameters.put("body", bodyorder); parameters.put("out_trade_no", outTradeNo);// 用户订单号 parameters.put("total_fee", totalfee);// 标价金额(分) // parameters.put("spbill_create_ip",IpAddressUtil.getIpAddr(request)); parameters.put("spbill_create_ip", "192.168.1.1");// 电脑测试 // parameters.put("spbill_create_ip",NetworkUtil.getIpAddress(request)); parameters.put("notify_url", ConfigUtil.NOTIFY_URL); parameters.put("trade_type", "JSAPI"); parameters.put("openid", openId); String sign = PayCommonUtil.createSign("UTF-8", parameters); parameters.put("sign", sign); String requestXML = PayCommonUtil.getRequestXml(parameters); String result = CommonUtil.httpsRequestR2s(ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML); System.out.println("第一弹数据" + result + "ip地址" + NetworkUtil.getIpAddress(request));
数据为
第一弹数据 <xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx06e68e38fcef451d]]></appid> <mch_id><![CDATA[1427607202]]></mch_id> <nonce_str><![CDATA[vOK9ll6ZylQAOiRV]]></nonce_str> <sign><![CDATA[4D7F2D8D55377493503F8BB9E2F94C8B]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <prepay_id><![CDATA[wx20170105120958d7d94506790707606719]]></prepay_id> <trade_type><![CDATA[JSAPI]]></trade_type> </xml>
2.拿到prepay_id后,就可以发起支付
支付,需要设置测试路径和真实路径,
发起支付,将参数转为json,在放到respond里,然后h5页面从request里取
SortedMap<Object, Object> params = new TreeMap<Object, Object>(); params.put("appId", ConfigUtil.APPID); params.put("timeStamp", Long.toString(new Date().getTime())); params.put("nonceStr", PayCommonUtil.CreateNoncestr()); System.out.println("订单id" + map.get("prepay_id")); params.put("package", "prepay_id=" + map.get("prepay_id")); params.put("signType", ConfigUtil.SIGN_TYPE); String paySign = PayCommonUtil.createSign("UTF-8", params); // params.put("packageValue", "prepay_id="+map.get("prepay_id")); // //这里用packageValue是预防package是关键字在js获取值出错 params.put("paySign", paySign); // paySign的生成规则和Sign的生成规则一致 String json = JSONObject.fromObject(params).toString(); System.out.println("第二弹数据" + json); try { response.setContentType("text/html" + ";charset=UTF-8"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.getWriter().write(json); response.getWriter().flush(); } catch (IOException e) { e.printStackTrace(); } }
上传,支付的html页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>微信支付</title> </head> <body> <!-- <form action="weiChatPayServlet" method="post" > <input type="button" value="确认支付" name="ajaxLoadId" id="test1"/> </form> --> <div> <p> 苏牌皮草</p> <p> 库存18件</p> <p> 原价:8888元</p> <p> 现价:5000</p> <p> <button id="test"> 我要购买</button></p> </div> <script src="js/jquery.min.js"></script> <script src="js/jweixin-1.0.0.js"></script> <script src="js/bootstrap.min.js"></script> <script type="text/javascript"> function checkWeiXinVersion(){ var wechatInfo = navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i) ; if( !wechatInfo ) { alert("本活动仅支持微信") ; } else if ( wechatInfo[1] < "5.0" ) { alert("本活动仅支持微信5.0以上版本") ; } } function onBridgeReady(obj){ WeixinJSBridge.invoke('getBrandWCPayRequest',{ "appId":obj.appId, //公众号名称,由商户传入 "timeStamp":obj.timeStamp, //时间戳,自 1970 年以来的秒数 "nonceStr":obj.nonceStr, //随机串 "package" : obj.package, //<span style="font-family:微软雅黑;">商品包信息</span> "signType" : obj.signType, //微信签名方式: "paySign" : obj.paySign //微信签名 },function(res){ alert(res.err_msg); if(res.err_msg == "get_brand_wcpay_request:ok" ) { window.location.href="http://weixin.xiaowanban.com/WXZ/weichatPay.html"; alert("f成功"); }else{ alert("fail"); window.location.href="http://weixin.xiaowanban.com/WXZ/signup.html"; //<span style="font-family:微软雅黑;">当失败后,继续跳转该支付页面让用户可以继续付款,贴别注意不能直接调转jsp,</span><span style="font-size:10.5pt">不然会报</span><span style="font-size:12.0pt"> system:access_denied。</span> } }); } var basePath ="weiChatPayServlet"; $("#test").one("click",function(){ $.ajax({ type:"POST", url:basePath //<span style="font-family:微软雅黑;">ajax调用微信统一接口获取prepayId</span> }).done(function(data){ alert("数据"+data); console.log("数据为"+data); var obj = eval('(' + data + ')'); //var obj =eval("("+data+")");//转换为json对象 /* if(parseInt(obj.agent)<5){ alert("您的微信版本低于5.0无法使用微信支付"); return; } */ /* //配置微信 wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: obj.appId, // 必填,公众号的唯一标识 timestamp:obj.timeStamp , // 必填,生成签名的时间戳 nonceStr: obj.nonceStr, // 必填,生成签名的随机串 signature: obj.signature,// 必填,签名,见附录1 jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 });*/ checkWeiXinVersion(); if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } }else{ onBridgeReady(obj); } }); }); </script> </body> </html>
支付后,可以登录商户平台查看支付状态
3.支付后要查询自己的订单
在支付时,我会默认存一下,商家生成的订单(商户订单号),一个openid下n那个订单,
商户订单号,要求唯一性,为了测试,我获取的时间戳,但是商用,最好用每秒100000次不同的订单号,自己可以搜
我拿到自己的数据库的商户号后,就去掉订单查询
private String checkOrder(String outTradeNo){ SortedMap<Object,Object> parameters = new TreeMap<Object,Object>(); parameters.put("appid", ConfigUtil.APPID); parameters.put("mch_id", ConfigUtil.MCH_ID); parameters.put("nonce_str", PayCommonUtil.CreateNoncestr()); parameters.put("out_trade_no", outTradeNo);//用户订单号 parameters.put("sign_type", ConfigUtil.SIGN_TYPE); String sign = PayCommonUtil.createSign("UTF-8", parameters); parameters.put("sign", sign); String requestXML = PayCommonUtil.getRequestXml(parameters); String result=null ; Map<String, String> map = null; result =CommonUtil.httpsRequestR2s(ConfigUtil.CHECK_ORDER_URL, "POST", requestXML); try { map = XMLUtil.doXMLParse(result); } catch (JDOMException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (map!=null) { String returnCode= map.get("return_code"); String resultCode= map.get("result_code"); if (returnCode.equals("SUCCESS")&&resultCode.equals("SUCCESS")){ // System.out.println("returnCode结果为"+returnCode+"resultCode结果"+resultCode); // System.out.println("支付状态"+map.get("trade_state")); return map.get("trade_state"); }else { return "noArrivePay";//为发起支付,没有到输入密码处直接退出 } }else{ return null; } }
直要查到为支付成功,就修改数据库,支付状态
4.微信支付退款,直接看pai,涉及到证书的
测试退款时,也可以自己登陆商户平台退款;
退款的servlet主要代码
SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); parameters.put("appid", ConfigUtil.APPID); parameters.put("mch_id", ConfigUtil.MCH_ID); parameters.put("nonce_str", PayCommonUtil.CreateNoncestr()); parameters.put("out_trade_no", outTradeNo);// 用户订单号 parameters.put("out_refund_no", outRefundno);// 商户退款单号 parameters.put("total_fee", totalFee);// 订单金额 parameters.put("refund_fee", refundFee);// 退款金额 parameters.put("op_user_id", ConfigUtil.MCH_ID);// 操作员id parameters.put("sign_type", ConfigUtil.SIGN_TYPE); String sign = PayCommonUtil.createSign("UTF-8", parameters); parameters.put("sign", sign); String requestXML = PayCommonUtil.getRequestXml(parameters); String result = null; Map<String, String> map = null; result = CommonUtil.httpsRequestR2s(ConfigUtil.REFUND_URL, "POST", requestXML); try { map = XMLUtil.doXMLParse(result); } catch (JDOMException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 退款微信证书相关 KeyStore keyStore = null; FileInputStream instream=null; try { keyStore = KeyStore.getInstance("PKCS12"); instream = new FileInputStream(new File("D:/10016225.p12")); keyStore.load(instream, "10016225".toCharArray()); } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CertificateException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext=null; try { sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "10016225".toCharArray()).build(); } catch (KeyManagementException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnrecoverableKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); try { HttpGet httpget = new HttpGet("https://api.mch.weixin.qq.com/secapi/pay/refund"); System.out.println("executing request" + httpget.getRequestLine()); CloseableHttpResponse responseSJT = httpclient.execute(httpget); try { HttpEntity entity = responseSJT.getEntity(); System.out.println("----------------------------------------"); System.out.println(responseSJT.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent())); String text; while ((text = bufferedReader.readLine()) != null) { System.out.println(text); } } EntityUtils.consume(entity); } finally { responseSJT.close(); } } finally { httpclient.close(); } }
退款成功图片
退款成功的数据
退款成功返回 executing requestPOST https://api.mch.weixin.qq.com/secapi/pay/refund HTTP/1.1 ---------------------------------------- HTTP/1.1 200 OK Response content length: 850 <xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx06e68e38fcef451d]]></appid> <mch_id><![CDATA[1427607202]]></mch_id> <nonce_str><![CDATA[tR8oByXN60Xc1C9M]]></nonce_str> <sign><![CDATA[4F9FD6304C7CF37F0DD9B194AA7C6B8A]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <transaction_id><![CDATA[4007112001201701115967786227]]></transaction_id> <out_trade_no><![CDATA[1484126688291]]></out_trade_no> <out_refund_no><![CDATA[20170113161502599000]]></out_refund_no> <refund_id><![CDATA[2007112001201701130741391621]]></refund_id> <refund_channel><![CDATA[]]></refund_channel> <refund_fee>100</refund_fee> <coupon_refund_fee>0</coupon_refund_fee> <total_fee>100</total_fee> <cash_fee>100</cash_fee> <coupon_refund_count>0</coupon_refund_count> <cash_refund_fee>100</cash_refund_fee> </xml>
5.说一下,支付的api准备配置
5.1微信支付需要验证
5.2微信支付,设置秘钥
设置秘钥时,会提醒你,是否安装证书,就是微信验证,发给你的邮件里附件里的cert
6.微信授权,获取openid,网页授权的东西,是最基本的,也要知道
网页授权,获取用户信息
相关推荐
微信开发工具包(微信服务号+微信企业号+微信小程序+微信支付+支付宝支付)。运行最底要求 PHP 版本 5.4 , 建议在 PHP7 上运行以获取最佳性能;目前 WeChatDeveloper 针对 access_token 失效增加了自动刷新机制;...
【新】微信开发工具包(微信服务号+微信企业号+微信小程序+微信支付+支付宝支付)。WeChatDeveloper 是基于 wechat-php-sdk 重构,优化并完善;运行最底要求 PHP 版本 5.4 , 建议在 PHP7 上运行以获取最佳性能;目前...
... ... WeChatDeveloper 针对 access_token 失效... 微信支付(账单、卡券、红包、退款、转账、App支付、JSAPI支付、Web支付、扫码支付等) 支付宝支付(账单、转账、App支付、刷卡支付、扫码支付、Web支付、Wap支付等)
本资料包"【新】微信服务号+微信小程序+微信支付+支付宝支付-WeChatDeveloper.zip"聚焦于这些关键领域,旨在帮助开发者更好地理解和利用微信生态系统。 1. 微信服务号: 微信服务号是微信为企业提供的一个平台,...
这个压缩包"DELPHI微信、支付宝支付(DLL源码)_delphi微信支付开发,delphi微信付款.zip"显然是为了解决这一问题,提供了DLL源码,帮助开发者实现Delphi环境下微信和支付宝的支付功能。 首先,我们来了解DLL(动态...
微信支付是腾讯公司提供的一种在线支付方式,用户可以通过微信APP完成商品或服务的支付。在易语言中实现微信支付,开发者需要集成微信支付SDK,该SDK提供了必要的接口和方法来处理支付请求和回调。在实际操作中,...
总结来说,基于微信服务号的商城应用开发结合了微信庞大的用户基础和电子商务的便利性,通过Vue.js、PHP、Node.js等技术手段,创建了一个集商品浏览、选购、支付、订单管理、个人信息维护于一体的全方位购物平台。...
在JavaWeb开发中,集成微信支付、支付宝支付和银联支付是常见的支付方式,这些支付方式为用户提供了多样化的支付选择,增强了用户体验。下面将详细解释这三个支付平台的集成技术及其关键知识点。 1. **微信支付...
2. **商户平台配置**:在使用微信支付前,开发者需要在微信商户平台上注册并获取必要的认证,如AppID、商户号、支付密钥等,这些信息在源码中通常以配置文件的形式存在。 3. **签名机制**:微信支付要求所有请求都...
服务商需要先在微信支付平台上注册并获取自己的商户号,然后可以为多个子商户创建账号并管理它们的支付业务。 4. **index.php**:这是项目的入口文件,通常包含了处理用户请求的代码。在这个例子中,index.php可能...
微信支付的接入需要注册成为微信支付商户,获取到APP ID、商户号(MCHID)、API密钥(Key)等关键参数。在SpringBoot项目中,你可以通过微信支付SDK来实现支付功能。主要涉及的接口包括统一下单( UnifiedOrder)...
### 微信支付Java SpringBoot对接开发详解 #### 一、微信支付配置申请 在进行微信支付集成前,首先需要完成微信支付的基本配置申请。这一步骤至关重要,因为只有完成配置后才能获得接入所需的凭证信息。 1. **...
微信的部分接口需要缓存数据在本地,因此配置目录并需要对目录有写权限;我们鼓励大家使用 composer 来管理您的第三方库,方便后期更新操作;WeChatDeveloper 已历经数个线上项目考验,欢迎 fork 或 star 此项目。...
ASP.NET微信支付开发SDK是用于在ASP.NET平台上集成微信支付功能的一个工具包,它使得开发者能够轻松地在自己的网站或应用程序中实现微信支付的功能。微信支付是中国最受欢迎的移动支付方式之一,广泛应用于线上购物...
在这个项目中,Spring可能被用来管理微信支付相关的bean,如支付服务、订单服务等。 3. **Maven**: Maven是一个项目管理工具,用于构建、依赖管理和项目信息管理。在本项目中,Maven负责管理项目的依赖关系,如...
Asp微信支付接口V5是针对ASP(Active Server Pages)开发环境设计的一种微信支付解决方案,它使得ASP开发者能够轻松地集成微信支付功能到他们的网站或应用程序中。在使用这个接口时,开发者需要对微信支付的相关协议...
在开发过程中,使用微信支付提供的沙箱环境进行测试,模拟不同支付场景,确保正式上线前所有功能都能正常工作。 总的来说,这个C++版的微信小程序支付后台系统提供了实现微信支付的基础框架,开发者需要根据具体...
- **配置支付插件**: 在ThinkPHP项目中引入微信支付或支付宝的SDK,设置必要的配置信息如商户号、API密钥等。 - **编写支付控制器**: 创建支付相关的控制器,处理支付请求,生成预支付订单、二维码或支付链接,并...