Alipay, micro-channel pay issue

1. Alipay new version simplifies the code, eliminating the need to own signature configuration parameters, stitching parameters troubles, plain and simple.

    public  static String buildAlipayRequest (AlipayVo alipayVo) { 
        String alipayInfo = null ;
         // instantiate client 
        AlipayClient alipayClient = new new DefaultAlipayClient (ALIPAY_URL, alipayVo.getAppId (), alipayVo.getAppPrivateKey (), 
                the FORMAT, CHARSET_UTF8, alipayVo.getAlipayPublicKey (), sign_type); 
        // instantiate API corresponding to the specific request class corresponding to the class name and an interface name, the current call interface name: alipay.trade.app.pay 
        AlipayTradeAppPayRequest request = new new AlipayTradeAppPayRequest ();
         // the SDK package has lost the common parameters , where only incoming traffic parameters. The following methods sdk embodiment of model parameters into the (case of the model and take biz_content biz_content simultaneously present). 
        AlipayTradeAppPayModel model =new new AlipayTradeAppPayModel (); 
        model.setBody ( "AlipayTrade" ); 
        model.setSubject (alipayVo.getSubject ()); 
        model.setOutTradeNo (alipayVo.getOutTradeNo ()); 
        model.setTimeoutExpress ( "30m" ); 
        model.setTotalAmount (alipayVo .getTotalAmount ()); 
        model.setProductCode ( "QUICK_MSECURITY_PAY" ); 
        request.setBizModel (Model); 
        request.setNotifyUrl (alipayVo.getNotifyUrl ()); 
        the try {
             // here and different common interface calls, using sdkExecute 
            AlipayTradeAppPayResponse = Response alipayClient.sdkExecute (Request); 
            log.info (response.getBody ()); //Is orderString can give the client requests directly, do not need treatment. 
            = alipayInfo response.getBody (); 
        } the catch (AlipayApiException E) { 
            e.printStackTrace (); 
        } 
        return alipayInfo; 
    }

 

2. Because the project uses to filter, resulting in sign signed data in "+" is replaced by "" Can not get the original sign

java.security.SignatureException: Signature length not correct: got 253 but was expecting 256

    Simple treatment is to replace to replace spaces with plus sign

sign = sign.replace(" ", "+");

 

3. Alipay relative to the document, the development of micro-letter more complicated, many of them need to develop their own implementation. Micro-channel tools, for reference.

public class WxpayUtil {

    private static final Logger log = LoggerFactory.getLogger(WxpayUtil.class);
    private static final String GATEURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";


    /**
     * 获取微信预支付prepayid
     * @param weixinpayVo
     * @return
     */
    public static JSONObject buildWxpayRequest(WeixinpayVo weixinpayVo){

        String noncestr = getNonceStr();

        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); 
        Parameters.put ( "AppID", weixinpayVo.getAppid ()); // minute car prices - micro letter assigned public account ID (ie Enterprise corpid do this appId) 
        parameters.put ( "mch_id", weixinpayVo. getMchid ()); // points cheqi - business micro channel number 
        parameters.put ( "nonce_str", noncestr); // random string 
        parameters.put ( "body", weixinpayVo.getSubject ()); // pay content 
        parameters.put ( "out_trade_no", weixinpayVo.getOutTradeNo ()); // merchant Order number 
        parameters.put ( "total_fee", change2Fen (weixinpayVo.getTotalAmount ())); // amount paid, in minutes 
        parameters.put ( "spbill_create_ip", weixinpayVo.getSpbillCreateIp ()) ;// end IP
        parameters.put ( "notify_url", weixinpayVo.getNotifyUrl ()); // asynchronous request address 
        parameters.put ( "trade_type", "APP"); // type of transaction App pay 
        String sign = creatingSign (weixinpayVo.getPartnerKey () , the parameters); // minute car prices - 
        parameters.put ( "Sign" , Sign); 

        // value into a unified interface calls returned in XML format 
        log.info ( "micro-channel payment request parameters:" + parameters.toString () ); 
        String xmlString to = sendPost (GATEURL, parameters); 
        the Map <String, String> Map = doXMLParse (xmlString to); 
        log.info ( "micro-channel payment request parameters:" + (Map == null ? null:map.toString()));
        Prepayid String = as map.get ( "prepay_id"); // Get prepayId 

