java实现微信支付与支付宝支付接口

技术标签: java  支付  java支付方面  

因为公司要求需要写支付宝支付与微信支付现在写完了,总结一下:

支付宝支付:

支付宝支付比较简单首先我说一下支付宝支付与微信支付大概的流程,就拿支付宝支付来说(微信同理)

首先去蚂蚁金服注册一下App 具体流程官方有,看下官方给的帮助就可以,支付宝支付首先是java服务器端生成预订单然后发送给蚂蚁服务器,稍后蚂蚁服务器会返回给你预处理信息,也就是说你生成订单之后请求蚂蚁服务器,有蚂蚁服务器把订单信息加签名之后返回给你,然后你拿着蚂蚁给你加签之后的订单信息直接给APP那边就可以(这里蚂蚁服务器返回的数据是不需要处理的可直接发给APP)然后APP接收到这个信息时会调起支付界面,支付成功之后,就会收到服务器返回给你的信息,支付成功或者失败,这时支付宝会返回结果,也就是异步通知,关于异步通知这里会返回两个,一个是返回给java服务器,一个是返回给APP,感觉返回APP的结果并不是很重要,无论是APP还是java服务器收到结果一定要给支付宝服务器返回结果,不然支付宝会给你发送好多次,发送几次记不清了,官方有说的很详细。这就是支付宝支付的整个流程。

下面是支付宝支付的代码:

支付宝有现成的sdk只要在你的java项目中使用了SDK相信这个支付是非常简单

//括号括起来的部分就是你自己在蚂蚁上边申请的一些配置

 AlipayClient alipayClient = new DefaultAlipayClient(ZhifubaoConfig.URL, ZhifubaoConfig.App_id, ZhifubaoConfig.RSA_PRIVATE_KEY, "json", ZhifubaoConfig.input_charset, ZhifubaoConfig.ALIPAY_PUBLIC_KEY, ZhifubaoConfig.SIGNTYPE);
    AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest ();
    AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
    model.setSubject("缴费订单");
    model.setOutTradeNo(orderNo);
    model.setProductCode("QUICK_MSECURITY_PAY");
    model.setTotalAmount(totalPrice.toString());
    model.setBody(accountNumber);
    model.setPassbackParams(coinNum.toString());
    request.setNotifyUrl(ZhifubaoConfig.Notify_url);
    request.setBizModel(model);
    String orderStr = "";
    try {
        //这里和普通的接口调用不同,使用的是sdkExecute
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        orderStr = response.getBody();
        System.out.println(orderStr);//就是orderString 可以直接给客户端请求,无需再做处理。
    } catch (AlipayApiException e) {
        e.printStackTrace();
    }
    return orderStr;
}
这个就是支付宝提供的sdk使用起来很方便,因为人家都给你写好了拿来直接使用就可以,以上代码是由java

服务器产生订单然后发给支付宝服务器由服务器帮你创建待支付订单,也就是上边说的订单加签直接返回给APP就能让APP唤醒支付宝支付。

关于微信及支付:微信支付我在微信支付官网找了半天也没找带微信提供的sdk(可能是因为知己笨吧)

