|
|
@@ -4,9 +4,9 @@ import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.alipay.api.AlipayApiException;
|
|
|
import com.alipay.api.AlipayClient;
|
|
|
+import com.alipay.api.AlipayConfig;
|
|
|
import com.alipay.api.DefaultAlipayClient;
|
|
|
-import com.alipay.api.domain.AlipayTradeAppPayModel;
|
|
|
-import com.alipay.api.domain.AlipayTradeRefundModel;
|
|
|
+import com.alipay.api.domain.*;
|
|
|
import com.alipay.api.request.AlipayTradeAppPayRequest;
|
|
|
import com.alipay.api.request.AlipayTradeQueryRequest;
|
|
|
import com.alipay.api.request.AlipayTradeRefundRequest;
|
|
|
@@ -33,8 +33,10 @@ import shop.alien.util.common.constant.PaymentEnum;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@@ -77,7 +79,7 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
private final StringRedisTemplate stringRedisTemplate;
|
|
|
|
|
|
@Override
|
|
|
- public R<Map<String, Object>> createPrePay(Integer storeId, Integer orderId, String amountYuan, String subject, Integer userId) {
|
|
|
+ public R<Map<String, Object>> createPrePay(Integer storeId, Integer orderId, String amountYuan, String subject, Integer userId, String smid) {
|
|
|
if (storeId == null || orderId == null) {
|
|
|
return R.fail("门店ID和订单ID不能为空");
|
|
|
}
|
|
|
@@ -171,21 +173,56 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
merchantPaymentOrderService.save(paymentOrder);
|
|
|
|
|
|
try {
|
|
|
- com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
|
|
|
- AlipayClient client = new DefaultAlipayClient(alipayConfig);
|
|
|
+// com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
|
|
|
+// AlipayClient client = new DefaultAlipayClient(alipayConfig);
|
|
|
+// AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
|
|
|
+// AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
|
|
|
+// model.setOutTradeNo(outTradeNo);
|
|
|
+// model.setTotalAmount(amountYuanBD.toPlainString());
|
|
|
+// model.setSubject(subject);
|
|
|
+// // 预支付单有效时间 15 分钟(相对超时,格式 1m~15d)
|
|
|
+// model.setTimeoutExpress("15m");
|
|
|
+// request.setBizModel(model);
|
|
|
+// // 必须用 certificateExecute 请求支付宝网关预创建交易,否则仅 sdkExecute 本地签名不会在支付宝侧落单,查单会报「交易不存在」
|
|
|
+// //AlipayTradeAppPayResponse response = client.certificateExecute(request);
|
|
|
+// AlipayTradeAppPayResponse response = client.sdkExecute(request);
|
|
|
+ // 初始化SDK
|
|
|
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
|
|
|
+
|
|
|
+ // 构造请求参数以调用接口
|
|
|
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
|
|
|
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
|
|
|
+
|
|
|
model.setOutTradeNo(outTradeNo);
|
|
|
- model.setTotalAmount(amountYuanBD.toPlainString());
|
|
|
+ BigDecimal total = new BigDecimal(String.valueOf(amountYuanBD));
|
|
|
+ model.setTotalAmount(String.valueOf(total));
|
|
|
+
|
|
|
model.setSubject(subject);
|
|
|
- // 预支付单有效时间 15 分钟(相对超时,格式 1m~15d)
|
|
|
+
|
|
|
model.setTimeoutExpress("15m");
|
|
|
+
|
|
|
+ // 1. 构建二级商户信息
|
|
|
+ SubMerchant subMerchant = new SubMerchant();
|
|
|
+ subMerchant.setMerchantId(smid); // 替换为实际的二级商户编号
|
|
|
+ // 【关键】设置二级商户信息(直付通必传)
|
|
|
+ model.setSubMerchant(subMerchant);
|
|
|
+
|
|
|
+ SettleInfo settleInfo = new SettleInfo();
|
|
|
+ SettleDetailInfo settleDetailInfo = new SettleDetailInfo();
|
|
|
+ settleDetailInfo.setTransInType("defaultSettle");
|
|
|
+ settleDetailInfo.setAmount(total.toString());
|
|
|
+ List<SettleDetailInfo> settleDetailInfos = new ArrayList<>();
|
|
|
+ settleDetailInfos.add(settleDetailInfo);
|
|
|
+ settleInfo.setSettleDetailInfos(settleDetailInfos);
|
|
|
+ model.setSettleInfo(settleInfo);
|
|
|
+
|
|
|
+ request.setNotifyUrl("https://frp-off.com:40279/alienStore/alipayPartnerNotify");
|
|
|
request.setBizModel(model);
|
|
|
- // 必须用 certificateExecute 请求支付宝网关预创建交易,否则仅 sdkExecute 本地签名不会在支付宝侧落单,查单会报「交易不存在」
|
|
|
- //AlipayTradeAppPayResponse response = client.certificateExecute(request);
|
|
|
- AlipayTradeAppPayResponse response = client.sdkExecute(request);
|
|
|
|
|
|
- String orderStr = response.isSuccess() ? response.getBody() : "";
|
|
|
+ AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
|
|
|
+ String orderStr = response.getBody();
|
|
|
+
|
|
|
+// String orderStr = response.isSuccess() ? response.getBody() : "";
|
|
|
|
|
|
if (!response.isSuccess()) {
|
|
|
return R.fail("预支付失败:" + response.getSubMsg());
|
|
|
@@ -231,13 +268,24 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
return R.success("支付成功");
|
|
|
}
|
|
|
try {
|
|
|
- com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
|
|
|
- AlipayClient client = new DefaultAlipayClient(alipayConfig);
|
|
|
+// com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
|
|
|
+// AlipayClient client = new DefaultAlipayClient(alipayConfig);
|
|
|
+// AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
|
|
|
+// JSONObject bizContent = new JSONObject();
|
|
|
+// bizContent.put("out_trade_no", outTradeNo);
|
|
|
+// request.setBizContent(bizContent.toJSONString());
|
|
|
+// AlipayTradeQueryResponse response = client.certificateExecute(request);
|
|
|
+
|
|
|
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
|
|
|
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
|
|
|
- JSONObject bizContent = new JSONObject();
|
|
|
- bizContent.put("out_trade_no", outTradeNo);
|
|
|
- request.setBizContent(bizContent.toJSONString());
|
|
|
- AlipayTradeQueryResponse response = client.certificateExecute(request);
|
|
|
+ AlipayTradeQueryModel model = new AlipayTradeQueryModel();
|
|
|
+ model.setOutTradeNo(outTradeNo);
|
|
|
+ List<String> queryOptions = new ArrayList<>();
|
|
|
+ queryOptions.add("trade_settle_info");
|
|
|
+ model.setQueryOptions(queryOptions);
|
|
|
+ request.setBizModel(model);
|
|
|
+
|
|
|
+ AlipayTradeQueryResponse response = alipayClient.execute(request);
|
|
|
if (!response.isSuccess()) {
|
|
|
String subMsg = response.getSubMsg();
|
|
|
String subCode = response.getSubCode();
|
|
|
@@ -319,15 +367,24 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
return R.fail("订单未支付或已退款,无法退款");
|
|
|
}
|
|
|
try {
|
|
|
- com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
|
|
|
- AlipayClient client = new DefaultAlipayClient(alipayConfig);
|
|
|
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
|
|
|
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
|
|
model.setOutTradeNo(outTradeNo);
|
|
|
model.setRefundAmount(refundAmount);
|
|
|
model.setRefundReason(StringUtils.isNotBlank(refundReason) ? refundReason : "用户申请退款");
|
|
|
request.setBizModel(model);
|
|
|
- AlipayTradeRefundResponse response = client.certificateExecute(request);
|
|
|
+ AlipayTradeRefundResponse response = refundRun(request);
|
|
|
+
|
|
|
+
|
|
|
+// com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
|
|
|
+// AlipayClient client = new DefaultAlipayClient(alipayConfig);
|
|
|
+// AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
|
|
|
+// AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
|
|
+// model.setOutTradeNo(outTradeNo);
|
|
|
+// model.setRefundAmount(refundAmount);
|
|
|
+// model.setRefundReason(StringUtils.isNotBlank(refundReason) ? refundReason : "用户申请退款");
|
|
|
+// request.setBizModel(model);
|
|
|
+// AlipayTradeRefundResponse response = client.certificateExecute(request);
|
|
|
if (!response.isSuccess()) {
|
|
|
String failMsg = "退款失败:" + response.getSubMsg();
|
|
|
markRefundFailed(order, paymentOrder, failMsg, refundReason, storeId, outTradeNo);
|
|
|
@@ -398,6 +455,33 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 执行退款请求
|
|
|
+ */
|
|
|
+ private AlipayTradeRefundResponse refundRun(AlipayTradeRefundRequest request) throws AlipayApiException {
|
|
|
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
|
|
|
+ AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建退款请求
|
|
|
+ */
|
|
|
+ private AlipayTradeRefundRequest buildRefundRequest(Map<String, String> params) {
|
|
|
+ AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
|
|
|
+ AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
|
|
+ model.setOutTradeNo(params.get("outTradeNo"));
|
|
|
+ model.setRefundAmount(params.get("refundAmount"));
|
|
|
+ model.setRefundReason(params.get("refundReason"));
|
|
|
+ if (StringUtils.isNotBlank(params.get("partialRefundCode"))) {
|
|
|
+ model.setOutRequestNo(params.get("partialRefundCode"));
|
|
|
+ }
|
|
|
+ request.setBizModel(model);
|
|
|
+ return request;
|
|
|
+ }
|
|
|
+
|
|
|
/** 退款失败时:订单与支付单置为退款中,并写入退款失败记录 */
|
|
|
private void markRefundFailed(UserReservationOrder order, MerchantPaymentOrder paymentOrder,
|
|
|
String errorMsg, String refundReason, Integer storeId, String outTradeNo) {
|
|
|
@@ -453,4 +537,18 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
|
|
|
return alipayConfig;
|
|
|
}
|
|
|
+
|
|
|
+ private static AlipayConfig getAlipayConfig() {
|
|
|
+ String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCBTOvScNrk0mw+WbR6Qtx2+HrPxB5IU/V2HSPGZUTDNiCiSU9UZcuXlo0UNwMksFYR43btk4BHW9OsZETdr3uJzbEEko4jQPrY49V6V8d3yFUiexcbLKf9W2X+h7EwdPDahHk6wmM73Lm500xzv8JxdGeo/d2uGTh+qD66HcPW+QYj1YbjRV1JyCOiJ2OiwLcb28arNNLOgj6PktQ69FPSWS4hWrM7nl6DLRr6SdOlyfBT47gwPtW0BQ96/2b9O+qxKBPfrcqdRDH323HvrGFDwa8GoWTdchnKwFjmfIFHMvf+eq3tzilFi8H7vQRtzVRrndwrNa0z+1ss07fcWFDRAgMBAAECggEAItgU0OAizPk7vE22SiBMgy8RAX5rXrhpdIwDwQo3Tpf+kV1KKIdKJy6mFCWDDlcKysVOnlVag2BmmZVnzYnls8wfgQjxjuSK9Pno5JBVK51r+9/J6UPOfYMs6Duu700EPw7mEISj81TXJBGiD6tEfgiNisfm/mzDgbZbORKeXQbaTyrtB+GZn6FNSyyHA1vraARMrgfMEGNzQ4AbtfcUxGO+mejdTFs0PxAq6lovHBY3fYYHI1Nx6kf9iPoom/G4UrcMO67W6QU+1tOCZCXjy4bD2y421z/8XD73+WDyYp+Tjy0hTLqVZc7TpYAOximo1vMIUe23EdJJngdlkdpDFQKBgQDFyETL0knwBSakLfAe2BmFb2x++B4YXUnt4dGbCFBnVooxf5i06GVt/CrfkJhYK6hBSowOScIRf8P6BOSQptRZb2/I1ngQm4vcpAZw6EjUTlgOj/J3XJ+ApUNQnRqE28jDrE4m2RHg4BkQo6yA3DizJAluPCtFoCYDm1a7dV7u7wKBgQCnXEH5sD8VSxURv02/gn80g/uZIP/EOU3ycjBEqZdRGkNINwXT+zqrlZIGYb+bxLvU/R2OqKC5vhcyAL3T1A8ORYqPu5KLnAxg7C+rHuVilUWwCEH7POpCk+ETPXCZwcNvLNa5PIqBH/gdV9Y9PBTef6J4rN6V6TDFgosf5by8PwKBgDpVG71Fk1sAGep4RgbC05wgRc6Y3T9wXDqVzJ098YDY7D83E9HfbPLoWbjAS75Nef1vwCkCpgNFPIbD5KmpGp4aGM0SPC0hwzlbAy9PwxMi3CPHXsrHfZ+SnmzrOQQQUoErk40vnm9FiP74VwtWaD6llUZ25ohNeIi9yvHU5x/vAoGAdU2d1JOq85LHtsO+i9+8pyNnAsJ1YqTDtI5CtK2lqKvewswGIrlxOvi//AchVN3ExZmP0QDyfp31BhAs/T8iOl+Vqf7PzVjX+Eszch5aqwlzadmv3ZepnnamCGVE+hAsmkz0R6tebPjqYC7Ds/HbssQFLc4EyVBD5fwE5ZuR+OMCgYAvGHUYpi0dY9uMHXzL721tIopiwUfKCgLAn3yhSH3p7644NxHBqLLaBLVT2q7JAZQUaZUvXlwiyxU1zvo0xmvcbnB/Vd2qp8KbEUkvHyIYVJkM6Fn+9xBosorcrHv+7B2V1XR9WQcXvppxbN/8farWGuAA0anBD+UGrxd8B0/hHg==";
|
|
|
+ String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnxevClLpYc6c8A9lwmnftPO2BeU+X6aZ/+b/n1Cvq096VJKiHmqcsRgRbrnSlmPDHRrQpDti4en2Ys0L2lx7CObIr/2xP/jJVwjIO1iWHUj/w/NAbjv7dLW/FFY4SeNp8rU+hlgGgviyUxzonfNfr3v+o8grFqQq27/hiZJAofsQRMQu1dEQqoKdJj7eQLkTstiK5miJMyQ+Y3tLztrEUMBz/zRgaCEfGqmFmRZ2diy2X+1dGaX6H4+0QJ2u50eY2QTBkNuvREGbAn6/lttAgvg/+CywPYKGeC4xOfnl5wP8iA1QXYbXrVJRkZjU097nyOmSNhLy9KvJH2BNpojS1QIDAQAB";
|
|
|
+ AlipayConfig alipayConfig = new AlipayConfig();
|
|
|
+ alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
|
|
|
+ alipayConfig.setAppId("2021005196608960");
|
|
|
+ alipayConfig.setPrivateKey(privateKey);
|
|
|
+ alipayConfig.setFormat("json");
|
|
|
+ alipayConfig.setAlipayPublicKey(alipayPublicKey);
|
|
|
+ alipayConfig.setCharset("UTF-8");
|
|
|
+ alipayConfig.setSignType("RSA2");
|
|
|
+ return alipayConfig;
|
|
|
+ }
|
|
|
}
|