SignUtil.java 5.81 KB
package com.cnlive.goldenline.pay;

import android.util.Log;

import com.cnlive.goldenline.Configs;
import com.cnlive.libs.util.Config;
import com.cnlive.libs.util.data.okhttp3.Headers;
import com.cnlive.libs.util.data.okhttp3.OkHttpClient;
import com.cnlive.libs.util.data.okhttp3.Request;
import com.cnlive.libs.util.data.okhttp3.Response;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * Created by gujun on 2017/4/9.
 */

public class SignUtil {

    public static final String PAY_TYPE_WEIXIN = "1";
    public static final String PAY_TYPE_ALIPAY = "2";

    public static final String PAY_RESULT_STATUS_SUCCESS = "200";
    public static final String PAY_RESULT_STATUS_FAIL = "500";

    /**
     * 从后台获取签名值
     * @param appId
     * @param notify_url
     * @param account
     * @param orderId
     * @param body
     * @param chooseMoney
     * @param payType
     * @param time
     * @param ver
     * @param sign
     * @return
     */
    public static Map<String, String> getPayToken(String appId,String notify_url,String account,
                                                  String orderId,String body,int chooseMoney,
                                                  int payType,String time,String ver,String sign,String userId) {

        Map<String, String> params = new LinkedHashMap<String, String>();
        params.put("appId", appId);
        params.put("out_trade_no",orderId);
        params.put("body",body);
        params.put("total_fee",chooseMoney+"");
        params.put("notify_url",notify_url);
        params.put("type",payType+"");
        if(payType == 1)//只有微信才有此参数
            params.put("account",account);
        params.put("timestamp",time);
        params.put("user_id",userId);
        params.put("ver",ver);
        params.put("sign",sign);

        return params;
    }


    /**
     * 获取签名字段值 供本地测试用
     * @param orderId 订单号
     * @param body 订单名称
     * @param chooseMoney 订单总额 (分)单位
     * @param payType 微信 1      百度钱包 2      支付宝 3       和包 4      IOS AppStore 1001
     * @return
     */
    public static Map<String, String> getPayToken(String appId,String notify_url,String account,
                                                  String orderId,String body,int chooseMoney,
                                                  int payType,String time,String ver) {

        Map<String, String> params = new LinkedHashMap<String, String>();
        if(payType == 1){
            params.put("account",account);
        }
        params.put("appId", appId);
        params.put("out_trade_no",orderId);
        params.put("body",body);
        params.put("total_fee",chooseMoney+"");
        params.put("notify_url",notify_url);
        params.put("type",payType+"");
        params.put("timestamp",time);
        params.put("ver",ver);
        params.put("sign",getSignParam(params));
        return params;
    }

    private static String getSignParam(Map<String, String> params) {
        if (params == null) return "";

        Map<String, String> map = order(params);

        if (map.containsKey("sign")) {
            map.remove("sign");
        }

        String signValue = SHA1
                .SHA1Digest(mapJoin(map, false).concat("&key=").concat(Config.getSpKey()))
                .toUpperCase(Locale.getDefault());

        return signValue;
    }

    //获取服务器时间
    public static long getTime() {
        OkHttpClient okHttpClient = new OkHttpClient();
        try {
            Request request = new Request.Builder().url("https://api.cnlive.com/open/api2/timestamp").build();
            Response response = okHttpClient.newCall(request).execute();
            Headers headers = response.headers();

            Date date = headers.getDate("Date");
            return date == null ? System.currentTimeMillis() : date.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return System.currentTimeMillis();
    }

    private static String mapJoin(Map<String, String> map, boolean valueUrlencode) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : map.keySet()) {
            if (map.get(key) != null && !"".equals(map.get(key))) {
                try {
                    stringBuilder.append(key)
                            .append("=")
                            .append(valueUrlencode ? URLEncoder.encode(map.get(key), "utf-8").replace("+", "%20") : map.get(key))
                            .append("&");
                } catch (UnsupportedEncodingException e) {
                    Log.e("error", "Load:" + e.getMessage(), e);
                }
            }
        }
        if (stringBuilder.length() > 0) {
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
//        Log.e(TAG, "Load:" + stringBuilder.toString());
        return stringBuilder.toString();
    }

    private static Map<String, String> order(Map<String, String> map) {
        HashMap<String, String> tempMap = new LinkedHashMap<>();
        List<Map.Entry<String, String>> infoIds = new ArrayList<>(map.entrySet());

        Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });

        for (int i = 0; i < infoIds.size(); i++) {
            Map.Entry<String, String> item = infoIds.get(i);
            tempMap.put(item.getKey(), item.getValue());
        }
        return tempMap;
    }
}