tj
2025-03-28 b1ab565909e471dde643755e93633cb84872733b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
package com.mzl.flower.utils.alipay;
 
 
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
 
/**
 * 2.0 订单串本地签名逻辑
 * 注意:本 Demo 仅作为展示用途,实际项目中不能将 RSA_PRIVATE 和签名逻辑放在客户端进行!
 */
 
public class OrderInfoUtil2_0 {
 
    // 获取当前时间并格式化
    static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
 
    /**
     * 构造授权参数列表
     *
     * @param pid
     * @param app_id
     * @param target_id
     * @return
     */
    public static Map<String, String> buildAuthInfoMap(String pid, String app_id, String target_id, boolean rsa2) {
        Map<String, String> keyValues = new HashMap<String, String>();
 
        // 商户签约拿到的app_id,如:2013081700024223
        keyValues.put("app_id", app_id);
 
        // 商户签约拿到的pid,如:2088102123816631
        keyValues.put("pid", pid);
 
        // 服务接口名称, 固定值
        keyValues.put("apiname", "com.alipay.account.auth");
 
        // 服务接口名称, 固定值
        keyValues.put("methodname", "alipay.open.auth.sdk.code.get");
 
        // 商户类型标识, 固定值
        keyValues.put("app_name", "mc");
 
        // 业务类型, 固定值
        keyValues.put("biz_type", "openservice");
 
        // 产品码, 固定值
        keyValues.put("product_id", "APP_FAST_LOGIN");
 
        // 授权范围, 固定值
        keyValues.put("scope", "kuaijie");
 
        // 商户唯一标识,如:kkkkk091125
        keyValues.put("target_id", target_id);
 
        // 授权类型, 固定值
        keyValues.put("auth_type", "AUTHACCOUNT");
 
        // 签名类型
        keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");
 
        return keyValues;
    }
 
    /**
     * 构造支付订单参数列表
     */
    public static Map<String, String> buildOrderParamMapTest(String app_id, boolean rsa2) {
        String timestamp = format.format(new Date());
 
        Map<String, String> keyValues = new TreeMap<>();
 
        keyValues.put("app_id", app_id);
 
        keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"0.01\",\"subject\":\"1\",\"body\":\"我是测试数据\",\"out_trade_no\":\"" + getOutTradeNo() +  "\"}");
 
        keyValues.put("charset", "utf-8");
 
        keyValues.put("method", "alipay.trade.app.pay");
 
        keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");
 
        keyValues.put("timestamp", timestamp);
 
        keyValues.put("version", "1.0");
 
        return keyValues;
    }
 
    /**
     * 构造支付订单参数列表
     */
    public static Map<String, String> buildOrderParamMap(String app_id, boolean rsa2, String bizContent) {
 
        String timestamp = format.format(new Date());
 
        Map<String, String> keyValues = new TreeMap<String, String>();
 
        keyValues.put("app_id", app_id);
 
        keyValues.put("biz_content", bizContent);
 
        keyValues.put("charset", "utf-8");
 
        keyValues.put("method", "alipay.trade.app.pay");
 
        keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");
 
        keyValues.put("timestamp", timestamp);
 
        keyValues.put("version", "1.0");
 
        return keyValues;
    }
 
    /**
     * 构造支付订单参数信息
     *
     * @param map
     * 支付订单参数
     * @return
     */
    public static String buildOrderParam(Map<String, String> map) {
        List<String> keys = new ArrayList<String>(map.keySet());
 
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keys.size() - 1; i++) {
            String key = keys.get(i);
            String value = map.get(key);
            sb.append(buildKeyValue(key, value, true));
            sb.append("&");
        }
 
        String tailKey = keys.get(keys.size() - 1);
        String tailValue = map.get(tailKey);
        sb.append(buildKeyValue(tailKey, tailValue, true));
 
        return sb.toString();
    }
 
    /**
     * 拼接键值对
     *
     * @param key
     * @param value
     * @param isEncode
     * @return
     */
    private static String buildKeyValue(String key, String value, boolean isEncode) {
        StringBuilder sb = new StringBuilder();
        sb.append(key);
        sb.append("=");
        if (isEncode) {
            try {
                sb.append(URLEncoder.encode(value, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                sb.append(value);
            }
        } else {
            sb.append(value);
        }
        return sb.toString();
    }
 
    /**
     * 对支付参数信息进行签名
     *
     * @param map
     *            待签名授权信息
     *
     * @return
     */
    public static String getSign(Map<String, String> map, String rsaKey, boolean rsa2) {
        List<String> keys = new ArrayList<String>(map.keySet());
        // key排序
        Collections.sort(keys);
 
        StringBuilder authInfo = new StringBuilder();
        for (int i = 0; i < keys.size() - 1; i++) {
            String key = keys.get(i);
            String value = map.get(key);
            authInfo.append(buildKeyValue(key, value, false));
            authInfo.append("&");
        }
 
        String tailKey = keys.get(keys.size() - 1);
        String tailValue = map.get(tailKey);
        authInfo.append(buildKeyValue(tailKey, tailValue, false));
 
        String oriSign = SignUtils.sign(authInfo.toString(), rsaKey, rsa2);
        String encodedSign = "";
 
        try {
            encodedSign = URLEncoder.encode(oriSign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "sign=" + encodedSign;
    }
 
    /**
     * 要求外部订单号必须唯一。
     * @return
     */
    public static String getOutTradeNo() {
        SimpleDateFormat format = new SimpleDateFormat("YYYYMMddHHmmss", Locale.getDefault());
        Date date = new Date();
        String key = format.format(date);
 
        Random r = new Random();
        key = key + r.nextInt();
        key = key.substring(0, 15);
        return key;
    }
 
}