diff --git a/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/AliPay.java b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/AliPay.java index 0212fc9b..1cc2872f 100644 --- a/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/AliPay.java +++ b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/AliPay.java @@ -8,6 +8,7 @@ import com.alipay.api.DefaultAlipayClient; import com.alipay.api.domain.AlipayTradePayModel; import com.alipay.api.domain.AlipayTradeQueryModel; import com.alipay.api.domain.AlipayTradeRefundModel; +import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.request.AlipayTradeAppPayRequest; import com.alipay.api.request.AlipayTradePayRequest; import com.alipay.api.request.AlipayTradeQueryRequest; @@ -20,8 +21,8 @@ import com.alipay.api.response.AlipayTradeWapPayResponse; import com.hccake.starte.pay.ali.domain.AliPayQuery; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.Map; import lombok.Data; -import lombok.NoArgsConstructor; /** * api文档: https://opendocs.alipay.com/apis. @@ -286,7 +287,7 @@ public class AliPay { * @return com.alipay.api.response.AlipayTradeQueryResponse * @author lingting 2021-01-25 11:12 */ - public AliPayQuery query(String sn) throws AlipayApiException { + public AliPayQuery query(String sn) throws AlipayApiException { return query(sn, null); } @@ -297,7 +298,7 @@ public class AliPay { * @return com.alipay.api.response.AlipayTradeQueryResponse * @author lingting 2021-01-25 11:12 */ - public AliPayQuery query(String sn, String tradeNo) throws AlipayApiException { + public AliPayQuery query(String sn, String tradeNo) throws AlipayApiException { AlipayTradeQueryModel model = new AlipayTradeQueryModel(); model.setOutTradeNo(sn); model.setTradeNo(tradeNo); @@ -309,7 +310,7 @@ public class AliPay { * @return com.alipay.api.response.AlipayTradeQueryResponse * @author lingting 2021-01-25 11:12 */ - public AliPayQuery query(AlipayTradeQueryModel model) throws AlipayApiException { + public AliPayQuery query(AlipayTradeQueryModel model) throws AlipayApiException { AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); request.setBizModel(model); return AliPayQuery.of(client.execute(request)); @@ -353,6 +354,30 @@ public class AliPay { return client.execute(request); } + /** + * v1 版本验签 + * @param map 所有参数 + * @return boolean + * @author lingting 2021-01-26 14:46 + */ + public boolean checkSignV1(Map map) throws AlipayApiException { + // 验签需要先移除 fund_bill_list 参数值中的 " 否则会导致正确的签名验签失败 + map.put("fund_bill_list", map.get("fund_bill_list").replaceAll(""","\"")); + return AlipaySignature.rsaCheckV1(map, alipayPublicKey, charset, signType); + } + + /** + * v2 版本验签 + * @param map 所有参数 + * @return boolean + * @author lingting 2021-01-26 14:46 + */ + public boolean checkSignV2(Map map) throws AlipayApiException { + // 验签需要先移除 fund_bill_list 参数值中的 " 否则会导致正确的签名验签失败 + map.put("fund_bill_list", map.get("fund_bill_list").replaceAll(""","\"")); + return AlipaySignature.rsaCheckV2(map, alipayPublicKey, charset, signType); + } + /** * 金额单位转换, 元 转为 分 * @param amount 支付金额, 单位 元 diff --git a/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/domain/AliPayCallback.java b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/domain/AliPayCallback.java new file mode 100644 index 00000000..fd6c940a --- /dev/null +++ b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/domain/AliPayCallback.java @@ -0,0 +1,121 @@ +package com.hccake.starte.pay.ali.domain; + +import static com.hccake.ballcat.common.core.util.JacksonUtils.toJson; +import static com.hccake.ballcat.common.core.util.JacksonUtils.toObj; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.hccake.starte.pay.ali.enums.TradeStatus; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author lingting 2021/1/26 13:31 + */ +@NoArgsConstructor +@Data +public class AliPayCallback { + + /** + * 解析回调参数 + * @param callbackParams 所有回调参数 + * @return com.hccake.starte.pay.ali.domain.AliPayCallback + * @author lingting 2021-01-26 14:39 + */ + public static AliPayCallback of(Map callbackParams) { + Map map = new HashMap<>(callbackParams); + String fundBillListStr = callbackParams.get("fund_bill_list").replaceAll(""", "\""); + map.put("fund_bill_list", toObj(fundBillListStr, List.class)); + // 覆盖原值 + callbackParams.put("fund_bill_list", fundBillListStr); + return toObj(toJson(map), AliPayCallback.class); + } + + @JsonProperty("gmt_create") + private String gmtCreate; + + @JsonProperty("charset") + private String charset; + + @JsonProperty("seller_email") + private String sellerEmail; + + @JsonProperty("subject") + private String subject; + + @JsonProperty("sign") + private String sign; + + @JsonProperty("buyer_id") + private String buyerId; + + @JsonProperty("invoice_amount") + private BigDecimal invoiceAmount; + + @JsonProperty("notify_id") + private String notifyId; + + @JsonProperty("fund_bill_list") + private List fundBillList; + + @JsonProperty("notify_type") + private String notifyType; + + @JsonProperty("trade_status") + private TradeStatus tradeStatus; + + @JsonProperty("receipt_amount") + private BigDecimal receiptAmount; + + @JsonProperty("app_id") + private String appId; + + @JsonProperty("buyer_pay_amount") + private BigDecimal buyerPayAmount; + + @JsonProperty("sign_type") + private String signType; + + @JsonProperty("seller_id") + private String sellerId; + + @JsonProperty("gmt_payment") + private String gmtPayment; + + @JsonProperty("notify_time") + private String notifyTime; + + @JsonProperty("version") + private String version; + + @JsonProperty("out_trade_no") + private String outTradeNo; + + @JsonProperty("total_amount") + private BigDecimal totalAmount; + + @JsonProperty("trade_no") + private String tradeNo; + + @JsonProperty("auth_app_id") + private String authAppId; + + @JsonProperty("buyer_logon_id") + private String buyerLogonId; + + @JsonProperty("point_amount") + private BigDecimal pointAmount; + + @Data + public static class FundBill { + + private BigDecimal amount; + + private String fundChannel; + + } + +} diff --git a/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/domain/AliPayQuery.java b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/domain/AliPayQuery.java index d651308d..1a875c55 100644 --- a/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/domain/AliPayQuery.java +++ b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/domain/AliPayQuery.java @@ -4,6 +4,7 @@ import static com.hccake.starte.pay.ali.constants.AliPayConstant.CODE_SUCCESS; import cn.hutool.core.util.StrUtil; import com.alipay.api.response.AlipayTradeQueryResponse; +import com.hccake.starte.pay.ali.enums.TradeStatus; import java.math.BigDecimal; import lombok.AccessLevel; import lombok.Getter; @@ -30,11 +31,11 @@ public class AliPayQuery { // 状态处理 if (CODE_SUCCESS.equals(raw.getCode())) { // 成功 - query.setStatus(Status.of(raw.getTradeStatus())); + query.setStatus(TradeStatus.of(raw.getTradeStatus())); } // 异常 else { - query.setStatus(Status.ERROR); + query.setStatus(TradeStatus.ERROR); } // 金额 @@ -62,7 +63,7 @@ public class AliPayQuery { /** * 订单状态 */ - private Status status; + private TradeStatus status; private String code; @@ -101,49 +102,4 @@ public class AliPayQuery { private String userType; - /** - * 交易状态 - */ - public enum Status { - - /** - * 成功 - */ - SUCCESS, - /** - * 未支付 - */ - WAIT, - /** - * 未付款交易超时关闭,或支付完成后全额退款 - */ - CLOSED, - /** - * 交易结束,不可退款 - */ - FINISHED, - /** - * 异常. 具体信息查询 subCode和subMsg - */ - ERROR, - - ; - - public static Status of(String status) { - switch (status) { - case "WAIT_BUYER_PAY": - return WAIT; - case "TRADE_CLOSED": - return CLOSED; - case "TRADE_SUCCESS": - return SUCCESS; - case "TRADE_FINISHED": - return FINISHED; - default: - return ERROR; - } - } - - } - } diff --git a/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/enums/TradeStatus.java b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/enums/TradeStatus.java new file mode 100644 index 00000000..4ac7e7bf --- /dev/null +++ b/ballcat-extends/ballcat-extend-pay-ali/src/main/java/com/hccake/starte/pay/ali/enums/TradeStatus.java @@ -0,0 +1,49 @@ +package com.hccake.starte.pay.ali.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * 交易状态 + */ +public enum TradeStatus { + + /** + * 成功 + */ + SUCCESS, + /** + * 未支付 + */ + WAIT, + /** + * 未付款交易超时关闭,或支付完成后全额退款 + */ + CLOSED, + /** + * 交易结束,不可退款 + */ + FINISHED, + /** + * 异常. 具体信息查询 subCode和subMsg + */ + ERROR, + + ; + + @JsonCreator + public static TradeStatus of(String status) { + switch (status) { + case "WAIT_BUYER_PAY": + return WAIT; + case "TRADE_CLOSED": + return CLOSED; + case "TRADE_SUCCESS": + return SUCCESS; + case "TRADE_FINISHED": + return FINISHED; + default: + return ERROR; + } + } + +} diff --git a/ballcat-samples/ballcat-sample-pay/pom.xml b/ballcat-samples/ballcat-sample-pay/pom.xml index dfd72a4a..9a746ec8 100644 --- a/ballcat-samples/ballcat-sample-pay/pom.xml +++ b/ballcat-samples/ballcat-sample-pay/pom.xml @@ -17,6 +17,10 @@ + + com.hccake + ballcat-common-conf + com.hccake ballcat-spring-boot-starter-pay diff --git a/ballcat-samples/ballcat-sample-pay/src/main/java/com/hccake/sample/pay/ali/Controller.java b/ballcat-samples/ballcat-sample-pay/src/main/java/com/hccake/sample/pay/ali/Controller.java index 9b2fd7cd..4e3b6d96 100644 --- a/ballcat-samples/ballcat-sample-pay/src/main/java/com/hccake/sample/pay/ali/Controller.java +++ b/ballcat-samples/ballcat-sample-pay/src/main/java/com/hccake/sample/pay/ali/Controller.java @@ -3,12 +3,15 @@ package com.hccake.sample.pay.ali; import cn.hutool.core.lang.Snowflake; import cn.hutool.core.util.IdUtil; import com.hccake.starte.pay.ali.AliPay; +import com.hccake.starte.pay.ali.domain.AliPayCallback; import java.math.BigDecimal; import java.util.Map; +import javax.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -21,18 +24,27 @@ public class Controller { private final AliPay aliPay; + BigDecimal amount = new BigDecimal("100"); + + BigDecimal zero = new BigDecimal("0.01"); + private static final Snowflake snowflake = IdUtil.createSnowflake(1, 1); + /** + * 支付宝支付回调 + * @param callback 回调参数 + * @return java.lang.String + * @author lingting 2021-01-26 15:18 + */ @PostMapping - public String notice(Map params) { - + public String notice(HttpServletRequest request, @RequestParam Map callback) { + System.out.println("notice"); + AliPayCallback of = AliPayCallback.of(callback); return "success"; } @GetMapping public String debug() { - String sn = snowflake.nextIdStr(); - BigDecimal amount = new BigDecimal("100"); // System.out.printf(sn); // aliPay.codePay(sn, amount, "280528061260052112", "测试"); return "success"; diff --git a/ballcat-samples/ballcat-sample-pay/src/main/resources/application.yml b/ballcat-samples/ballcat-sample-pay/src/main/resources/application.yml index 748e8a62..8514efe9 100644 --- a/ballcat-samples/ballcat-sample-pay/src/main/resources/application.yml +++ b/ballcat-samples/ballcat-sample-pay/src/main/resources/application.yml @@ -1,3 +1,7 @@ +spring: + application: + name: 支付演示 + ballcat: pay: bitcoin: