Java微信支付和支付宝支付

java集成微信支付(完整流程)
1.申请微信支付能力

 * 要想使用微信支付能力,不管是app支付、公众号支付、h5支付等支付方式都需要先在微信商户平台申请开通支付能力。
 * 申请开通支付能力的资料有公司营业执照、负责人身份证正反面等图片,相关所需的所有资料在微信官方商户平台上有说明。
 * 申请完开通支付能力后,我们会得到商户号以及appId,然后设置32位官方密钥。
1
2
3
2.准备工作

  * 如果你是h5支付,还需要去微信商户平台设置支付URL的IP或者域名,一般最多可以设置5个IP或者域名,建议同时将正式环境和测试环境的IP或者域名设置好。
  * 如果你是公众号支付,同上,你也需要设置你的支付IP或者域名,注意,异步通知的URL也要在你设置的IP或者域名下。
1
2
3.开始集成

 *** APP支付**
 
     支付集成流程如下:
     步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。(app端向服务端发起请求)
     步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。(服务端向微信请求)
     步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay(将微信回传的prepayid与其他参数组合返回给app端)
     步骤4:商户APP调起微信支付。(app端利用服务端回传的参数调起微信支付)
     步骤5:商户后台接收支付通知。(微信将支付结果异步通知服务端)
     步骤6:商户后台查询支付结果。(微信将支付结果同步通知app端)
     上代码:
   


 DecimalFormat df = new DecimalFormat("######0.00"); 
    //根据订单id查询出该订单的金额
    money=df.format(Double.parseDouble(okamiOrder.getReallMoney()));
    //定义返回值
    ReturnValue    rv=new ReturnValue();
    String token=request.getParameter("token");
    //当前用户的id
    String userId=TokenParmValue.getUserId(token);
    //开始组装调用统一下单接口所需的参数
    String currTime = TenpayUtil.getCurrTime();
    // 8位日期
    String strTime = currTime.substring(8, currTime.length());
    // 四位随机数
    String strRandom = TenpayUtil.buildRandom(4) + "";
    // 10位序列号,可以自行调整。
    String strReq =strTime+strRandom;
    SONObject retMsgJson = new JSONObject();
   //应用配置
    String  appId="";                //appid
    String  appSecret="";            //微信支付appsecret
    String  partner="";              //微信商户号
    String  partnerkey="";           //api密钥
    //定义应用支付配置
    appId=WeixinPayUtil.appid;
    appSecret=WeixinPayUtil.appsecret;
    partner=WeixinPayUtil.partner;
    partnerkey=WeixinPayUtil.partnerkey;
   //********************************************当前微信支付业务处理开始
    // 时间戳加后四位随机数作为商户订单号
        String sjbh = RandomUtil.getRandomFileName();
        // 封装参数
        TreeMap<String, String> treeMap = new TreeMap<String, String>();
        // 微信支付所需要的appId
        treeMap.put("appid",appId);
        // 微信商户号
        treeMap.put("mch_id",partner);
        // 随机数
        treeMap.put("nonce_str", strReq);
        // 订单内容
        treeMap.put("body",subject);
        // 商户订单号
        treeMap.put("out_trade_no", sjbh);
        // 终端ip(下单生成机器的ip),可以获取支付接口的请求IP
        treeMap.put("spbill_create_ip", Property.getProperty("weixinIp"));
        // 订单金额
        treeMap.put("total_fee",money);
        // 支付类型            
        treeMap.put("trade_type",WeixinPayUtil.trade_type);
        // 微信异步通知地址
        treeMap.put("notify_url",Property.getProperty("okamiWeixinUrl").trim());
        //禁止充值的时候使用信用卡
        if("3".equals(payType)){
            treeMap.put("limit_pay","no_credit");   
        }
        StringBuilder sb = new StringBuilder();
        for (String key : treeMap.keySet()) {
            sb.append(key).append("=").append(treeMap.get(key)).append("&");
        }
        sb.append("key="+partnerkey);
        // 获得微信支付验签 
        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appId,appSecret,partnerkey);
        // 参数加签名认证
        String sign = reqHandler.createSign(treeMap);// 获取签名
        treeMap.put("sign", sign);
        StringBuilder xml = new StringBuilder();
        xml.append("<xml>\n");
        for (Map.Entry<String, String> entry : treeMap.entrySet()) {
            if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
                xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
            } else {
                xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
            }
        }
        xml.append("</xml>");
       //开始调用统一下单接口
        String createOrderURL = WeixinPayUtil.createOrderURL;
        String prepay_id = "";
        try {
            // 获得预下单的订单号
            prepay_id = GetWxOrderno.getPayNo(createOrderURL,xml.toString());

        } catch (Exception e1) {
             e1.printStackTrace();
             rv.setResult("error");
             rv.setMsg(ReturnUtil.PAYMENT_FAILURE);
             return new JsonMapper().toJson(rv);
        }
        log.info("微信支付prepay_id的值为:----------------"+prepay_id);
        // 获取到prepayid后对以下字段进行签名最终发送给app
            SortedMap<Object, Object> finalpackage = new TreeMap<Object, Object>();
            String timestamp = Sha1Util.getTimeStamp();
            finalpackage.put("appid",appId);
            finalpackage.put("noncestr", strReq);
            finalpackage.put("partnerid", partner);
            finalpackage.put("timestamp", timestamp);
            finalpackage.put("package", "Sign=WXPay");
            finalpackage.put("prepayid", prepay_id);
            String wenXinSign=WenXinPay.createSign("UTF-8",finalpackage,partnerkey);
            retMsgJson.put("appid",appId);
            retMsgJson.put("timestamp",timestamp);
            retMsgJson.put("noncestr", strReq);
            retMsgJson.put("partnerid",partner);
            retMsgJson.put("prepayid", prepay_id);
            retMsgJson.put("packageX", "Sign=WXPay");
            retMsgJson.put("sign", wenXinSign);
            // 最终给app的参数
            String json = retMsgJson.toString();
            以上是app端发起微信支付,服务端回传app端所需要的参数。