微信生成预处理订单代码:

 public static SortedMap<Object, Object> createWxPayParam(String orderNo, String totalPrice, String accountNumber, Integer coinNum) {
//声明统一下单待签名字符串的map
        SortedMap<Object, Object> wxparameters = new TreeMap<Object, Object>();

        wxparameters.put("appid", WXconfig.appid);//微信开放平台审核通过的应用APPID

        wxparameters.put("mch_id", WXconfig.partner);//微信支付分配的商户号

        String nonce_str = WxUtil.getRandomString(20);

        wxparameters.put("nonce_str", nonce_str);//随机字符串,不长于32位。

        wxparameters.put("body", WXconfig.body);

        //以下注释均为非必要参数,可根据实际情况决定是否需要
        //wxparameters.put("detail", "");//商品详情,非必要参数,根据项目实际需求
        wxparameters.put("attach", coinNum);//附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
        wxparameters.put("device_info", accountNumber);
        //wxparameters.put("fee_type", "");//默认人民币:CNY
        //String time[] = WxUtil.getTime().split(",")
        //wxparameters.put("time_start", time[0]);//订单生成时间
        //wxparameters.put("time_expire", time[1]);//订单失效时间
        //wxparameters.put("goods_tag", "");//商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠(官方api)
        //wxparameters.put("limit_pay", "no_credit");//指定支付方式,no_credit

        wxparameters.put("out_trade_no", orderNo);//商户订单号

        /**
         * 订单总金额  传入的金额暂定为元,则需要*100变成分  int类型
         */
        Integer payMoney = new BigDecimal(totalPrice).multiply(new BigDecimal(100)).intValue();
        wxparameters.put("total_fee", payMoney);//订单总金额 接口中参数支付金额单位为【分】,参数值不能带小数。

        wxparameters.put("spbill_create_ip", WXconfig.spbill_create_ip);//终端IP  用户端实际ip

        wxparameters.put("notify_url", WXconfig.notify_url);//接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。

        wxparameters.put("trade_type", WXconfig.trade_type);//支付类型  只有一个参数APP

        //生成签名
        String sign = WxUtil.createSign("UTF-8", wxparameters);

        Unifiedorder unifiedorder = new Unifiedorder(WXconfig.appid, WXconfig.partner, nonce_str, sign, WXconfig.body, orderNo, payMoney, WXconfig.spbill_create_ip, WXconfig.notify_url, WXconfig.trade_type, accountNumber, coinNum);

        //转成xml形式
        String xmlInfo = HttpXmlUtil.xmlInfo(unifiedorder);

        if (StringUtil.isNull(xmlInfo)) {

            String weixinPost = HttpXmlUtil.httpsRequest(WXconfig.createOrderURL, "POST", xmlInfo).toString();//请求微信

            UnifiedorderResult unifiedorderResult = ParseXMLUtils.jdomParseXml(weixinPost);//解析微信的反馈

            if (unifiedorderResult != null) {

                if ("SUCCESS".equals(unifiedorderResult.getReturn_code())) {

                    //开始拼接App调起微信的参数
                    SortedMap<Object, Object> wxAppparameters = new TreeMap<Object, Object>();
                    wxAppparameters.put("appid", unifiedorderResult.getAppid());
                    wxAppparameters.put("partnerid", unifiedorderResult.getMch_id());
                    wxAppparameters.put("prepayid", unifiedorderResult.getPrepay_id());
                    wxAppparameters.put("package", WXconfig.wx_package);
                    wxAppparameters.put("noncestr", WxUtil.getRandomString(20));
                    wxAppparameters.put("timestamp", String.valueOf(new Date().getTime()).substring(0, 10));
                    wxAppparameters.put("sign", WxUtil.createSign("UTF-8", wxAppparameters));
                    //String finalsign = WxUtil.createSign("UTF-8", wxparameters);
                    //Map<Object, Object> maps = new HashMap();
                   // maps.put("msg", WXconfig.wx_msg);
                   // maps.put("appid", WXconfig.appid);
                   // maps.put("timestamp", String.valueOf(new Date().getTime()).substring(0, 10));
                   // maps.put("noncestr", nonce_str);
                   // maps.put("partnerid", WXconfig.partner);
                   // maps.put("prepayid", unifiedorderResult.getPrepay_id());
                   // maps.put("package", WXconfig.wx_package);
                   // maps.put("sign", finalsign);
                    return wxAppparameters;
                } else {
                    logf.error("错误原因为:" + unifiedorderResult.getReturn_msg());
                    return null;
                }
            } else {
                logf.error("服务端请求微信的返回值异常。");
                return null;
            }
        } else {
            logf.error("微信参数转成的xml形式错误");
            return null;
        }

    }
Unifiedorder.java代码:
**
 * 统一下单提交为微信的参数
 */
