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));*/
|
// }
|
}
|