java实现微信支付与支付宝支付接口_带刺的螳螂的博客-程序员宅基地_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

智能推荐

开源API网关系统:Kong简介_秦岭熊猫的博客-程序员宅基地

Kong 是在客户端和(微)服务间转发API通信的API网关,通过插件扩展功能。Kong 有两个主要组件:1、Kong Server :基于nginx的服务器,用来接收 API 请求。2、Apache Cassandra:用来存储操作数据。你可以通过增加更多 Kong Server 机器对 Kong 服务进行水平扩展,通过前置的负载均衡器向这些机器分发请求。根据文档描述,两个Cassa...

使用 F12 开发人员工具调试 HTML 和 CSS(IE浏览器)_jackljf的博客-程序员宅基地

转自:http://msdn.microsoft.com/zh-cn/library/gg699337(v=vs.85).aspx [本文档是初步文档,以后可能更改。]F12 开发人员工具可帮助你查找和修复 HTML 和级联样式表 (CSS) 代码中的错误。如果不使用这些工具,则可能很难在源代码中发现这些错误。 通过在 Windows Internet Explorer 解释源时在文档

NS2:添加一个新的自写协议的方法_高冷喵的博客-程序员宅基地

本文介绍如何在最新版的NS-2.30中嵌入一个自己写的简单新协议,读者可先不必较真协议的具体实现代码,先熟悉嵌入流程因为此代码还是有一定bug的,但实现一个协议的总体框架是对的。后续文章将对如何写一个新协议进行解析,如TCL如何传值到C++等。一、编写新协议simple_trans我们在 NS-2.30目录下创建一个文件夹 kgn,目录下有两个文件: simple_trans.h和simp

WIN10系统pycharm 虚拟环境下pip install 失败问题_qq_39992916的博客-程序员宅基地

使用pycharm工具下载安装flask依赖的包的时候报错,pycharm中event log detail提示如下。Try to run this command from the system terminal. Make sure that you use the correct version of 'pip' installed for your Python interpreter l...

极客 Play 玩 Terminal——GitHub 热点速览 Vol.40_削微寒的博客-程序员宅基地

作者:HelloGitHub-小鱼干多少人以为暗黑的终端便是一名程序员的工作台,其实上,终端可以不只是一个输入 command 的界面,也可以是本周特推 kb 一样,面向极客的极简命令行...

sap 事务代码跳过权限检查_u010812593的博客-程序员宅基地

在有些时候我们输入某些事务代码来完成一些业务操作,例如业务人员告诉开发人员某某事物代码有问题,让你查查看,当你输入业务人员给你的事物代码时却提示没有权限,可以通过函数ALINK_CALL_TRANSACTION跳过权限检查。step1:se37 输入函数名ALINK_CALL_TRANSACTION step2:在导入参数TRANSACTIONNAME中输入T-CODE

随便推点

驰骋工作流发起前置导航设置系列_weixin_34117522的博客-程序员宅基地

为什么80%的码农都做不了架构师?&gt;&gt;&gt; ...

dellR720xd服务器做raid安装操作系统_爱辉弟啦的博客-程序员宅基地_r720xd装系统

连接显示器然后开机服务器会先进行加载。先做RAID1.开机出现这个的时候按住Ctrl+R就会进入删除之前做的RAID,新机器不用操作此步骤创建RAID按F2选择raid级别生效做RAID5和RAID1差不多选择raid1做为boot,应用一下按esc退出进行重启开机后按F11会进入这个界面选这个,具体也根据你自己的引导设备进行选择后续Cent...

java对象的深度复制_JAVA 对象深度复制实现_林伯权的博客-程序员宅基地

JAVA 有两种深度复制实现方式,分别是实现Cloneabel接口,并在接口函数中为每个属性调用Cloneable,也可以通过序列化的方式来实现。package JAVAImprove;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import ...

火星城规划指南_智能交通技术的博客-程序员宅基地

火星移民之梦即将实现文章来源丨AssBook设计食堂胖五飞天了!下一步火星登录还会远吗?前些天,人民日报发布了「中国航天2020年硬核预告」。除了“硬核通货”航空登月外,还有个让人十分好奇...

python停用词_python 去停用词_weixin_39603995的博客-程序员宅基地

原博文2017-05-25 09:20 −Try caching the stopwords object, as shown below. Constructing this each time you call the function seems to be the bottleneck. from nltk.corpus impo...04220相关推荐2019-12-23 11:07...

windows xp 环境下 Oracle8i 双击安装文件无反应的解决办法_dekhjgdfv895375041的博客-程序员宅基地

今天调试一份比较老的程序,数据库用的是Oracle8i,在本地xp系统上搞了半天,双击安装文件就是没反应!在网上整理了一下解决办法:1、将ORACLE软件拷贝到硬盘。 (比如我拷贝到:F:\Oracle8i)2、将硬盘目录文件F:\Oracle8i\stage\Components\oracle.swd.jre\1.1.7.24\1\DataFiles\Expanded\jre\...

推荐文章

热门文章

相关标签