public class Unifiedorder {
    private String appid;//微信分配的公众账号ID(企业号corpid即为此appId),例如:wxd678efh567hg6787
    private String mch_id;//商户id
    private String nonce_str;//随机字符串:数字+大写字母的组合,32位
    private String sign;//签名
    private String body;//商品或支付单简要描述
    private String out_trade_no;//商户系统内部的订单号
    private int total_fee;//总金额
    private String spbill_create_ip;//APP和网页支付提交[用户端ip],Native支付填调用微信支付API的机器IP。
    private String notify_url;//接收微信支付异步通知回调地址
    private String trade_type;//交易类型:JSAPI,NATIVE,APP
    private String device_info;//设备号
    private Integer attach;//附加数据
    public String getDevice_info() {
        return device_info;
    }

    public void setDevice_info(String device_info) {
        this.device_info = device_info;
    }

    public Integer getAttach() {
        return attach;
    }

    public void setAttach(Integer attach) {
        this.attach = attach;
    }


    public String getAppid() {
        return appid;
    }
    public String getMch_id() {
        return mch_id;
    }
    public String getNonce_str() {
        return nonce_str;
    }
    public String getSign() {
        return sign;
    }
    public String getBody() {
        return body;
    }
    public String getOut_trade_no() {
        return out_trade_no;
    }
    public int getTotal_fee() {
        return total_fee;
    }
    public String getSpbill_create_ip() {
        return spbill_create_ip;
    }
    public String getNotify_url() {
        return notify_url;
    }
    public String getTrade_type() {
        return trade_type;
    }
    public void setAppid(String appid) {
        this.appid = appid;
    }
    public void setMch_id(String mch_id) {
        this.mch_id = mch_id;
    }
    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }
    public void setSign(String sign) {
        this.sign = sign;
    }
    public void setBody(String body) {
        this.body = body;
    }
    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }
    public void setTotal_fee(int total_fee) {
        this.total_fee = total_fee;
    }
    public void setSpbill_create_ip(String spbill_create_ip) {
        this.spbill_create_ip = spbill_create_ip;
    }
    public void setNotify_url(String notify_url) {
        this.notify_url = notify_url;
    }
    public void setTrade_type(String trade_type) {
        this.trade_type = trade_type;
    }
    public Unifiedorder(String appid, String mchId, String nonceStr,
                        String sign, String body, String outTradeNo, int totalFee,
                        String spbillCreateIp, String notifyUrl, String tradeType,String accountNumber,Integer coinNum ) {
        super();
        this.appid = appid;
        mch_id = mchId;
        nonce_str = nonceStr;
        this.sign = sign;
        this.body = body;
        out_trade_no = outTradeNo;
        total_fee = totalFee;
        spbill_create_ip = spbillCreateIp;
        notify_url = notifyUrl;
        trade_type = tradeType;
        device_info=accountNumber;
        this.attach=coinNum;
    }
}
HttpXmlUtil.java
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


/**
 * post提交xml格式的参数
 */
public class HttpXmlUtil {

