86183
2022-09-09 0d999e33085c0a25c5525242748f6aa62a401159
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
package com.dsh.app.util.pay;
 
 
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.dsh.app.util.DoubleUtil;
import com.dsh.app.util.pay.config.Config;
import com.dsh.app.util.pay.entity.RefundBean;
import com.dsh.app.util.pay.wechat.*;
 
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
 
public class PayUtil {
 
    /**
     * 获取支付宝支付 组装参数
     *
     * @param sn            订单号
     * @param paymentMethod 支付方式
     * @param price         价格
     * @return
     */
    public static JSONObject getSignParam(String sn, String paymentMethod, BigDecimal price, String memo) {
        JSONObject jsonObject = new JSONObject();
        if (paymentMethod == "alipay") {//支付宝组装参数
            //实例化客户端
            AlipayClient alipayClient = new DefaultAlipayClient(Config.ALIPAY_URL, Config.ALIPAY_APP_ID,
                    Config.ALIPAY_PRIVATE_KEY, "json", "utf-8", Config.ALIPAY_PUBLIC_KEY, "RSA2");
 
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setBody(memo);
            model.setSubject( memo + "订单");
            model.setOutTradeNo(sn);
            model.setTimeoutExpress("30m");
            model.setTotalAmount(price.toString());
//            model.setTotalAmount("0.01");
            model.setProductCode("Sn" + sn);
            request.setBizModel(model);
            request.setNotifyUrl(Config.CALL_ORDER_URL + sn);
            try {
                //这里和普通的接口调用不同,使用的是sdkExecute
                AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
                jsonObject.put("sign", response.getBody());
                System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
        } else if (paymentMethod == "wechat") {//微信支付
            //price BigDecimal.valueOf(0.01)
            String orderParam = new WXPayParam().getPatParam(sn, price, memo + "订单", Config.CALL_ORDER_URL + sn);
            try {
                System.out.println(orderParam);
                String rsp = HttpsConnectUtil.doPost(Config.WX_UNIFIED_ORDER_URL, orderParam, "UTF-8", 30000, 30000, true);
                System.out.println(rsp);
 
                jsonObject.put("wxSign", WXPayCommonUtil.appParam(rsp));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return jsonObject;
    }
 
    /**
     * 微信退款
     *
     * @param out_trade_no 商户订单号
     * @param total_fee    订单金额
     * @param refund_fee   退款金额
     * @param request
     * @return
     */
    public static RefundBean wechatRefund(String out_trade_no, BigDecimal total_fee, BigDecimal refund_fee, String refund_desc, HttpServletRequest request) {
        RefundBean refundBean = new RefundBean();
        refundBean.setSuccess(false);
        // 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
        String out_refund_no = UUID.randomUUID().toString().substring(0, 32);
        String nonce_str = WXPayCommonUtil.CreateNoncestr();// 随机字符串
        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", Config.WX_PAY_APPID);
        packageParams.put("mch_id", Config.WX_PAY_MCH_ID);
        packageParams.put("nonce_str", nonce_str);
//        packageParams.put("transaction_id", transaction_id); // 微信生成的订单号,在支付通知中有返回(微信平台流水号和商户订单号取其一)
        packageParams.put("out_trade_no", out_trade_no); // 商户支付订单号
        packageParams.put("out_refund_no", out_refund_no); // 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔
        packageParams.put("total_fee", total_fee.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString()); // 订单总金额,单位为分,只能为整数
        packageParams.put("refund_fee", refund_fee.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString()); // 退款总金额,订单总金额,单位为分,只能为整数
//        packageParams.put("op_user_id", Config.WX_PAY_MCH_ID);
        packageParams.put("refund_desc", refund_desc);
 
        RequestHandler reqHandler = new RequestHandler(null, null);
        reqHandler.init(Config.WX_PAY_APPID, Config.WX_PAY_SECRET, Config.WX_PAY_API_KEY);
 
        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" +
                "<appid>" + Config.WX_PAY_APPID + "</appid>" +
                "<mch_id>" + Config.WX_PAY_MCH_ID + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<sign><![CDATA[" + sign + "]]></sign>" +
                "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
                "<out_refund_no>" + out_refund_no + "</out_refund_no>" +
                "<total_fee>" + total_fee.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString() + "</total_fee>" +
                "<refund_fee>" + refund_fee.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString() + "</refund_fee>" +
                "<refund_desc>" + refund_desc + "</refund_desc>" +
//                "<op_user_id>" + Config.WX_PAY_MCH_ID + "</op_user_id>" +
                "</xml>";
 
        String createOrderURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        try {
            ClientCustomSSL ccs = new ClientCustomSSL();
            Map<String, String> map = ccs.doRefund(createOrderURL, xml, request);
            if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
                refundBean.setSuccess(true);
            } else {
                System.out.println(map.get("return_msg"));
                System.out.println(map.get("err_code"));
                System.out.println(map.get("err_code_des"));
            }
            //保存微信退款返回信息
            refundBean.setDesc(JSONObject.toJSONString(map));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("微信退款错误!");
        }
        return refundBean;
    }
 
    /**
     * 支付宝退款
     *
     * @param trade_no      商户订单号
     * @param refund_amount 退款金额
     * @param memo          退款原因
     * @return
     */
    public static RefundBean alipayRefund(String trade_no, Double refund_amount, String memo) {
        RefundBean refundBean = new RefundBean();
        refundBean.setSuccess(false);
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(Config.ALIPAY_URL, Config.ALIPAY_APP_ID, Config.ALIPAY_PRIVATE_KEY, "json", "utf-8", Config.ALIPAY_KEY, "RSA2");
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
        refundModel.setOutTradeNo(trade_no);
        refundModel.setRefundAmount(DoubleUtil.format(refund_amount).toString());
        refundModel.setRefundReason(memo);
        refundModel.setOutRequestNo("HZ01RF001");
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizModel(refundModel);
        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            //保存支付宝退款返回信息
            refundBean.setDesc(JSONObject.toJSONString(response));
            System.out.println(response.getMsg() + "\n");
            System.out.println(response.getBody());
            if (response.isSuccess()) {
                System.out.println("调用成功");
                refundBean.setSuccess(true);
            } else {
                System.out.println("调用失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("支付宝退款错误!");
        }
        return refundBean;
    }
 
 
 
//    public static void main(String[] args) {
//        Date date = new Date();
//        date.getTime();
//        PayUtil.getSignParam(date.getTime() + "", Config.paymentMethod.alipay.ordinal(), new BigDecimal(1), "测试");
//    }
//    public static void main(String[] args) {
//     String orderParam="";
//    orderParam=new WXPayParam().getPatParam("1223233334",new BigDecimal(0.01),"医网天下", UrlAddress.ALI_PAY_PREFIX + "123456000654321");
//        System.out.println(orderParam);
//        try {
//          String  s=  HttpsConnectUtil.doPost(ConfigParam.WX_UNIFIED_ORDER_URL,orderParam,"UTF-8",30000,30000,true);
//            System.out.println(s);
//
//            WXPayCommonUtil.decodeXml(s);
//
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
/*String  s="<xml><return_code><![CDATA[SUCCESS]]></return_code>" +
        "<return_msg><![CDATA[OK]]></return_msg>" +
        "<appid><![CDATA[wx39b6f80d336ca5e4]]></appid>" +
        "<mch_id><![CDATA[1264744601]]></mch_id>" +
        "<nonce_str><![CDATA[cBajyxj5PSGPyly7]]></nonce_str>" +
        "<sign><![CDATA[37E1EE9D780F7F581EC654A8AB728BA6]]></sign>" +
        "<result_code><![CDATA[SUCCESS]]></result_code>" +
        "<prepay_id><![CDATA[wx201801171652025bf1ed5ab60033862709]]></prepay_id>" +
        "<trade_type><![CDATA[APP]]></trade_type>" +
        "</xml>";*/
    /*    System.out.println(WXPayCommonUtil.appParam(s));*/
//    }
}