cn.ieclipse.pay.wxpay.OrderInfoUtil.java Source code

Java tutorial

Introduction

Here is the source code for cn.ieclipse.pay.wxpay.OrderInfoUtil.java

Source

/*
 * Copyright (C) 2015-2017 QuickAF
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.ieclipse.pay.wxpay;

import android.text.TextUtils;
import android.util.Xml;

import com.tencent.mm.opensdk.modelpay.PayReq;

import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;

import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * Description
 *
 * @author Jamling
 */
public abstract class OrderInfoUtil {

    /**
     * <xml>
     * <return_code><![CDATA[SUCCESS]]></return_code>
     * <return_msg><![CDATA[OK]]></return_msg>
     * <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
     * <mch_id><![CDATA[10000100]]></mch_id>
     * <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
     * <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
     * <result_code><![CDATA[SUCCESS]]></result_code>
     * <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
     * <trade_type><![CDATA[APP]]></trade_type>
     * </xml>
     * ??xml
     *
     * @param content ?xml
     *
     * @return ?map
     */
    public static Map<String, String> parseXmlResponse(String content) {
        try {
            Map<String, String> xml = new HashMap<>();
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(new StringReader(content));
            int event = parser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT) {

                String nodeName = parser.getName();
                switch (event) {
                case XmlPullParser.START_DOCUMENT:
                    break;
                case XmlPullParser.START_TAG:
                    if ("xml".equals(nodeName) == false) {
                        // 
                        xml.put(nodeName, parser.nextText());
                    }
                    break;
                case XmlPullParser.END_TAG:
                    break;
                }
                event = parser.next();
            }
            return xml;
        } catch (Exception e) {
            if (Wxpay.DEBUG) {
                Wxpay.log("xml???" + e.toString());
            }
        }
        return null;
    }

    public static Map<String, String> parseJsonResponse(String content) {
        try {
            JSONObject object = new JSONObject(content);
            Map<String, String> map = new HashMap<>();
            Iterator<String> keys = object.keys();
            if (keys != null) {
                while (keys.hasNext()) {
                    String key = keys.next();
                    map.put(key, object.getString(key));
                }
            }
            return map;
        } catch (Exception e) {
            if (Wxpay.DEBUG) {
                Wxpay.log("json???" + e.toString());
            }
        }
        return null;
    }

    /**
     * Get {@link com.tencent.mm.opensdk.modelpay.PayReq} from order map result.
     *
     * @param result order result map
     *
     * @return PayReq
     */
    public static PayReq getPayReq(Map<String, String> result) {
        PayReq req = null;
        if (result != null && "SUCCESS".equals(result.get("result_code"))
                && "SUCCESS".equals(result.get("return_code"))) {
            req = new PayReq();
            req.appId = result.get("appid");
            req.nonceStr = result.get("nonce_str");
            req.partnerId = result.get("mch_id");
            req.packageValue = "Sign=WXPay";
            req.prepayId = result.get("prepay_id");
            req.timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
            req.sign = result.get("sign");
            signPayReq(req);
        }
        return req;
    }

    /**
     * ??????timestamptimestamp?????
     * ???????????PayReq?
     *
     * @param req ?
     */
    public static void signPayReq(PayReq req) {
        Map<String, String> sortedMap = new TreeMap<>();
        sortedMap.put("appid", req.appId);
        sortedMap.put("noncestr", req.nonceStr);
        sortedMap.put("partnerid", req.partnerId);
        sortedMap.put("prepayid", req.prepayId);
        sortedMap.put("timestamp", req.timeStamp);
        sortedMap.put("package", req.packageValue);
        String sign = OrderInfoUtil.genSign(sortedMap);
        if (Wxpay.DEBUG) {
            Wxpay.log("???" + sign);
        }
        req.sign = sign;
    }

    /**
     * Get {@link com.tencent.mm.opensdk.modelpay.PayReq} from order xml result.
     *
     * @param xmlResultContent order result xml content
     *
     * @return PayReq
     */
    public static PayReq getPayReq(String xmlResultContent) {
        Map<String, String> result = OrderInfoUtil.parseXmlResponse(xmlResultContent);
        return getPayReq(result);
    }

    /**
     * Sample :
     * <xml>
     * <appid>wx2421b1c4370ec43b</appid>
     * <attach></attach>
     * <body>APP</body>
     * <mch_id>10000100</mch_id>
     * <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
     * <notify_url>http://wxpay.wxutil.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>
     *
     * @return request xml body
     */
    public static Map<String, String> buildOrderParamMap(String out_trade_no, String body, String detail,
            String fee, String notify_url, String nonce_str, String ip) {
        Map<String, String> map = new LinkedHashMap<>();
        map.put("appid", Wxpay.Config.app_id);
        if (body.length() > 128) {
            map.put("body", body.substring(0, 128));
        } else {
            map.put("body", body);
        }
        if (!TextUtils.isEmpty(detail)) {
            map.put("detail", detail);
        }
        map.put("mch_id", Wxpay.Config.mch_id);
        map.put("nonce_str", TextUtils.isEmpty(nonce_str) ? OrderInfoUtil.genNonceStr() : nonce_str);
        map.put("notify_url", TextUtils.isEmpty(notify_url) ? Wxpay.Config.notify_url : notify_url);
        map.put("out_trade_no", out_trade_no);
        map.put("spbill_create_ip", TextUtils.isEmpty(ip) ? "127.0.0.1" : ip);
        map.put("total_fee", fee);
        map.put("trade_type", "APP");
        return map;
    }

    public static String genNonceStr() {
        String str = String.valueOf(new java.util.Random().nextDouble());
        return MD5.getMessageDigest(str.getBytes());
    }

    public static String genSign(Map<String, String> parameters) {
        // see https://pay.weixin.qq.com/wiki/tools/signverify/
        Map<String, String> sortedMap = new TreeMap<>();
        for (String key : parameters.keySet()) {
            sortedMap.put(key, parameters.get(key));
        }

        StringBuffer sb = new StringBuffer();
        Set<String> es = sortedMap.keySet();
        for (String k : es) {
            String v = sortedMap.get(k);
            if (!TextUtils.isEmpty(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        if (Wxpay.DEBUG) {
            Wxpay.log("?" + sb.toString());
        }
        sb.append("key=" + Wxpay.Config.api_key);
        if (Wxpay.DEBUG) {
            Wxpay.log("key" + sb.toString());
        }
        String sign = MD5.getMessageDigest(sb.toString().getBytes());
        if (Wxpay.DEBUG) {
            Wxpay.log("MD5?" + sign);
        }
        return sign;
    }
}