   /**
    * 开始post提交参数到接口
    * 并接受返回
    * @param url
    * @param xml
    * @param method
    * @param contentType
    * @return
    */
   public static String xmlHttpProxy(String url,String xml,String method,String contentType){
      InputStream is = null;
      OutputStreamWriter os = null;

      try {
         URL _url = new URL(url);
         HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
         conn.setDoInput(true);   
         conn.setDoOutput(true);   
         conn.setRequestProperty("Content-type", "text/xml");
         conn.setRequestProperty("Pragma:", "no-cache");  
         conn.setRequestProperty("Cache-Control", "no-cache");  
         conn.setRequestMethod("POST");
         os = new OutputStreamWriter(conn.getOutputStream());
         os.write(new String(xml.getBytes(contentType)));
         os.flush();

         //返回值
         is = conn.getInputStream();
         return getContent(is, "utf-8");
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } finally{
         try {
            if(os!=null){os.close();}
            if(is!=null){is.close();}
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
      return null;
   }

   /**
    * 解析返回的值
    * @param is
    * @param charset
    * @return
    */
   public static String getContent(InputStream is, String charset) {
      String pageString = null;
      InputStreamReader isr = null;
      BufferedReader br = null;
      StringBuffer sb = null;
      try {
         isr = new InputStreamReader(is, charset);
         br = new BufferedReader(isr);
         sb = new StringBuffer();
         String line = null;
         while ((line = br.readLine()) != null) {
            sb.append(line + "\n");
         }
         pageString = sb.toString();
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         try {
            if (is != null){
               is.close();
            }
            if(isr!=null){
               isr.close();
            }
            if(br!=null){
               br.close();
            }
         } catch (IOException e) {
            e.printStackTrace();
         }
         sb = null;
      }
      return pageString;
   }

   /**
    * 构造xml参数
    * @return
    */
   public static String xmlInfo(Unifiedorder unifiedorder){
      //构造xml参数的时候,至少有10个必传参数
      /*
       * <xml>
            <appid>wx2421b1c4370ec43b</appid>
            <body>APP支付测试</body>
            <mch_id>10000100</mch_id>
            <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
            <notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>
            <out_trade_no>1415659990</out_trade_no>
            <spbill_create_ip>14.23.150.211</spbill_create_ip>
            <total_fee>1</total_fee>
            <trade_type>APP</trade_type>
            <sign>0CB01533B8C1EF103065174F50BCA001</sign>
         </xml> 
       */

      if(unifiedorder!=null){
         StringBuffer bf = new StringBuffer();
         bf.append("<xml>");

         bf.append("<appid>");
         bf.append(unifiedorder.getAppid());
         bf.append("</appid>");

         bf.append("<attach>");
         bf.append(unifiedorder.getAttach());
         bf.append("</attach>");

         bf.append("<body>");
         bf.append(unifiedorder.getBody());
         bf.append("</body>");

         bf.append("<device_info>");
         bf.append(unifiedorder.getDevice_info());
         bf.append("</device_info>");

         bf.append("<mch_id>");
         bf.append(unifiedorder.getMch_id());
         bf.append("</mch_id>");

         bf.append("<out_trade_no>");
         bf.append(unifiedorder.getOut_trade_no());
         bf.append("</out_trade_no>");

         bf.append("<nonce_str>");
         bf.append(unifiedorder.getNonce_str());
         bf.append("</nonce_str>");

         bf.append("<notify_url>");
         bf.append(unifiedorder.getNotify_url());
         bf.append("</notify_url>");
         bf.append("<sign>");
         bf.append(unifiedorder.getSign());
         bf.append("</sign>");

         bf.append("<spbill_create_ip>");
         bf.append(unifiedorder.getSpbill_create_ip());
         bf.append("</spbill_create_ip>");

         bf.append("<total_fee>");
         bf.append(unifiedorder.getTotal_fee());
         bf.append("</total_fee>");

         bf.append("<trade_type>");
         bf.append(unifiedorder.getTrade_type());
         bf.append("</trade_type>");

         bf.append("</xml>");
         /*
         bf.append("<time_start><![CDATA[");
         bf.append(unifiedorder.getTime_start());
         bf.append("]]></time_start>");

         bf.append("<time_expire><![CDATA[");
         bf.append(unifiedorder.getTime_expire());
         bf.append("]]></time_expire>");
         
         bf.append("<detail><![CDATA[");
         bf.append(unifiedorder.getDetail());
         bf.append("]]></detail>");

         bf.append("<attach><![CDATA[");
         bf.append(unifiedorder.getAttach());
         bf.append("]]></attach>");
         */
         return bf.toString();
      }

      return "";
   }


   
   
   /**
    * post请求并得到返回结果
    * @param requestUrl
    * @param requestMethod
    * @param output
    * @return
    */
   public static String httpsRequest(String requestUrl, String requestMethod, String output) {
      try{
         URL url = new URL(requestUrl);
         //打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream
         HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
         //如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true
         connection.setDoOutput(true);
         //打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true
         connection.setDoInput(true);
         /*
          * 有些协议用于文档缓存。有时候能够进行“直通”并忽略缓存尤其重要,
          * 例如浏览器中的“重新加载”按钮。如果连接中的 UseCaches 标志为 true,
          * 则允许连接使用任何可用的缓存。如果为 false,则忽略缓存。
          * 默认值来自 DefaultUseCaches,它默认为 true。 
          */
         connection.setUseCaches(false);
         //设置 URL 请求的方法, 
         connection.setRequestMethod(requestMethod);
         if (null != output) {
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(output.getBytes("UTF-8"));
            outputStream.close();
         }
         // 从输入流读取返回内容
         InputStream inputStream = connection.getInputStream();
         InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
         BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
         String str = null;
         StringBuffer buffer = new StringBuffer();
         while ((str = bufferedReader.readLine()) != null) {
            buffer.append(str);
         }
         bufferedReader.close();
         inputStreamReader.close();
         inputStream.close();
         inputStream = null;
         //指示近期服务器不太可能有其他请求。调用 disconnect() 并不意味着可以对其他请求重用此 HttpURLConnection 实例。
         connection.disconnect();
         return buffer.toString();
      }catch(Exception ex){
         ex.printStackTrace();
      }

      return "";
   }
   
   /** 
     * 回调后将结果返回给微信 
     * @param return_code 
     * @param return_msg 
     * @return 
     */  
    public static String backWeixin(String return_code,String return_msg){  
        try{
            StringBuffer bf = new StringBuffer();
            bf.append("<xml>");

            bf.append("<return_code><![CDATA[");
            bf.append(return_code);
            bf.append("]]></return_code>");

            bf.append("<return_msg><![CDATA[");
            bf.append(return_msg);
            bf.append("]]></return_msg>");

            bf.append("</xml>");
            return bf.toString();
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return "";
    }  

}
ParseXMLUtils.java
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;

import cn.jiguang.common.utils.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;



public class ParseXMLUtils {
   
   private static Logger log = Logger.getLogger(ParseXMLUtils.class);

   /**
    * 1、DOM解析
    */
   public static void beginXMLParse(String xml){
      Document doc = null;
      try {
         doc = DocumentHelper.parseText(xml); // 将字符串转为XML

         Element rootElt = doc.getRootElement(); // 获取根节点smsReport

         System.out.println("根节点是:"+rootElt.getName());

         Iterator iters = rootElt.elementIterator("sendResp"); // 获取根节点下的子节点sms

         while (iters.hasNext()) {
            Element recordEle1 = (Element) iters.next();
            Iterator iter = recordEle1.elementIterator("sms");

            while (iter.hasNext()) {
               Element recordEle = (Element) iter.next();
               String phone = recordEle.elementTextTrim("phone"); // 拿到sms节点下的子节点stat值

               String smsID = recordEle.elementTextTrim("smsID"); // 拿到sms节点下的子节点stat值

               System.out.println(phone+":"+smsID);
            }
         }
      } catch (DocumentException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   /**
    * 2、DOM4j解析XML(支持xpath)
    * 解析的时候自动去掉CDMA
    * @param xml
    */
   public static void xpathParseXml(String xml){
      try { 
         StringReader read = new StringReader(xml);
         SAXReader saxReader = new SAXReader();
         Document doc = saxReader.read(read);
         String xpath ="/xml/appid";
         System.out.print(doc.selectSingleNode(xpath).getText());  
      } catch (DocumentException e) {
         e.printStackTrace();
      }  
   }

   /**
    * 3、JDOM解析XML
    * 解析的时候自动去掉CDMA
    * @param xml
    */
   public static UnifiedorderResult jdomParseXml(String xml){
      UnifiedorderResult unifieorderResult = new UnifiedorderResult();
      try { 
         StringReader read = new StringReader(xml);
         // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
         InputSource source = new InputSource(read);
         // 创建一个新的SAXBuilder
         SAXBuilder sb = new SAXBuilder();
         // 通过输入源构造一个Document
         org.jdom.Document doc;
         doc = (org.jdom.Document) sb.build(source);

         org.jdom.Element root = doc.getRootElement();// 指向根节点
         List<org.jdom.Element> list = root.getChildren();

         if(list != null && list.size() > 0){
            boolean flag1 = true;
            boolean flag2 = true;
            for (org.jdom.Element element : list) {
               log.info("key是:"+element.getName()+",值是:"+element.getText());
               
               if("return_code".equals(element.getName())){
                  if("FAIL".equals(element.getText())){
                     flag1 = false;
                  }else{
                     unifieorderResult.setReturn_code(element.getText());
                  }
               }
               
               if("return_msg".equals(element.getName())){
                  if(element.getText() != null && !"OK".equals(element.getText())){
  //微信支付的第一个坑,这里返回了OK,23333
                     log.error("统一下单参数有误,错误原因为:"+element.getText());
                     return null;
                  }
               }
               
               if(flag1){
                  if("appid".equals(element.getName())){
                     unifieorderResult.setAppid(element.getText());
                  }
                  if("mch_id".equals(element.getName())){
                     unifieorderResult.setMch_id(element.getText());
                  }
                  if("nonce_str".equals(element.getName())){
                     unifieorderResult.setNonce_str(element.getText());
                  }
                  if("sign".equals(element.getName())){
                     unifieorderResult.setSign(element.getText());
                  }
                  if("err_code".equals(element.getName())){
                     unifieorderResult.setErr_code(element.getText());
                  }
                  if("err_code_des".equals(element.getName())){
                     unifieorderResult.setErr_code_des(element.getText());
                  }
                  if("result_code".equals(element.getName())){
                     if("FAIL".equals(element.getText())){
                        flag2 = false;
                        log.error("统一下单业务结果有误,无法返回预支付交易会话标识");
                     }else{
                        unifieorderResult.setResult_code(element.getText());
                     }
                  }
               }
               if(flag1 && flag2 && flag2 == true){
                  if("trade_type".equals(element.getName())){
                     unifieorderResult.setTrade_type(element.getText());
                  }
                  if("prepay_id".equals(element.getName())){
                     log.info("统一下单接口成功返回预支付交易会话标识!");
                     unifieorderResult.setPrepay_id(element.getText());
                  }
               }
               
            }
            return unifieorderResult;
         }else{
            return null;
         }

      } catch (Exception e) {
         e.printStackTrace();
         return null;
      }
      
   }

   public static boolean parseInt(String key){
      if(!StringUtils.isEmpty(key)){
         if(key.equals("total_fee")||key.equals("cash_fee")||key.equals("coupon_fee")||key.equals("coupon_count")||key.equals("coupon_fee_0")){
            return true;
         }
      }

      return false;
   }



   


}

上边的微信生成预订单处理有点多,我简单的总结一下什么意思,总体就是说把所有的请求参数都封装成一个实体类,然后通过dom4j转换成微信需要格式的XML然后通过http发送给微信服务器端就可以了。

 以上就是微信与支付宝支付生成预订单处理信息的代码,有些乱。

最后说一下异步回调异步回调处理的不是很好,凑合能用可以再严谨一些

首先支付宝:

@RequestMapping(value = "/ZFBmobilePayNotify")
public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
    logf.debug("进入支付宝回调函数");
    // 获取支付宝POST过来反馈信息
    Map<String, String> params = new HashMap<String, String>();
    Map<String, String[]> requestParams = request.getParameterMap();
    for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
        String name = 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] + ",";
        }
        params.put(name, valueStr);
    }
    // 买家付款账号
    String buyer_logon_id = params.get("buyer_logon_id");
    BigDecimal total_amount = new BigDecimal(params.get("total_amount"));
    // 商户订单号
    String out_trade_no = params.get("out_trade_no");
    // 支付宝交易号
    String trade_no = params.get("trade_no");
    // 交易状态
    String trade_status = params.get("trade_status");
    //商户编号
    String stord_id = params.get("body");
    //充值硬币
    Integer coin_num = Integer.parseInt(params.get("passback_params"));
    String extraParam = "";
    int offset = out_trade_no.indexOf("_");
    if (offset > -1) {
        extraParam = out_trade_no.substring(offset + 1);
        out_trade_no = out_trade_no.substring(0, offset);
    }

    boolean signVerified = AlipaySignature.rsaCheckV1(params, ZhifubaoConfig.ALIPAY_PUBLIC_KEY, ZhifubaoConfig.CHARSET, ZhifubaoConfig.SIGNTYPE); //调用SDK验证签名
    if (signVerified) {
        if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
            Boolean falg = true;
            BigDecimal b2 = new BigDecimal(Double.toString(100));
            total_amount=total_amount.multiply(b2);
            falg = accountCoinService.addPayMoney(stord_id, coin_num, total_amount, "1");
            if (falg == false) {
                logf.debug("APIConsumeController--------------暂无商户记录");
            } else {
                logf.debug("APIConsumeController--------------充值成功");
            }
        } else {
            logf.debug("alipayNotify验证失败——商户订单号:" + out_trade_no + ";支付宝交易号:" + trade_no + ",交易状态:" + trade_status);
            response.getWriter().write("failure");
        }
        response.getWriter().write("success");
    } else {
        response.getWriter().write("failure");
        logf.debug("logError================================支付宝解签失败");
    }
}