        the JSONObject jsonObject = new new the JSONObject (); 
        jsonObject.put ( "prepayid" , prepayid); 
        jsonObject.put ( "noncestr" , noncestr);
         return jsonObject; 
    } 

    / ** 
     * the POST request, Map mode data 
     * @param URL request address 
     * @param param request data 
     * @param charset encoding
      * / 
    public  static String sendPost (String URL, Map <Object, Object> param) {

        StringBuffer buffer = new StringBuffer();
        buffer.append("<xml>");
        if (param != null && !param.isEmpty()) {
            for (Map.Entry<Object, Object> entry : param.entrySet()) {
                if(entry.getKey().equals("attach") || entry.getKey().equals("body") || entry.getKey().equals("sign")){
                    buffer.append("<"+entry.getKey()+">");
                    buffer.append("<![CDATA["+entry.getValue()+"]]>");
                    buffer.append("</"+entry.getKey()+">");
                }else{
                    buffer.append("<"+entry.getKey()+">");
                    buffer.append(entry.getValue());
                    buffer.append("</"+entry.getKey()+">");
                }
            }
        }
        buffer.append("</xml>");
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = newThe URL (URL);
             // open a connection and the URL 
            the URLConnection Conn = realUrl.openConnection ();
             // set the common request attribute 
            conn.setRequestProperty ( "Accept", "* / *" ); 
            conn.setRequestProperty ( " Connection "," the Keep-Alive " ); 
            conn.setRequestProperty ( " User-Agent "," the Mozilla / 4.0 (compatible; MSIE 6.0; the Windows NT 5.1; SVl) " );
             // send a POST request must set the following two lines 
            conn .setDoOutput ( to true ); 
            conn.setDoInput ( to true );
            // Get URLConnection object corresponding to the output stream 
            out =new new the PrintWriter (conn.getOutputStream ());
             // send a request parameter 
            Out.print (Buffer);
             // the flush buffered output stream 
            out.flush ();
             // define BufferedReader input stream to read the URL of the response 
            in = new new the BufferedReader ( new new the InputStreamReader (conn.getInputStream (), "UTF-. 8" )); 
            String Line; 
            the while (! (= in.readLine Line ()) = null ) { 
                Result + = Line; 
            } 
        } the catch (Exception E) { 
            e.printStackTrace (); 
        }
        // Use finally block to close the output stream, the input stream 
        finally {
             the try {
                 IF (OUT =! Null ) { 
                    the out.close (); 
                } 
                IF (in =! Null ) { 
                    in.close (); 
                } 
            } the catch (IOException EX) { 
                ex.printStackTrace (); 
            } 
        } 
        return Result; 
    } 

    / ** 
     * generates signature 
     * @param partnerkey 
     * @param characterEncoding 
     * @param parameters
     * @return https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3
     */
    public static String creatingSign(String PartnerKey, SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        Iterator it = parameters.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + PartnerKey);
        return  MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
    }
    /**
     * 金额元-> 分
     * @param money
     * @return
     */
    public static int change2Fen(String money){
        if(null==money){
            return 0;
        } 
        Return  new new the BigDecimal (Money) .multiply ( new new the BigDecimal (100 )) intValue ();. 
    } 

    / ** 
     * <P> (converted into units of the elements (except 100)) </ P> 
     * / 
    / ** the amount of minute format * / 
    public  static  Final String CURRENCY_FEN_REGEX = "\\ - [0-9] +?" ;
     public  static String change2Yuan (String aMOUNT) throws Exception {
         return String.valueOf ( new new the BigDecimal (aMOUNT). Divide ( new new the BigDecimal (100 ))); 
    } 

    / ** 
     * <P> (the 32-bit random string, anti-replay) </ P> 
     * /
    public static String getNonceStr() {
        Random random = new Random();
        return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "UTF-8");
    }

    /**
     * 获取时间戳
     * @return
     */
    public static String getTimeStamp() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }

    /**
     * 获取ip地址
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return  ip;
    } 

    / ** 
     * String XML parsing stream object type the InputStream 
     * parsed xml, returned to the first stage element pairs. If the first stage element has a child node, the value of this node is a child node xml data. 
     * @Param strXML 
     * @return 
     * @throws JDOMException 
     * @throws IOException
      * / 
    public  static the Map <String, String> doXMLParse (String strXML) {
         IF ( null == strXML || "" .equals (strXML)) {
             return  null ; 
        } 

        the Map <String, String> Map = new new the HashMap <String, String> ();
        InputStream in =null;
       try{
           in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
           SAXBuilder builder = new SAXBuilder();
           builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
           builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
           builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
           builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
           Document doc = builder.build(in);
           Element root = doc.getRootElement();
           List list = root.getChildren();
           Iterator it = list.iterator();
           while(it.hasNext()) {
               Element e = (Element) it.next();
               String k = e.getName();
               String v = "";
               List children = e.getChildren();
               if(children.isEmpty()) {
                   v = e.getTextNormalize();
               } else {
                   v = getChildrenText(children);
               }
               map.put(k, v);
           }
       }catch (Exception e){
            e.printStackTrace();
       }finally {
            if(in!=null){
                //关闭流
                IOUtils.closeQuietly(in);
            }
       }
       return map;
    }

    /**
     * 获取子结点的xml
     * @param children
     * @return String
     */
    private static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if(!children.isEmpty()) {
            Iterator it = children.iterator();
            while(it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if(!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
        return sb.toString();
    }


    public static String setResultXML(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code
                + "]]></return_code><return_msg><![CDATA[" + return_msg
                + "]]></return_msg></xml>";
    }
}
View Code

 

4. The micro-channel payment process, obtaining single unified prepayid, then assembled Mobile Originated request parameters return payment.

  • Note that, noncestr random string parameter is the same in the two request
  • Micro-letter signature parameters partnerkey, key settings Path: micro-channel merchant platform (pay.weixin.qq.com) -> Account Settings -> API Security -> Key Settings
  • The amount is based on micro-channel sub- units

Guess you like

Origin www.cnblogs.com/yangjiming/p/11410282.html