From 74c33ca341881c44446b456b3d49274f4a31f3a2 Mon Sep 17 00:00:00 2001 From: egzosn Date: Sun, 5 Dec 2021 12:40:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20=E7=BD=91=E9=A1=B5=E6=94=AF=E4=BB=98=20=E4=B8=AD=E9=80=94?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=94=AF=E4=BB=98=E5=9B=9E=E8=B0=83=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=EF=BC=8C=E6=96=B0=E5=A2=9E=20=E6=94=B6=E5=8D=95?= =?UTF-8?q?=E9=80=80=E6=AC=BE=E5=86=B2=E9=80=80=E5=AE=8C=E6=88=90=E9=80=9A?= =?UTF-8?q?=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/egzosn/pay/ali/api/AliPayService.java | 76 ++++++++-- .../egzosn/pay/ali/api/AliPayServiceInf.java | 22 +++ .../com/egzosn/pay/ali/bean/AliPayConst.java | 9 ++ .../RefundDepositBackCompletedNotify.java | 139 ++++++++++++++++++ 4 files changed, 236 insertions(+), 10 deletions(-) create mode 100644 pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayServiceInf.java create mode 100644 pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/RefundDepositBackCompletedNotify.java diff --git a/pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayService.java b/pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayService.java index 3b39bd8..82011b8 100644 --- a/pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayService.java +++ b/pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayService.java @@ -10,6 +10,7 @@ import static com.egzosn.pay.ali.bean.AliPayConst.ALIPAY_CERT_SN_FIELD; import static com.egzosn.pay.ali.bean.AliPayConst.APP_AUTH_TOKEN; import static com.egzosn.pay.ali.bean.AliPayConst.BIZ_CONTENT; import static com.egzosn.pay.ali.bean.AliPayConst.CODE; +import static com.egzosn.pay.ali.bean.AliPayConst.DBACK_AMOUNT; import static com.egzosn.pay.ali.bean.AliPayConst.HTTPS_REQ_URL; import static com.egzosn.pay.ali.bean.AliPayConst.NOTIFY_URL; import static com.egzosn.pay.ali.bean.AliPayConst.PASSBACK_PARAMS; @@ -61,7 +62,7 @@ import com.egzosn.pay.common.util.str.StringUtils; * email egzosn@gmail.com * date 2017-2-22 20:09 */ -public class AliPayService extends BasePayService { +public class AliPayService extends BasePayService implements AliPayServiceInf { /** @@ -184,7 +185,6 @@ public class AliPayService extends BasePayService { } - /** * 生成并设置签名 * @@ -249,6 +249,8 @@ public class AliPayService extends BasePayService { case PAGE: bizContent.put(PASSBACK_PARAMS, order.getAddition()); bizContent.put(PRODUCT_CODE, "FAST_INSTANT_TRADE_PAY"); + bizContent.put(AliPayConst.REQUEST_FROM_URL, payConfigStorage.getReturnUrl()); + OrderParaStructure.loadParameters(bizContent, AliPayConst.REQUEST_FROM_URL, order); setReturnUrl(orderInfo, order); break; case WAP: @@ -259,6 +261,9 @@ public class AliPayService extends BasePayService { //默认值为QUICK_WAP_PAY。 bizContent.put(PRODUCT_CODE, "QUICK_WAP_PAY"); OrderParaStructure.loadParameters(bizContent, PRODUCT_CODE, order); + + bizContent.put(AliPayConst.QUIT_URL, payConfigStorage.getReturnUrl()); + OrderParaStructure.loadParameters(bizContent, AliPayConst.QUIT_URL, order); setReturnUrl(orderInfo, order); break; case APP: @@ -314,12 +319,24 @@ public class AliPayService extends BasePayService { * @return 放回公共请求参数 */ protected Map getPublicParameters(TransactionType transactionType) { + boolean depositBack = transactionType == AliTransactionType.REFUND_DEPOSITBACK_COMPLETED; Map orderInfo = new TreeMap<>(); orderInfo.put("app_id", payConfigStorage.getAppId()); - orderInfo.put("method", transactionType.getMethod()); orderInfo.put("charset", payConfigStorage.getInputCharset()); - orderInfo.put("timestamp", DateUtils.format(new Date())); - orderInfo.put("version", "1.0"); + String method = "method"; + String version = "1.0"; + if (depositBack) { + method = "msg_method"; + orderInfo.put("utc_timestamp", System.currentTimeMillis()); + version = "1.1"; + } + else { + orderInfo.put("timestamp", DateUtils.format(new Date())); + } + + orderInfo.put(method, transactionType.getMethod()); + orderInfo.put("version", version); + loadCertSn(orderInfo); return orderInfo; } @@ -482,7 +499,6 @@ public class AliPayService extends BasePayService { } - /** * 交易关闭接口 * @@ -544,12 +560,19 @@ public class AliPayService extends BasePayService { /** * 申请退款接口 + * 兼容 收单退款冲退完成通知 {@link #refundDepositBackCompleted(RefundOrder)} 与 {@link com.egzosn.pay.ali.bean.RefundDepositBackCompletedNotify} * * @param refundOrder 退款订单信息 * @return 返回支付方申请退款后的结果 */ @Override public AliRefundResult refund(RefundOrder refundOrder) { + if (null != refundOrder.getTransactionType() && refundOrder.getTransactionType() == AliTransactionType.REFUND_DEPOSITBACK_COMPLETED) { + String status = refundDepositBackCompleted(refundOrder); + AliRefundResult result = new AliRefundResult(); + result.setCode(status); + return result; + } //获取公共参数 Map parameters = getPublicParameters(AliTransactionType.REFUND); setAppAuthToken(parameters, refundOrder.getAttrs()); @@ -557,9 +580,9 @@ public class AliPayService extends BasePayService { Map bizContent = getBizContent(refundOrder.getTradeNo(), refundOrder.getOutTradeNo(), null); OrderParaStructure.loadParameters(bizContent, AliPayConst.OUT_REQUEST_NO, refundOrder.getRefundNo()); bizContent.put("refund_amount", Util.conversionAmount(refundOrder.getRefundAmount())); - OrderParaStructure.loadParameters(bizContent, AliPayConst.REFUND_REASON, refundOrder.getDescription()); - OrderParaStructure.loadParameters(bizContent, AliPayConst.REFUND_REASON, refundOrder); - OrderParaStructure.loadParameters(bizContent,"refund_royalty_parameters", refundOrder); + OrderParaStructure.loadParameters(bizContent, AliPayConst.REFUND_REASON, refundOrder.getDescription()); + OrderParaStructure.loadParameters(bizContent, AliPayConst.REFUND_REASON, refundOrder); + OrderParaStructure.loadParameters(bizContent, "refund_royalty_parameters", refundOrder); OrderParaStructure.loadParameters(bizContent, AliPayConst.QUERY_OPTIONS, refundOrder); //设置请求参数的集合 parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent)); @@ -586,7 +609,7 @@ public class AliPayService extends BasePayService { setAppAuthToken(parameters, refundOrder.getAttrs()); Map bizContent = getBizContent(refundOrder.getTradeNo(), refundOrder.getOutTradeNo(), null); OrderParaStructure.loadParameters(bizContent, AliPayConst.OUT_REQUEST_NO, refundOrder.getRefundNo()); - OrderParaStructure.loadParameters(bizContent, AliPayConst.QUERY_OPTIONS, refundOrder); + OrderParaStructure.loadParameters(bizContent, AliPayConst.QUERY_OPTIONS, refundOrder); // bizContent.putAll(refundOrder.getAttrs()); //设置请求参数的集合 parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent)); @@ -782,4 +805,37 @@ public class AliPayService extends BasePayService { public PayMessage createMessage(Map message) { return AliPayMessage.create(message); } + + /** + * 收单退款冲退完成通知 + * 退款存在退到银行卡场景下时,收单会根据银行回执消息发送退款完成信息 + * + * @param refundOrder 退款订单 + * @return fail 消息获取失败 是 success 消息获取成功 否 + */ + @Override + public String refundDepositBackCompleted(RefundOrder refundOrder) { + //获取公共参数 + Map parameters = getPublicParameters(refundOrder.getTransactionType()); + OrderParaStructure.loadParameters(parameters, "notify_id", refundOrder); + OrderParaStructure.loadParameters(parameters, "msg_type", refundOrder); + OrderParaStructure.loadParameters(parameters, "msg_uid", refundOrder); + OrderParaStructure.loadParameters(parameters, "msg_app_id", refundOrder); + + Map bizContent = getBizContent(refundOrder.getTradeNo(), refundOrder.getOutTradeNo(), null); + OrderParaStructure.loadParameters(bizContent, AliPayConst.OUT_REQUEST_NO, refundOrder.getRefundNo()); + OrderParaStructure.loadParameters(bizContent, "dback_status", refundOrder); + bizContent.put(DBACK_AMOUNT, refundOrder.getRefundAmount()); + OrderParaStructure.loadParameters(bizContent, DBACK_AMOUNT, refundOrder); + OrderParaStructure.loadParameters(bizContent, "bank_ack_time", refundOrder); + OrderParaStructure.loadParameters(bizContent, "est_bank_receipt_time", refundOrder); + //设置请求参数的集合 + parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent)); + //设置签名 + setSign(parameters); + + return null; + } + + } diff --git a/pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayServiceInf.java b/pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayServiceInf.java new file mode 100644 index 0000000..c425c45 --- /dev/null +++ b/pay-java-ali/src/main/java/com/egzosn/pay/ali/api/AliPayServiceInf.java @@ -0,0 +1,22 @@ +package com.egzosn.pay.ali.api; + +import com.egzosn.pay.common.bean.RefundOrder; + +/** + * 支付宝定制化服务接口 + * @author Egan + *
+ * email egan@egzosn.com
+ * date 2021/12/4
+ * 
+ */ +public interface AliPayServiceInf { + + /** + * 收单退款冲退完成通知 + * 退款存在退到银行卡场景下时,收单会根据银行回执消息发送退款完成信息 + * @param refundOrder 退款订单 + * @return fail 消息获取失败 是 success 消息获取成功 否 + */ + String refundDepositBackCompleted(RefundOrder refundOrder); +} diff --git a/pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/AliPayConst.java b/pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/AliPayConst.java index edd824b..dd09e40 100644 --- a/pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/AliPayConst.java +++ b/pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/AliPayConst.java @@ -68,4 +68,13 @@ public final class AliPayConst { public static final String REFUND_REASON = "refund_reason"; public static final String QUERY_OPTIONS = "query_options"; public static final String OUT_REQUEST_NO = "out_request_no"; + /** + * 用户付款中途退出返回商户网站的地址 + */ + public static final String QUIT_URL = "quit_url"; + /** + * 请求来源地址。如果使用ALIAPP的集成方式,用户中途取消支付会返回该地址。 + */ + public static final String REQUEST_FROM_URL = "request_from_url"; + public static final String DBACK_AMOUNT = "dback_amount"; } diff --git a/pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/RefundDepositBackCompletedNotify.java b/pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/RefundDepositBackCompletedNotify.java new file mode 100644 index 0000000..33f1978 --- /dev/null +++ b/pay-java-ali/src/main/java/com/egzosn/pay/ali/bean/RefundDepositBackCompletedNotify.java @@ -0,0 +1,139 @@ +package com.egzosn.pay.ali.bean; + +import com.egzosn.pay.common.bean.RefundOrder; +import com.egzosn.pay.common.bean.SignType; + +/** + * 收单退款冲退完成通知 + * + * @author Egan + *
+ * email egan@egzosn.com
+ * date 2021/12/4
+ * 
+ */ +public class RefundDepositBackCompletedNotify extends RefundOrder { + + /** + * 通知 + */ + private String notifyId; + /** + * 消息类型。目前支持类型:sys:系统消息;usr,用户消息;app,应用消息 + */ + private String msgType; + + /** + * 消息归属的商户支付宝uid。用户消息和应用消息时非空 + */ + private String msgUid; + + /** + * 消息归属方的应用id。应用消息时非空 + */ + private String msgAppId; + /** + * 加密算法 + */ + private SignType encryptType; + + + /** + * 银行卡冲退状态。S-成功,F-失败。银行卡冲退失败,资金自动转入用户支付宝余额。 + */ + private String dbackStatus; + /** + * 银行卡冲退金额 + */ + private String dbackAmount; + /** + * 银行响应时间,格式为yyyy-MM-dd HH:mm:ss + */ + private String bankAckTime; + /** + * 预估银行入账时间,格式为yyyy-MM-dd HH:mm:ss + */ + private String estBankReceiptTime; + + public String getNotifyId() { + return notifyId; + } + + public void setNotifyId(String notifyId) { + this.notifyId = notifyId; + addAttr("notify_id", notifyId); + } + + public String getMsgType() { + return msgType; + } + + public void setMsgType(String msgType) { + this.msgType = msgType; + addAttr("msg_type", msgType); + } + + public String getMsgUid() { + return msgUid; + } + + public void setMsgUid(String msgUid) { + this.msgUid = msgUid; + addAttr("msg_uid", msgUid); + } + + public String getMsgAppId() { + return msgAppId; + } + + public void setMsgAppId(String msgAppId) { + this.msgAppId = msgAppId; + addAttr("msg_app_id", msgAppId); + } + + public SignType getEncryptType() { + return encryptType; + } + + public void setEncryptType(SignType encryptType) { + this.encryptType = encryptType; + addAttr("encrypt_type", encryptType); + } + + + public String getDbackStatus() { + return dbackStatus; + } + + public void setDbackStatus(String dbackStatus) { + this.dbackStatus = dbackStatus; + addAttr("dback_status", dbackStatus); + } + + public String getDbackAmount() { + return dbackAmount; + } + + public void setDbackAmount(String dbackAmount) { + this.dbackAmount = dbackAmount; + addAttr("dback_amount", dbackAmount); + } + + public String getBankAckTime() { + return bankAckTime; + } + + public void setBankAckTime(String bankAckTime) { + this.bankAckTime = bankAckTime; + addAttr("bank_ack_time", bankAckTime); + } + + public String getEstBankReceiptTime() { + return estBankReceiptTime; + } + + public void setEstBankReceiptTime(String estBankReceiptTime) { + this.estBankReceiptTime = estBankReceiptTime; + addAttr("est_bank_receipt_time", estBankReceiptTime); + } +}