下面是微信异步回调:

/**
 * 微信回调函数
 *
 * @param request
 * @param response
 * @return
 */
@RequestMapping(value = "/WXmobilePayNotify")
public void WXalipayNotify(HttpServletRequest request, HttpServletResponse response) {
    SortedMap<Object, Object> parameters = null;
    try {
        parameters = PayOrder.checkWxPayParam(request);
    } catch (Exception e) {
        logf.error("验证微信异步回调出错,错误为:" + e.getMessage());
    }
    if (parameters != null) {
        try {
            response.getWriter().write(HttpXmlUtil.backWeixin("SUCCESS", "OK"));//没有分销
        }catch (Exception e){
            logf.error("====================== notify url error",e);
        }
        Boolean falg = true;
        falg = accountCoinService.addPayMoney(parameters.get("device_info").toString(), Integer.parseInt(parameters.get("attach").toString()), new BigDecimal(parameters.get("total_fee").toString()), "0");
        if (falg) {
            logf.info("充值成功!");
        } else {
            logf.info("充值失败!");
        }
    } else {
        logf.info("微信回调验证失败。可能不是微信发来的通知。");
    }
}

最后说一下异步回调:这个异步回调是你在蚂蚁服务器那边配置的一个地址,这个地址外网必须能访问到,不然不会接收到异步回调通知,不能用 localhost:8080/xxx/xxx



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_36675031/article/details/80392328

