xuhy
昨天 185b90fbbd29bcf520456196d758079e60b325eb
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
package com.ruoyi.payment.ali.v2;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.*;
import com.alipay.api.diagnosis.DiagnosisUtils;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.ruoyi.payment.ali.config.AliH5Properties;
import com.ruoyi.payment.ali.config.AliProperties;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
import static com.ruoyi.payment.ali.v2.util.Md5Util.byteArrayToHexString;
 
 
/**
 * 第三方支付工具类
 */
@Component
public class H5PayUtil {
    private static Logger log = LoggerFactory.getLogger(AppletPayUtil.class);
 
    @Autowired
    private AliH5Properties aliH5Properties;
 
    private String aliAppid = "2021004172608506";//支付宝appid
    private String appPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCREjc1/sU4fdzCJrtNBhaxIZb17G/9CoxDRCyHqy15TecDHl3tMt+sTpzIv1mWRUUIDtNvgBUMMv9gPfDbfl/T5Lk3MyM8sQocGBTQRTzcQzNL4fLjBT6LF6F9WSe65wG8OEtaI2IwFlKDbB7No2EkVKjWcAEdYkPu50WP6aEzXGj6CkO3CLRlUm2TXPngun8krVsB8zYkxpVA86mcB5DOXW9/1+XnXQ0i4c4k1XeDx25ycXyJGftDwBdV7Y9VA0GavUAXMZV2afRjObRcfQ554mCj4L52M/y+AC02io/+G2k+cq/yM+zr/bGp1A00gqFWI7HNLHFzoR7RdjCZXSQvAgMBAAECggEAP0r0PaGPCEuZcjeVxlAevF9MTrU+Uuc0NPDcgMCFUYRUgr7P+foVLkcKDme1vWMxcAeP5fi6thzV4HaFzC3Bv1/uExBDkmonYAR9qDRdDjhfe/7zimqyU9sWgOrR87BvyF/DOGtxnktO6rnUYqGic0hgdVZeliRWQTgz2Er1IsPJMEg/mrBDvPXeoSh+cppayYL3d7W8QVP650Eraxim0CfdFdiV0Fb5OMq/X5oPr93TdRbMoE8TMid9i+XlcmKe9pMjwat/CGK8auRpYOm0W3Ml+ybf3q2O+p/TTTSZfBYlLVb7fDdPxmZeDU/9u04k75DQR3taAQnYVvAJp3LwaQKBgQDMhpkAKR7GcI9AxpKDZY59Sg0SR68qrjYJqDtexr177wXZMxqh5a2S08fk3wLk8z5TAyucSg3kuX79wEeTMFlEBHERko/9bIVsT6U+lRY4AiXfQK1phIvRBiODQ9yBRPyEWBqkdZa0PaD4cbx0BMWe1GJE9zgoGNkOmZOa6mDrlQKBgQC1lQNfcbrr0r5coL+vx/BSSoaiHFZ4ijcCxWMPdjtxnKAfxTncq0C2UxzPgtpXYmLPrpsaulYE9nmUZIblbSPQbyTmoBIVx20Izzt/jY3YOJ7UnTgDoC24aq/RV4n/I2q3flnBqmA/+wcLwMEJvnQ+oWYIJ2e5q2XXybiWtXP/swKBgDgqGif2ItJhpKUoIqHcqKV1SWOktdClqIc8YJllQDGhcNy1cPHWjbTNXY5XQ4c12P6Y10gC+g++dMYgIEemNk08XwRxWANC4tzcfkdST5iv1lCZhUV9tZt/8Q6h+xKwrBt3ylExTWJPrj2rlhHSIaa9MgM4VH6GXEzrFaKsDFOFAoGAe33zhEbZxCZYdrCQjSDiTWUH+VpiaKo/TXAmtc5IETVfJRxCBNSnNxiBQJOSoNl1sB7kt6HAfLGP8B8KKyA1ujzMkNiOVCeD/PjLUy1XKZUgWCLwhG68iW5tUmdBn7Zbjp2st2yC9yBnI1QdNN5FOo8T0DnUbk6l/cLf+gc/88cCgYEAjYJFvXDhGKlx1xI/eLPSKNUIab5i3K57A9B8CejFIHxdV4jDf9OGj/kf/WrNcFfBGqgpqNXgtpBmtplPAQmcvNJVVoI0wfXDQHuO0vZ600Rku2Bv/uldObwq/xk46rTHtQjkIzBI25IcRh5gvaoyk+Yq+zkLZosuNyXYwVSxVJs=";//支付宝开发者应用私钥
    private String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkRI3Nf7FOH3cwia7TQYWsSGW9exv/QqMQ0Qsh6steU3nAx5d7TLfrE6cyL9ZlkVFCA7Tb4AVDDL/YD3w235f0+S5NzMjPLEKHBgU0EU83EMzS+Hy4wU+ixehfVknuucBvDhLWiNiMBZSg2wezaNhJFSo1nABHWJD7udFj+mhM1xo+gpDtwi0ZVJtk1z54Lp/JK1bAfM2JMaVQPOpnAeQzl1vf9fl510NIuHOJNV3g8ducnF8iRn7Q8AXVe2PVQNBmr1AFzGVdmn0Yzm0XH0OeeJgo+C+djP8vgAtNoqP/htpPnKv8jPs6/2xqdQNNIKhViOxzSxxc6Ee0XYwmV0kLwIDAQAB";//支付宝应用公钥
    private String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkoPidM7vHL/74FhOWARjkMDZN0GktpVEQaYz6qpIjTuKLcQsR74CUv9LoiGD9uquYAI52TdmxzMWbuMEvrdVIT6pWyJuCvScX2U5Zwn9Bk8bE5RmTobUrU3LFudMYIGFU3qUHqnTJFQxLsSUibTtxbov1bpCQNwk3/2RdYOpJHKDjkXzNcjJrkuNcGcuzNW/3+L5CMaVm0dxqxx0dhJ4H0xvpMw2uvdxdLXN/KoYszfps4j61x0KFwkulvD1WHzR1f/ot9NU8FZe+dkNm5cXb9HbwQIbfARyB5bd0EYHSr4fJIUJx1GnjpfT6/traxEoyOcI6diJa4b2hZpR3WvxTQIDAQAB";//支付宝支付公钥
    private String callbackPath = "http://221.182.45.100:9000";//支付回调网关地址
    private AlipayConfig getAlipayConfig() {
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId(aliH5Properties.getAppId());
        alipayConfig.setPrivateKey(aliH5Properties.getPrivateKey());
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(aliH5Properties.getAlipayPublicKey());
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        return alipayConfig;
    }
    /**
     * 支付宝支付
     */
    public String alipay(String body, String subject, String passbackParams, String outTradeNo, String amount, String notifyUrl,String returnUrl) {
        try {
            //实例化客户端
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
            AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
            //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
            AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
            model.setBody(body);//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
            model.setSubject(subject);//商品的标题/交易标题/订单标题/订单关键字等。
            model.setOutTradeNo(outTradeNo);//商户网站唯一订单号
            model.setTimeoutExpress("30m");
            model.setTotalAmount(new BigDecimal(amount).setScale(2, RoundingMode.HALF_UP).toString());//付款金额
            model.setProductCode("QUICK_WAP_WAY");
            model.setPassbackParams(passbackParams);//自定义参数
            request.setBizModel(model);
            request.setNotifyUrl(aliH5Properties.getNotifyUrl() + notifyUrl);
            request.setReturnUrl(returnUrl);
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "POST");
            // 如果需要返回GET请求,请使用
            // AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "GET");
            String pageRedirectionData = response.getBody();
            log.info("-----支付宝H5支付-------:{}",pageRedirectionData);
            if (response.isSuccess()) {
                log.info("支付宝H5支付成功");
                return pageRedirectionData;
            }else {
                log.info("支付宝H5支付失败");
                String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
                return diagnosisUrl;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public boolean close(String outTradeNo){
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            // 构造请求参数以调用接口
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            AlipayTradeCloseModel model = new AlipayTradeCloseModel();
            // 设置订单支付时传入的商户订单号
            model.setOutTradeNo(outTradeNo);
            request.setBizModel(model);
            AlipayTradeCloseResponse response = alipayClient.execute(request);
            log.info("-----关闭支付宝支付订单-----");
            log.info("请求参数:{}", outTradeNo);
            log.info("返回结果:{}", response.getBody());
            if(response.isSuccess()){
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }
 
    /**
     * 支付成功后的回调处理逻辑
     *
     * @param request
     */
    public Map<String, String> alipayCallback(HttpServletRequest request) {
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) 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] + "_";
            }
            //乱码解决,这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        Map<String, String> map = new HashMap<>();
        System.err.println("返回码"+params);
        if (params.get("trade_status").equals("TRADE_SUCCESS")){
            String out_trade_no = params.get("out_trade_no");
            String subject = params.get("subject");
            String total_amount = params.get("total_amount");
            String trade_no = params.get("trade_no");
            String passback_params = params.get("passback_params");
            map.put("out_trade_no", out_trade_no);//商家订单号
            map.put("subject", subject);
            map.put("total_amount", total_amount);
            map.put("trade_no", trade_no);//支付宝交易号
            map.put("passback_params", passback_params);//回传参数
            System.err.println("回调map");
            return map;
        }else{
            return null;
        }
    }
 
 
    /**
     * 支付宝查询订单支付状态
     *
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    public AlipayTradeQueryResponse queryAliOrder(String out_trade_no) {
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();
            // 设置订单支付时传入的商户订单号
            model.setOutTradeNo(out_trade_no);
            request.setBizModel(model);
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                String tradeStatus = response.getTradeStatus();//交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
                return response;
            } else {
                return response;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }
 
 
    /**
     * 支付宝退款
     *
     * @param trade_no      支付宝交易号
     * @param refund_amount 退款金额
     * @return
     * @throws AlipayApiException
     */
    public Map<String, String> aliRefund(String trade_no, String refund_amount) {
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            // 设置订单支付时传入的商户订单号
            model.setTradeNo(trade_no);
            model.setRefundAmount(refund_amount);
            model.setRefundReason("充电退款");
            request.setBizModel(model);
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            Map<String, String> map = new HashMap<>();
            if (response.isSuccess()) {
                log.info("调用成功");
                String outTradeNo = response.getOutTradeNo();
                map.put("code", response.getCode());//10000
                map.put("trade_no", response.getTradeNo());//支付宝交易号
                map.put("out_trade_no", outTradeNo);//商户订单号
                map.put("refund_fee", response.getRefundFee());
                map.put("msg",  response.getMsg());
            } else {
                log.error("调用失败");
                map.put("code", response.getCode());
                map.put("msg", response.getSubMsg());
            }
            return map;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public static Map<String, String> xmlToMap(Element tmpElement, Map<String, String> respMap) {
        if (tmpElement.isTextOnly()) {
            respMap.put(tmpElement.getName(), tmpElement.getText());
            return respMap;
        }
 
        @SuppressWarnings("unchecked")
        Iterator<Element> eItor = tmpElement.elementIterator();
        while (eItor.hasNext()) {
            Element element = eItor.next();
            xmlToMap(element, respMap);
        }
        return respMap;
    }
}