异步通知处理:
         在做异步通知功能之前一定要设计好异步通知功能,防止重复通知,建议通知成功后将记录储存与缓存或者数据库中,以避免重复异步通知。
  @RequestMapping(value = "payment/wechatAsynchronous",method=RequestMethod.POST,produces = "text/html;charset=UTF-8")
@ResponseBody
    public    void   wechatAsynchronous(HttpServletRequest requestWechat,HttpServletResponse response) throws Exception{
        log.info("进入微信异步通知啦"+moduleName+"方法名为:wechatAsynchronous");
        DecimalFormat df = new DecimalFormat("######0.00");
        DecimalFormat dformat = new DecimalFormat("######0");
        requestWechat.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*"); 
        InputStream in = requestWechat.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.close();
        in.close();
        String msgxml = new String(out.toByteArray(), "utf-8");// xml数据
        System.out.println(msgxml);
        log.info("msgxml的值为:-----------------"+msgxml);
        Map map = XmlToMap.xmlToMap(msgxml);
         //过滤空 设置 TreeMap  
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
        Iterator it = map.keySet().iterator();  
        while (it.hasNext()) {  
            String parameter = (String) it.next();  
            String parameterValue = (String) map .get(parameter);  

            String v = "";  
            if(null != parameterValue) {  
                v = parameterValue.trim();  
            }  
            packageParams.put(parameter, v);  
        }  
        log.info("进入微信异步通知啦"+moduleName+"异步通知参数:"+packageParams);
        // 获得支付结果
        String result_code = (String) map.get("result_code");
        // 获得商户订单号
        String out_trade_no = (String) map.get("out_trade_no");
        // 获得订单签名
        String sign = (String) map.get("sign");
        log.info("sign订单签名为:---------------------"+sign);
        //买家实际支付金额
        String total_fee=(String)map.get("total_fee");
        String realMoney=String.valueOf(Double.parseDouble(total_fee)/100);
        // 交易记录表的id
        String tranId = out_trade_no.replace(" ", "");
        log.info("参数 tranId:" + tranId);
        log.info("微信支付的result_code为-----------------------:" + result_code);
        // 根据交易id查询一条交易记录
        Transaction tran = tranService.findById(tranId);
        if(tran!=null){
    
            log.info("tran对象的值不为空:--------------------");
            // 订单表的id
            String orderId = tran.getOrderId();
            log.info("参数订单主键 orderId:" + orderId);
            // 微信支付成功
            if (result_code.equals("SUCCESS")){
               //防止重复通知
                long  size=requestRedisTemplate.boundValueOps("weixinpay:lock:"+out_trade_no).increment(1);
                 requestRedisTemplate.expire("weixinpay:lock:"+out_trade_no,24,TimeUnit.HOURS);
                 if(size==1){
                       log.info("进入微信异步通知啦"+moduleName+"异步通知请求进入!!!");
                     //插入异步通知日志
                    asyncService.insertResrcord("weixin",tran.getUserId(),(String)map.get("transaction_id"),realMoney,tranId);
                     // 财付通订单号
                    String transaction_id = (String) map.get("transaction_id");
                    //获得微支付商户号
                    String  mch_id=(String) map.get("mch_id");
                    //获得微信支付appid---->异步通知
                    String  appid=(String) map.get("appid");
                
                    if(StringUtils.isNotBlank(mch_id)&&StringUtils.isNotBlank(appid)){
                        log.info("商户号与appid不为空");
                        
                        //根据不同的appid校验应用配置
                        //应用1
                        String  appId_local_one=WeixinPayUtil.appid;
                        //应用2
                        String  appId_local_two=WeixinPayUtil.appid_two;
                        //应用3
                        String  appId_local_three=WeixinPayUtil.appid_three;
                        String    partner_local=WeixinPayUtil.partner;
                        String    partnerKey_local=WeixinPayUtil.partnerkey;
                        String    appVersion="1";
                
                        // 验证商户号是否正确
                        if (mch_id.equals(partner_local)) {
                            log.info("微信商户号与appid验证验证成功");
                            //验证签名
                            if(WenXinPay.isTenpaySign("UTF-8", packageParams,partnerKey_local)){
                                        log.info("微信验证签名成功了!!!!!!");
                                        // 业务处理
                                    
                 }else{
                     response.getWriter().write(setXml("FAIL", "ERROR")); 
                    log.info("微信支付异步通知失败了!!!!!!");
                 }
                
            }else{
                response.getWriter().write(setXml("FAIL", "ERROR")); 
                log.info("微信支付异步通知失败了!!!!!!");
            }
    }
    
       //微信异步通知返回xml格式数据
    public static String setXml(String return_code, String return_msg) {
            return "<xml><return_code><![CDATA[" + return_code
                    + "]]></return_code><return_msg><![CDATA[" + return_msg
                    + "]]></return_msg></xml>";
    }

以上就是app支付的所有代码,其中所用的工具类大部分为微信支付开发文档中demo提供,下载地址为:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3        
  ***h5支付**
  
       记得在微信官方商户平台配置好支付域名
       基本流程:
            1、用户在商户侧完成下单,使用微信支付进行支付。
            2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB。
            3、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url调起微信支付中间页。
            4、中间页进行H5权限的校验,安全性检查。
            5、如支付成功,商户后台会接收到微信侧的异步通知。
            6、用户在微信支付收银台完成支付或取消支付,返回商户页面。
            7、商户在展示页面,引导用户主动发起支付结果的查询。
            8,9、商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态。
            10、展示最终的订单支付结果给用户。
    **此处注意微信h5支付最终的结果是提供前端一个支付链接的字符串。**
支付接口代码:


  /**
         * 微信发送支付请求,微信官方h5支付
         * @param paramMap
         * @return
         */
        @Override
        public Result officialSend(Map paramMap){
            Result  result=new Result();
            String pay_url="";
            // 封装参数
            TreeMap<String, String> treeMap = new TreeMap<String, String>();
            // 微信支付所需要的appId
            treeMap.put("appid",WeiXinConstant.official_app_id);
            // 微信商户号
            treeMap.put("mch_id",WeiXinConstant.official_mch_id);
            // 随机数
            treeMap.put("nonce_str",TenpayUtil.getNonceStr());
            // 订单内容
            treeMap.put("body",paramMap.get("productname")+"");
            // 商户订单号
            treeMap.put("out_trade_no",paramMap.get("orderId")+"");
            // 终端ip(下单生成机器的ip)
            treeMap.put("spbill_create_ip",paramMap.get("spbill_create_ip")+"");
            // 订单金额
            treeMap.put("total_fee",new Double(Double.valueOf(paramMap.get("money")+"")*100).intValue()+"");
            // 支付类型            
            treeMap.put("trade_type","MWEB");//h5支付
            // 微信异步通知地址
            treeMap.put("notify_url", PropertiesUtil.getDom()+WeiXinConstant.official_notify_url);
            //业务参数
            treeMap.put("attach",paramMap.get("orderId")+"");
            JSONObject js=new JSONObject();
            JSONObject jb=new JSONObject();
            if("1".equals(paramMap.get("source"))){//安卓
                js.put("type", "Android");
                js.put("app_name", "8wan游戏");
                js.put("package_name", "com.xianqing.sdk");
                jb.put("h5_info", js);
            }else{//ios
                js.put("type", "IOS");
                js.put("bundle_id", "com.xianqing.sdk");
                js.put("app_name", "8wan游戏");
                jb.put("h5_info", js);
            }
            //场景信息
            treeMap.put("scene_info",jb.toString());
            //禁止充值的时候使用信用卡,默认可以使用
            //treeMap.put("limit_pay","no_credit");   
             Map<String,String> params = SignUtils.paraFilter(treeMap);
             StringBuilder buf = new StringBuilder((params.size() +1) * 10);
             SignUtils.buildPayParams(buf,params,false);
             String preStr = buf.toString();
             String sign = MD5.sign(preStr, "&key=" + WeiXinConstant.partnerkey, "utf-8");
             treeMap.put("sign", sign);
             CloseableHttpResponse response = null;
             CloseableHttpClient client = null;
             try {
                 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
                 StringEntity entityParams = new StringEntity(WXPayUtil.mapToXml(treeMap),"utf-8");
                 httpPost.setEntity(entityParams);
                 //httpPost.setHeader("Content-Type", "text/xml;charset=ISO-8859-1");
                 client = HttpClients.createDefault();
                 response = client.execute(httpPost);
                 if(response != null && response.getEntity() != null){
                     Map<String,String> resultMap = WXPayUtil.xmlToMap(new         String(EntityUtils.toByteArray(response.getEntity())));
                     if("SUCCESS".equalsIgnoreCase(resultMap.get("return_code"))){
                         if("SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))){
                             String prepay_id=resultMap.get("prepay_id");
                             String mweb_url=resultMap.get("mweb_url");
                             logger.info("微信官方支付mweb_url:"+mweb_url);
                             String packagevalue="";
                             if(mweb_url.indexOf("&package=")!=-1){
                                 packagevalue=mweb_url.substring(mweb_url.indexOf("&package=")+9,mweb_url.length());
                             }         
                             String type="";
                                if(PropertiesUtil.getDom().indexOf("test")!=-1){
                                   type="1";
                                }else{
                                   type="2";
                                }
                                pay_url=PropertiesUtil.getDom()+"pay/pay_h5_wx.html?prepay_id="+prepay_id+"&packagevalue="+packagevalue+"&type="+type;
                         }
                     }else{
                         logger.info("微信官方h5支付失败,失败原因为:"+resultMap.get("return_msg")); 
                     }
                     logger.info("支付结果为:"+resultMap.toString());
                 }else{
                     logger.info("微信官方h5支付失败,请求未响应");
                 }
             } catch (Exception e) {
                 logger.info("微信官方支付错误信息:"+e.getMessage());
             } finally {
                 if(response != null){
                     try {
                        response.close();
                    } catch (IOException e) {
                         logger.info("微信官方支付,响应关闭错误信息:"+e.getMessage());
                    }
                 }
                 if(client != null){
                     try {
                        client.close();
                    } catch (IOException e) {
                         logger.info("微信官方支付,请求关闭错误信息:"+e.getMessage());
                    }
                 }
             }
             JSONObject job=new JSONObject();
            if(StringUtils.isNotBlank(pay_url)){
                job.put("res",pay_url);
            }else{
                job.put("res","");
            }
            result.setData(job);
            return result;
        }
    注意,微信h5支付接口最终返回给前端是一个支付链接,此链接所在的页面的IP或者域名必须要在你之前在商户平台配置的IP或者域名之下,另外如果是app请求h5支付接口,也同样将此链接返回给app端,最后贴上支付连接中页面的代码:
       
 

        <html>
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta content="width=device-width, initial-scale=1, minimum-scale=1.0, user-scalable=no" name="viewport">
            <title>微信官方h5支付</title>
          <script type="text/javascript">
              function GetRequest() {
                var url = location.search; //获取url中"?"符后的字串
                var theRequest = new Object();
                if (url.indexOf("?") != -1) {
                    var str = url.substr(1);
                    strs = str.split("&");
                    for(var i = 0; i < strs.length; i ++) {
                        theRequest[strs[i].split("=")[0]]=decodeURI(strs[i].split("=")[1]);
                    }
                }
                return theRequest;
              } 
              var Request = new Object();
              Request = GetRequest();
              var prepay_id,packagevalue,type,redirect_url;
              prepay_id = Request['prepay_id'];
              packagevalue = Request['packagevalue'];    
              type=Request['type'];    //环境类型   1测试环境  2正式环境
              //回调地址
              if(type==1){
                redirect_url="http://测试域名/pay/wxreturn.html";
              }else{
                redirect_url="http://正式域名pay/wxreturn.html";
              }
              window.location="https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id="+prepay_id+"&package="+packagevalue+"&redirect_url="+redirect_url;
          </script>
        </head>
        <body>    
        </body>
    </html>

 异步通知代码:
  
     /**
         * 微信支付回调,微信官方h5支付
         * @return
         */
        @Override
            public Result callbackUrlOfficial(HttpServletRequest req) throws Exception{
                 String resString = XmlUtils.parseRequst(req);
                 logger.info("微信官方h5支付回调参数:"+resString);
                 Result result = new Result();
                 if(StringUtils.isNotBlank(resString)){
                     Map<String,String> map = WXPayUtil.xmlToMap(resString);
                     logger.info("微信官方h5支付通知map内容:"+map);
                     String return_code  = map.get("return_code");
                     logger.info("微信官方h5支付异步通知业务结果为:"+return_code);
                     if("SUCCESS".equals(return_code)){//通知状态    SUCCESS:成功  
                       if(map.containsKey("sign")){
                          if(SignUtils.checkParam(map, WeiXinConstant.partnerkey)){//验证签名通过
                            logger.info("微信官方h5支付异步通知签名通过!!!sign-success");  
                            if("SUCCESS".equals(map.get("result_code"))){//支付结果  SUCCESS:成功
                              //业务处理
                                //判断微信支付返回值表中是否存在记录,如果不存在则插入返回信息
                                List<PayResponseBean> list =payServiceImpl.getPayResponse(map.get("out_trade_no"));
                                if(list == null || list.size() == 0){
                                    payServiceImpl.addPayResponse(map.get("out_trade_no"), map.get("transaction_id"), "5", map.toString());
                                    //开始业务处理
                                }
                                return result;
                            }else{
                                logger.info("微信官方h5订单支付失败:平台订单编号orderid="+map.get("attach"));
                                result.setCode(SystemStatus.WX_ORDER_PAY_ERROR.CODE);
                                result.setMsg(SystemStatus.WX_ORDER_PAY_ERROR.MSG);
                                   return result;        
                            }  
                          }else{
                            logger.info("微信官方h5支付回调签名错误:平台订单编号orderid="+map.get("attach"));
                            result.setCode(SystemStatus.WX_SIGN_ERR.CODE);
                            result.setMsg(SystemStatus.WX_SIGN_ERR.MSG+"签名错误");
                               return result;    
                          }  
                       }else{
                           logger.info("微信官方h5支付回调签名不存在:平台订单编号orderid="+map.get("attach"));
                           result.setCode(SystemStatus.WX_SIGN_ERR.CODE);
                           result.setMsg(SystemStatus.WX_SIGN_ERR.MSG+"签名不存在");
                              return result;  
                       }     
                     }else{
                        logger.info("微信官方h5支付异步通知失败,失败原因为"+map.get("return_msg"));
                        result.setCode(SystemStatus.PARAM_ERROR.CODE);
                        result.setMsg(SystemStatus.PARAM_ERROR.MSG);
                        return result;
                     }
                 }else{
                     result.setCode(SystemStatus.PARAM_ERROR.CODE);
                     result.setMsg(SystemStatus.PARAM_ERROR.MSG);
                     return result;
                 }
            }    
   以上就是微信h5支付的所有代码,其中所涉及到的工具类请大家自己在官方开发文档上下载:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4

*公众号支付*
   公众号支付与h5支付类似,只需要将支付方式改成公众号支付方式就行,参考文档为:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3
   同样,公众号支付也是需要在你的公众号后台设置授权域名。
 

**

java集成支付宝(完成流程)
**

*申请支付能力
   1、准备好相关资料在支付宝官网申请你所需要的支付方式,例如app支付,或者h5支付。
   2、获取集成支付能力所需的参数:appid、支付宝公钥与私钥、(seller_id)卖家账号。
   
*开始集成(app支付)


    app支付集成
           DecimalFormat df = new DecimalFormat("######0.00"); 
           //appid
            String  app_id=AlipayConfig.app_id;
            //商户私钥
            String  private_key=AlipayConfig.private_key_refund;
            //支付宝公钥验签
            String  alipay_public_key=AlipayConfig.alipay_public_key;
            //卖家账号
            String  seller_id=AlipayConfig.partner;
            //实例化客户端
            AlipayClientApp alipayClient = new                   DefaultAlipayClientApp("https://openapi.alipay.com/gateway.do", app_id, private_key, "json", "utf-8", alipay_public_key);
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            String tradeId = RandomUtil.getRandomFileName();
            //业务订单主体内容
            model.setBody(body);
            //业务订单描述
            model.setSubject(subject);
            //商户订单号,也就是该笔订单的交易记录主键
            model.setOutTradeNo(tradeId);
            //该订单的商品总价格
            model.setTotalAmount(price);
            //签约卖家的账号
            model.setSellerId(seller_id);  
            //销售产品码
            model.setProductCode("QUICK_MSECURITY_PAY");
            //禁用支付方式     此处充值禁用信用卡支付
            if("3".equals(payType)){
                model.setDisablePayChannels("credit_group");                
            }
            //装载订单的业务参数
            request.setBizModel(model);
            //支付宝异步通知地址
            request.setNotifyUrl(Property.getProperty("noifyUrl").trim()); 
            
             //定义orderString返回给客户端
             String  orderString="";
            try {
                //这里和普通的接口调用不同,使用的是sdkExecute
                AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
                //就是orderString 可以直接给客户端请求,无需再做处理。
                 System.out.println(response.getBody());  
                 orderString=response.getBody();
                } catch (AlipayApiException e) {
                  e.printStackTrace();
            }
        
        异步通知集成开始
        @RequestMapping(value = "pay/ailipayNotify", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
public   @ResponseBody  String  ailipayNotify(HttpServletRequest request){
    log.info("支付宝调用了                Pay treasure to call。。。。。666666666。。。。。。。。");
    log.info("进入支付宝异步通知     Enter the pay treasure to asynchronous notification ******");
    DecimalFormat df = new DecimalFormat("######0.00");
    DecimalFormat dformat = new DecimalFormat("######0");
    //获取支付宝POST过来反馈信息
    Map<String,String> params = new HashMap<String,String>();
    Map requestParams = request.getParameterMap();
    log.info("支付宝异步返回结果为:"+requestParams);
    for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
        String name = (String) iter.next();
        String[] values = (String[]) requestParams.get(name);
        String valueStr = "";
        for (int i = 0; i < values.length; i++) {
            valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
      }
      //乱码解决,这段代码在出现乱码时使用。
      //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
      params.put(name, valueStr);
     }
    //支付宝公钥验签
    String  alipay_public_key=AlipayConfigSecond.ALIPAY_PUBLIC_KEY;
    log.info("异步通知参数为:params"+params);
    //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
    //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
    boolean  alipayFlag=false;
    try {
        //利用支付宝公钥验签
        alipayFlag= AlipaySignatureNew.rsaCheckV1(params, alipay_public_key, "utf-8", "RSA");
    } catch (AlipayApiException e) {
        e.printStackTrace();
        return "response fail";
    }
    //公钥验签通过
    if(alipayFlag){
        log.info("支付宝公钥验签通过了&&&&&&&&&&&&&&&&&&&&&");
        log.info("支付宝异步通知参数内容 :" + params);
        // 商户订单号
        String out_trade_no=params.get("out_trade_no");
        log.info("参数 22:" + out_trade_no);
        // 支付宝交易号
        String trade_no=params.get("trade_no");
        log.info("参数 e:" + trade_no);
        // 交易状态
        String trade_status=params.get("trade_status");
        log.info("参数66786 :" + trade_status);
        // 开发者账号
        String partner = params.get("seller_id");
        log.info("参数697979 :" + partner);
        String total_fee=params.get("receipt_amount");
        log.info("参数  实际支付金额:"+total_fee);
        // 交易记录表的id
        String tranId = out_trade_no.replace(" ","");
        log.info("参数 tranId:" + tranId);
        // 根据交易id查询一条交易记录
        Transaction tran = tranService.findById(tranId);
        
        //根据用户的交易记录判断
        if (tran!=null) {
            // 订单表的id
            String orderId = tran.getOrderId();
            log.info("参数 orderId:" + orderId);
            log.info("支付宝第四步     Pay the asynchronous notification of success  ");
            log.info("支付宝第五步     Pay the asynchronous notification of success  ");
            // 通过验证卖家账号和开发者账号是否是商户
            if (AlipayConfig.partner.equals(partner)){
                log.info("支付宝第六步     Pay the asynchronous notification of success  ");
                if (trade_status.equals("TRADE_FINISHED")||trade_status.equals("TRADE_SUCCESS")) {
                   //防止重复通知
                    long size=requestRedisTemplate.boundValueOps("alipay:lock:"+trade_no).increment(1);
                     requestRedisTemplate.expire("alipay:lock:"+trade_no,93,TimeUnit.DAYS);
                    if(size==1){
                        //插入异步通知日志
                        asyncService.insertResrcord("alipay", tran.getUserId(), trade_no, total_fee, tranId);
                        
                        log.info("支付异步通知成功     Pay the asynchronous notification of success  ");
                        // 支付宝交易号
                        String payNo = trade_no.replace(" ","");
                        // 业务处理
                    
             } else {
                log.info("支付宝异步通知请求失败了呜呜呜呜呜!!!!!"); 
                return "response fail";
            }
        }else{
            return "response fail";
        }
    }else{
        return "response fail";
    }
}else{
    return "response fail";
}
    return "success";
}    

  * 注意,以上所用的工具类都可以在支付宝官方demo中下载,进入开发者中心找到对应语言的demo即可下载。
  * 其他支付方式与此类似。
————————————————
 

java集成支付宝原路退款功能
      * 支付宝原路退款集成需要商户订单号,支付宝交易流水号,以及退款金额(退款金额不得大于订单金额)

  /****
     * 支付宝订单原路退款
     * @param out_trade_no   商户内部订单号
     * @param trade_no       支付宝内部交易流水号
     * @param refund_amount  退款金额,金额不得大于订单金额,最多保留两位小数
     * @return
     */
    public static String aliapyRefund(String out_trade_no,String trade_no,String refund_amount) {
              //appid
            String  app_id=AlipayConfig.app_id;
              //商户私钥
            String  private_key=AlipayConfig.private_key_refund;
              //支付宝公钥验签
            String  alipay_public_key=AlipayConfig.alipay_public_key;
          AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",app_id,private_key,"json","utf-8",alipay_public_key);
          AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
          //订单退款业务参数拼装
          request.setBizContent("{" +"\"out_trade_no\":\""+out_trade_no+"\"," +"\"trade_no\":\""+trade_no+"\","+"\"out_request_no\":\""+"HZ01RF001"+"\"," +"\"refund_amount\":"+refund_amount+"" +"  }");  
          AlipayTradeRefundResponse response=null;
          try {
              response = alipayClient.execute(request);
              log.info("支付宝退款结果展示:"+response);
          } catch (AlipayApiException e) {
              log.info("支付宝退款结果错误内容显示:");
              e.printStackTrace();
          }
          if("10000".equals(response.getCode())){ 
              log.info("支付宝退款成功");
              return "success";   //退款成功
          } else {
              log.info("支付宝退款失败");
              return  "error";   //退款失败
          }
      
    }
    *以上相关支付宝工具类都可以去官方下载

————————————————

java集成微信原路退款功能
 * 注意,微信原路退款需要操作证书,操作证书可以放在项目中,也可以放在远程服务器
     /****
     * @param transactionID  微信订单号,就是微信支付的流水号
     * @param outTradeNo     退款订单的订单号 ,也就是交易记录的主键
     * @param totalFee       订单金额
     * @param refundFee      退款金额,必须小于或等于用户实际支付的金额
     * @param outRefundNo    订单退款的单号,也就是订单的主键
     * @param request
     * @param response
     * @return   success 退款成功   error 退款失败
     * @throws Exception
     */
    public static String weixinRefund(String transactionID,String outTradeNo,String totalFee,String  refundFee,String outRefundNo,String appVersion,HttpServletRequest request,HttpServletResponse response) throws Exception {
        //获得微信退款操作证书当前目录
        String path =request.getSession().getServletContext().getRealPath("/");

        log.info("当前未处理微信退款买家实际支付金额展示:"+totalFee);
     
        RefundReqData  refundData= new RefundReqData();
        String   refundXml=refundData.RefundReqData(transactionID, outTradeNo, outRefundNo, new BigDecimal(totalFee).multiply(new BigDecimal(100)).intValue(), new BigDecimal(refundFee).multiply(new BigDecimal(100)).intValue(),appVersion,request, response);
        log.info("微信退款请求结果xml展示:"+refundXml);
        log.info("当前未处理微信退款买家实际支付金额转int类型展示:"+new BigDecimal(totalFee).multiply(new BigDecimal(100)).intValue());
        try {
            WeixinRefundRequest refundRequest = new WeixinRefundRequest();
            String result = refundRequest.httpsRequest("https://api.mch.weixin.qq.com/secapi/pay/refund", refundXml, path,appVersion);
            log.info("微信退款返回结果:"+result);
            Map<String,String> getMap = WeixinMessage.parseXml(new String(result.toString().getBytes(), "utf-8"));
            if("SUCCESS".equals(getMap.get("result_code"))){ 
                 log.info("微信订单退款原路返回成功!");
                return "success";   //退款成功
            }else{
                 log.info("微信订单退款原路返回失败了呜呜呜!");
                //返回错误描述
                return "error";    //退款失败
            }
        }catch(Exception e){
             log.info("微信订单退款原路返回失败了呜呜呜!");
            e.printStackTrace();
            return "error";       //退款失败
        }
    }

    *  以上所有用到的微信相关工具类都可以去官方网站下载
————————————————
 

发布了29 篇原创文章 · 获赞 66 · 访问量 52万+

猜你喜欢

转载自blog.csdn.net/M_Jack/article/details/104413220