智能推荐

整数的3种表达形式及在内存中的存储_哆啦A梦的110的博客-程序员宅基地_整数在内存中的存储形式

整数在内存中存储的是补码整数有3种二进制的表示形式:原码、反码和补码。而整数在内存中存储的是补码。接下来就让我来讲一讲原码、反码和补码的的形式分别是什么吧。对正数而言,其原码、反码和补码都相同。整型,在32位平台下占4个字节,32个比特位如正整数5,它的原码、反码、补码都相同,如下:原码:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1反码:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

使用 Vagrant 打造跨平台开发环境_jiufreeman的博客-程序员宅基地

参考地址1: http://segmentfault.com/blog/fenbox/1190000000264347参考地址2: http://blog.phpor.me/2014/10/12/vagrant-%E6%9C%AC%E5%9C%B0%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83.html 下载的系统是centos6.3 64位: https...

Verilog中常用数据变量类型_Leslie0920的博客-程序员宅基地_verilog变量类型

1.wire型wire型是指整数型,常用来表示用以assign关键字指定的组合逻辑信号。在Verilog程序模块中,输入、输出信号类型默认为wire型。wire型信号可以用做任何方程式的输入,也可以用做assign语句。wire是wire型数据的确认符;[n-1:0]代表该数据的位宽,即该数据有几位,然后后面跟着数据的名字。若一次定义多个数据,可以用逗号隔开,但是最后一个数据名称不用跟逗号。如wire a;/定义一个1位的wire型数据 a/wire[3:0] b;/定义一个4位的wire型

Robotium测试套管理测试用例_weixin_30340353的博客-程序员宅基地

前提:已写好测试用例新建个测试套MyTestSuite管理你需要跑的测试用例,或者将相同功能的测试用例归纳到一个测试套中package com.robotium.test.testsuite;import junit.framework.TestSuite;import com.qunar.test.Test2;import com.qunar.test.test;...

今天大聪明不教你学Java了 | Happy wife,Happy life ( 距离求婚还有七天 )_不肯过江东丶的博客-程序员宅基地

星辰大海,再也不是我想要的远方,看你微笑,才是我最终的梦想。距离求婚还有7天~

js uri解码_js转义字符及URI编码基础知识点_兴兴的小伙伴呐的博客-程序员宅基地

js 转义字符及URI编码详解URL中的转义字符当URL的参数中出现诸如+,空格,/,?,%,#,&amp;,=等特殊字符串符号时,因为上述字符有特殊含义,导致服务器端无法正确解析参数,如何处理?解决办法:将这些字符转化成服务器可以识别的字符。如果要在URL中传递特殊符号的原本意义,要对他们进行编码。编码的格式为:%加字符的ASCII码(16进制),例如空格的编码值是"%20"。URL中特殊符号的...

随便推点

20张高清数据分析全知识地图,拿去吧你_程序媛秃秃的博客-程序员宅基地_数据分析 知识图谱

最近团队小伙伴为大家整理了20张数据分析的知识地图,话不多说直接上图,觉得有用别忘了转发点赞收藏!(还打包成了电子版,文末领)1、数据分析步骤地图2、数据分析基础知识地图3、数据分析技术知识地图4、数据分析业务流程5、数据分析师能力体系6、数据分析思路体系7、电商数据分析核心主题8、数据科学技能书知识地图9、数据挖掘体系10、python学习路径11、线下店铺数据分析12、小程序数据分析13、用户分析14、用户画像法15、Excel常用公式16、

B端产品:通过线上渠道增长_于连林_的博客-程序员宅基地

老于笔记·11.29征服畏惧建立自信的最快最确实的方法,就是去做你害怕的事,直到你获得成功的经验。前言疫情让我们越来越重视线上流量。作为B端产品的市场运营,每天我有多少流量,从哪些地方来、...

catboost和xgboost_Catboost:超越Lightgbm和XGBoost的又一个boost算法神器_weixin_39892460的博客-程序员宅基地

原标题:Catboost:超越Lightgbm和XGBoost的又一个boost算法神器机器学习AI算法工程 公众号:datayx今天介绍一个超级简单并且又极其实用的boosting算法包Catboost,据开发者所说这一boosting算法是超越Lightgbm和XGBoost的又一个神器。论文链接https://arxiv.org/pdf/1706.09516.pdf它可以很容易地与谷歌的Te...

网站高并发解决方案(理论知识)_非凡的世界的博客-程序员宅基地_高并发网站解决方案

一:mysql方面mysql方面,我们主要要从以下几点去考虑:1:索引mysql其实没有想象中的那么差,相反,mysql表数据,只要查到了索引,都不会慢,(1.5亿数据表查索引0.0几秒),所以mysql索引是个好东西,用好之后,查询效率自然很快,所以,数据表设计,一定要考虑全面,给查询频繁使用的字段增加索引,或者组合索引索引学习传送门https://www.cnblogs.c...

nginx服务器状态,Nginx服务器启用Status状态页面_韩锋裂变营销的博客-程序员宅基地

一、Nginx 服务器开启status页面检测服务状态Nginx可以通过with-http_stub_status_module模块来监控Nginx服务器的状态信息。1、通过nginx -V来查看是否有with-http_stub_status_module该模块。[[email protected] ~]# /usr/local/nginx/sbin/nginx -VPS:nginx -V 这里"V"...

浙江万里学院计算机期末考,浙江万里学院 期末考试 练习题.doc_TJNiiiaaann的博客-程序员宅基地

浙江万里学院 期末考试 练习题.doc (25页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!9.90 积分本文档有心友木玩 全国最大的木制玩具批发网提供 官网地址www.xinyours.com木制玩具批发 欢迎所有玩具批发网和经销商来心友木玩 选购木制玩具;我们将以最优惠的价格带给您最大的价值!知识点:参考方向1.说明下列电路中电压的实际方向( )...

推荐文章

热门文章

相关标签