From 3b0749da5719cbbc2cd493f8f1d2188914001312 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Thu, 5 Jun 2025 12:09:16 +0800 Subject: [PATCH 1/6] 11 --- .../src/main/resources/doc/第三方支付文档.wps | Bin 169984 -> 168960 bytes .../java/com/bsd/pjcloud/admin/PayTest.java | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/doc/第三方支付文档.wps b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/doc/第三方支付文档.wps index a8d465388ebe11990a9d2126977c1e38cb543bc2..f6e3916d1aaaa2fd32fdb914d8c55867047a14ef 100644 GIT binary patch delta 1648 zcmZvde@xVM7{@=)hd55WJHB@uaxp+a+^A5blolaB3=n~dFmpi*ZYoGgz)+hzft?)b zYz)Z@KFrPO2;HSFnymX8kvb~ZvJm)#wW!vN5vzq^ZW0LB`vWE4Hov#meLwH#dA`p+ zpXYhLcg~Ljou0t94RM*omM(>{m#~&{!RPZyV>ZNAkOS0=7Ve=_Ji}PQmma`(iOHR) zi*#4A|{=%(I8-3fBr`3hHGfZ7*8+e>tjcp_d=P47`OiG+`7 z!~nwvkPUK#*-jB+eFqucn{~13tCe(~%sKEB0Xx_W>QqGCB~u;N2SGDvd6aS=4I5iv zky|?lx*nHP>4K*lTmcp{V;$9Gd;R`$6&Rb=iV3awMJs;Riear7(28EI=$3U7&KhbI zKdk0!M0pj3aJIr*OZq5Xaxm%;teXB@EKoa6lLJdWCB6EJ zi;I?pxJSk~hw-ws7Sb9~kjD>j=I_ntGwUqz zcv0kwC|^4HdUYwnrr`%IijC%73AK~h`M*as;wA$+A1$-?ziS076MdTI_)s$bojs$`9&I;bY?6{ROF*f*9oHvU%LkC%Kei$WLQ7`Jc#?{zB!eFr`i zXAe%+O*x8A>^*X;*is)?9p3O&aX~{^!9v5E%B@Cm#>K;9=Z=man=*cXJj=asX6nv^ z9&h<<&#AI6dwrK3>ixLsPnwR_d@6=rJl&7Ie_bfee4XvHum`gXqj%@NuJ=9Mv+Mf& z%}(EZZBvO)Y-{G>*6#gtKGz%bi@)6^OJ}K24>j{L@*d+E6waoHpL(%?(&ZUF=Agg( z#+KGfgi@xycASR>P`WtO%A2V|%(imJ%8i6#pvJg_xs4~d({&d0#z}4nFv$OiO>idx a@m&Xx4Uv`%s4YOQC0XK0!GC?XR{szDHJgwC delta 1664 zcmZvde@xVM7{@=)M-B+N850={cao-L6X z9*49W4kQba2<=giU&h8;4J$t4YeeoLZ0#`QrU)U~DgD<(A+q6fI9`ZG1l)<|W6)2- zISC$}hBgHJ0+K#-E25YpDG83G+Ztsrb^4-oUldi=(nD~_(+ll%nY0+ZngOg}Gbq=! zdYUIwIphjZ1M1DX=`LlG%HL1djP4i3Q|uFQukx5Jg$aOFn0 zG9IoBhb!k$xJ$~d$fbT6r-u#Pb`N;_DLN~Z3NNSPD4O65_y!DvD`1sWu=y(Z11uzS zDkew`d`PKrV$A|TUSBiu7JkoSOk(3o<6z(&{{ zzzsV7AFu<)e()JM1EzujH%vjE2DiWhsI;K2;J*H;P)W74K|PsES;}#evZB`rVZ)RR zsp?8f(Fc80&Ak(QnR4`;KAI%&_Z002C2WQhX3i8M732adC<3b_jLpTM8rU=Wes{=d zhq4d64V+3Vmf_(@ zBt(IJ%qjmQO4nVjvP$L{-6YN##WLL6gb(YyLeD+wj!SN}BzCz9Ti5lJn9C+hob=lE zguvwX$?2Be>iKqAU|Aazc=Jnjs=4O;)?T|J~8y%{-vaO0rd3QjI``b4el*ezj+x3?^Wl9w7P=~wZ5o%KY zF6mrbhy-jz#;}yuE%Om7ULXBH#zw^!VCxCMe;exOUYVU<3e9%UvJ=mz@5$`(jM6;v G_kRJpnUy5~ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/test/java/com/bsd/pjcloud/admin/PayTest.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/test/java/com/bsd/pjcloud/admin/PayTest.java index 3ea4a9c5a..1d5fbfee3 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/test/java/com/bsd/pjcloud/admin/PayTest.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/test/java/com/bsd/pjcloud/admin/PayTest.java @@ -29,8 +29,8 @@ import java.util.Map; @SpringBootTest(classes = ThirdPartyApp.class) public class PayTest { - // private final String baseUrl = "http://123.156.230.15:8089/api"; - private final String baseUrl = "http://127.0.0.1:9999"; + private final String baseUrl = "http://123.156.230.15:8089/api"; + // private final String baseUrl = "http://127.0.0.1:9999"; private final String walletInfoUrl = "/third/third-pay-api/user-wallet"; @@ -80,7 +80,7 @@ public class PayTest { Map paramsMap = new HashMap<>(); paramsMap.put("userId", 1875049673022279681L); paramsMap.put("thirdOrderId", System.currentTimeMillis()); - paramsMap.put("price", 800); + paramsMap.put("price", 900); paramsMap.put("products", null); String body = JSONUtil.toJsonStr(paramsMap); // 发送请求 @@ -119,7 +119,7 @@ public class PayTest { public void walletRefund() throws Exception { ThirdKeyManageEntity config = getLbConfig(); Map paramsMap = new HashMap<>(); - paramsMap.put("platformOrderId", "1928048358927982594"); + paramsMap.put("platformOrderId", "1928337501121765377"); paramsMap.put("thirdRefundId", System.currentTimeMillis()); paramsMap.put("price", "300"); String body = JSONUtil.toJsonStr(paramsMap); @@ -152,7 +152,7 @@ public class PayTest { public void detail() throws Exception { ThirdKeyManageEntity config = getLbConfig(); Map paramsMap = new HashMap<>(); - paramsMap.put("thirdOrderId", "1748517531534"); + paramsMap.put("thirdOrderId", "1748586470745"); paramsMap.put("thirdRefundId", ""); String body = JSONUtil.toJsonStr(paramsMap); // 发送请求 From 6381c3be2f51276cc3ec508671911c706551f8e7 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Fri, 6 Jun 2025 14:42:08 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat:=E4=BD=8D=E7=BD=AE=E4=BB=98=E6=AC=BE?= =?UTF-8?q?=E7=A0=81=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/constant/order/HardPayTypeEnum.java | 11 +- .../api/dto/wechat/WechatMicropayDto.java | 28 ++ .../hard/api/dto/wechat/WechatQueryDto.java | 21 ++ .../hard/api/dto/wechat/WechatRefundDto.java | 21 ++ .../api/dto/wechat/WechatRefundQueryDto.java | 17 + .../wechat/WechantRefunCallbackSoureVo.java | 30 ++ .../api/vo/wechat/WechantRefunCallbackVo.java | 77 ++++ .../hard/api/vo/wechat/WechatMicropayVo.java | 43 +++ .../hard/api/vo/wechat/WechatQueryVo.java | 125 +++++++ .../api/vo/wechat/WechatRefundQueryVo.java | 102 ++++++ .../hard/api/vo/wechat/WechatRefundVo.java | 84 +++++ .../bsd/pjcloud/hard/config/WechatPay.java | 43 +++ .../wechant/WechantPayController.java | 40 +++ .../hard/service/HardOrderService.java | 7 +- .../hard/service/WechatPayService.java | 46 +++ .../impl/order/HardOrderServiceImpl.java | 62 +++- .../impl/wechat/WechatPayServiceImpl.java | 332 ++++++++++++++++++ .../utils/constant/WechantPayConstant.java | 63 ++++ .../src/main/resources/application.yml | 8 + .../pjcloud-thirdparty-biz/pom.xml | 6 + .../wechant/WechantPayController.java | 40 +++ .../com/bsd/pjcloud/wallet/WechatPayTest.java | 68 ++++ 22 files changed, 1257 insertions(+), 17 deletions(-) create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatQueryDto.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundQueryDto.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackSoureVo.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatMicropayVo.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatQueryVo.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundQueryVo.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundVo.java create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/WechatPay.java create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/wechant/WechantPayController.java create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/wechat/WechatPayServiceImpl.java create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java create mode 100644 pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java create mode 100644 pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/WechatPayTest.java diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardPayTypeEnum.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardPayTypeEnum.java index 1d054be0e..63bbb45b3 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardPayTypeEnum.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardPayTypeEnum.java @@ -24,6 +24,8 @@ public enum HardPayTypeEnum { RESERVE_QR_CODE("7", "线上二维码支付"), CASH("8", "现金支付"), HARD_DOOR_FREE_PAY("9", "智能柜免密支付"), + WECHANT_SELF_QR_CODE_PAY("10", "微信付款码支付"), + ALI_SELF_QR_CODE_PAY("11", "支付宝付款码支付"), ; private final String type; private final String description; @@ -36,7 +38,14 @@ public enum HardPayTypeEnum { CASH ); - public static final List isNotPay = List.of( + public static final List isNotWalletPay = List.of( + STRIDE_DEPT_QR_CODE, + FOREIGN_TICKET_QR_CODE, + WECHANT_SELF_QR_CODE_PAY, + ALI_SELF_QR_CODE_PAY + ); + + public static final List isNeedCancel = List.of( STRIDE_DEPT_QR_CODE, FOREIGN_TICKET_QR_CODE ); diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java new file mode 100644 index 000000000..79b1b40d4 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java @@ -0,0 +1,28 @@ +package com.bsd.pjcloud.hard.api.dto.wechat; + +import lombok.Data; + +@Data +public class WechatMicropayDto { + + /** + * 商户id + */ + private Long merId; + + /** + * 订单id + */ + private Long orderId; + + /** + * 支付金额(分) + */ + private Long price; + + /** + * 微信付款码code + */ + private String wechatQrCode; + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatQueryDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatQueryDto.java new file mode 100644 index 000000000..c3678e794 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatQueryDto.java @@ -0,0 +1,21 @@ +package com.bsd.pjcloud.hard.api.dto.wechat; + +import lombok.Data; + +/** + * 查询订单入参 + */ +@Data +public class WechatQueryDto { + + /** + * 微信订单号 + */ + private String wechantOrderId; + + /** + * 商户订单号 + */ + private String orderId; + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java new file mode 100644 index 000000000..b3e67c85c --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java @@ -0,0 +1,21 @@ +package com.bsd.pjcloud.hard.api.dto.wechat; + +import lombok.Data; + +/** + * 退款入参 + */ +@Data +public class WechatRefundDto { + + private String orderId; + + private String wechantOrderId; + + private String refundId; + + private Long orderPrice; + + private Long refundPrice; + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundQueryDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundQueryDto.java new file mode 100644 index 000000000..b01d99737 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundQueryDto.java @@ -0,0 +1,17 @@ +package com.bsd.pjcloud.hard.api.dto.wechat; + +import lombok.Data; + +/** + * 微信退款查询入参 + */ +@Data +public class WechatRefundQueryDto { + + /** + * 退款id + */ + private String refundId; + + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackSoureVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackSoureVo.java new file mode 100644 index 000000000..8f0905354 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackSoureVo.java @@ -0,0 +1,30 @@ +package com.bsd.pjcloud.hard.api.vo.wechat; + +import lombok.Data; + +/** + * 微信退款回调加密的返回参数 + */ +@Data +public class WechantRefunCallbackSoureVo { + + /** + * 公众账号ID + */ + private String appid; + + /** + * 退款的商户号 + */ + private String mch_id; + + /** + * 随机字符串 + */ + private String nonce_str; + + /** + * 加密信息 + */ + private String req_info; +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java new file mode 100644 index 000000000..bd00563b5 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java @@ -0,0 +1,77 @@ +package com.bsd.pjcloud.hard.api.vo.wechat; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; + +/** + * 微信退款回调返回参数 + */ +@Data +public class WechantRefunCallbackVo { + + public static final String SUCCESS_CODE = "SUCCESS"; + + /** + * 微信订单号 + */ + private String transaction_id; + + /** + * 商户订单号 + */ + private String out_trade_no; + + /** + * 微信退款单号 + */ + private String refund_id; + + /** + * 商户退款单号 + */ + private String out_refund_no; + + /** + * 订单金额 + */ + private String total_fee; + + /** + * 应结订单金额 + */ + private String settlement_total_fee; + + /** + * 申请退款金额 + */ + private String refund_fee; + + /** + * 退款金额 + */ + private String settlement_refund_fee; + + /** + * 退款状态 + */ + private String refund_status; + + public boolean isAllSuccess() { + return ObjectUtil.equals(refund_status, SUCCESS_CODE); + } + + public static String wechantError() { + return "" + + "" + + "" + + ""; + } + + public static String wechantSuccess() { + return "" + + "" + + "" + + ""; + } + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatMicropayVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatMicropayVo.java new file mode 100644 index 000000000..0c3878e6a --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatMicropayVo.java @@ -0,0 +1,43 @@ +package com.bsd.pjcloud.hard.api.vo.wechat; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; + +@Data +public class WechatMicropayVo { + + public static final String SUCCESS = "SUCCESS"; + + private String return_code; + + private String return_msg; + + private String appid; + + private String mch_id; + + private String device_info; + + private String nonce_str; + + private String sign; + + private String result_code; + + private String err_code; + + private String err_code_des; + + public boolean isHttpSucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, return_code); + } + + public boolean isPaySucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, result_code); + } + + public boolean isAllSuccess(){ + return isHttpSucess() && isPaySucess(); + } + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatQueryVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatQueryVo.java new file mode 100644 index 000000000..c4cd034b6 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatQueryVo.java @@ -0,0 +1,125 @@ +package com.bsd.pjcloud.hard.api.vo.wechat; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; + +/** + * 查询订单返回 + */ +@Data +public class WechatQueryVo { + public static final String SUCCESS = "SUCCESS"; + + private String return_code; + + private String return_msg; + + private String appid; + + private String mch_id; + + private String nonce_str; + + private String sign; + + private String result_code; + + private String err_code; + + private String err_code_des; + + private String device_info; + + /** + * 用户标识 + */ + private String openid; + + /** + * 是否关注公众账号 + */ + private String is_subscribe; + + /** + * 交易类型 + */ + private String trade_type; + + /** + * 交易状态 + */ + private String trade_state; + + /** + * 付款银行 + */ + private String bank_type; + + /** + * 标价金额 + */ + private String total_fee; + + /** + * 应结订单金额 + */ + private String settlement_total_fee; + + /** + * 标价币种 + */ + private String fee_type; + + /** + * 现金支付金额 + */ + private String cash_fee; + + /** + * 现金支付币种 + */ + private String cash_fee_type; + + /** + * 代金券金额 + */ + private String coupon_fee; + + /** + * 代金券使用数量 + */ + private String coupon_count; + + /** + * 微信支付订单号 + */ + private String transaction_id; + + /** + * 商户订单号 + */ + private String out_trade_no; + + /** + * 附加数据 + */ + private String attach; + + /** + * 支付完成时间 + */ + private String time_end; + + /** + * 交易状态描述 + */ + private String trade_state_desc; + + public boolean isHttpSucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, return_code); + } + + public boolean isPaySucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, result_code); + } +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundQueryVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundQueryVo.java new file mode 100644 index 000000000..3479d177e --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundQueryVo.java @@ -0,0 +1,102 @@ +package com.bsd.pjcloud.hard.api.vo.wechat; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; + +/** + * 退款返回 + */ +@Data +public class WechatRefundQueryVo { + + public static final String SUCCESS = "SUCCESS"; + + /** + * 业务结果 + */ + private String result_code; + + /** + * 错误码 + */ + private String err_code; + + /** + * 错误描述 + */ + private String err_code_des; + + /** + * 公众账号ID + */ + private String appid; + + /** + * 商户号 + */ + private String mch_id; + + /** + * 随机字符串 + */ + private String nonce_str; + + /** + * 签名 + */ + private String sign; + + /** + * 订单总退款次数 + */ + private Long total_refund_count; + + /** + * 微信订单号 + */ + private String transaction_id; + + /** + * 商户订单号 + */ + private String out_trade_no; + + /** + * 订单金额 + */ + private Long total_fee; + + /** + * 应结订单金额 + */ + private Long settlement_total_fee; + + /** + * 货币种类 + */ + private String fee_type; + + /** + * 现金支付金额 + */ + private Long cash_fee; + + /** + * 退款笔数 + */ + private Long refund_count; + + /** + * 退款总金额 + */ + private Long refund_fee; + + public boolean isHttpSucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, err_code); + } + + public boolean isPaySucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, result_code); + } + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundVo.java new file mode 100644 index 000000000..4355502e7 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechatRefundVo.java @@ -0,0 +1,84 @@ +package com.bsd.pjcloud.hard.api.vo.wechat; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; + +/** + * 退款返回 + */ +@Data +public class WechatRefundVo { + + public static final String SUCCESS = "SUCCESS"; + + private String return_code; + + private String return_msg; + + private String result_code; + + private String err_code; + + private String err_code_des; + + private String appid; + + private String mch_id; + + private String nonce_str; + + + private String sign; + + /** + * 微信支付订单号 + */ + private String transaction_id; + + /** + * 商户订单号 + */ + private String out_trade_no; + + /** + * 商户退款单号 + */ + private String out_refund_no; + + /** + * 微信退款单号 + */ + private String refund_id; + + /** + * 退款金额 + */ + private String refund_fee; + + /** + * 应结退款金额 + */ + private String settlement_refund_fee; + + /** + * 标价金额 + */ + private String total_fee; + + /** + * 应结订单金额 + */ + private String settlement_total_fee; + + public boolean isHttpSucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, return_code); + } + + public boolean isPaySucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, result_code); + } + + public boolean isAllSuccess() { + return isHttpSucess() && isPaySucess(); + } +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/WechatPay.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/WechatPay.java new file mode 100644 index 000000000..b201ed6bd --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/WechatPay.java @@ -0,0 +1,43 @@ +package com.bsd.pjcloud.hard.config; + + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "wechat-pay") +@Data +public class WechatPay { + + /** + * 基础路径 + */ + private String baseUrl; + + /** + * 微信公共平台 appId + */ + private String appId; + + /** + * 商户号 + */ + private String merchantId; + + /** + * 商户证书序列path + */ + private String merchantSerialPath; + + /** + * 商户APIV2密钥 + */ + private String apiV2Key; + + /** + * 退款回调地址 + */ + private String refundCallbackUrl; + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/wechant/WechantPayController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/wechant/WechantPayController.java new file mode 100644 index 000000000..c96891b49 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/wechant/WechantPayController.java @@ -0,0 +1,40 @@ +package com.bsd.pjcloud.hard.controller.wechant; + +import com.bsd.pjcloud.common.security.annotation.Inner; +import com.bsd.pjcloud.hard.service.WechatPayService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/hard-wechant-pay") +@Tag(description = "hard-wechant", name = "微信相关") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +@Validated +public class WechantPayController { + + private final WechatPayService wechatPayService; + + /* ************************************* start callback start ************************************* */ + + @Inner(value = false) + @PostMapping("/callback/refund") + @Operation(summary = "微信退款回调") + public String refundCallback(HttpEntity httpEntity, @RequestHeader Map headers) { + return wechatPayService.refundCallback(httpEntity, headers); + } + + /* ************************************* end callback end ************************************* */ + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java index ec193b7b2..0cc4b93f6 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java @@ -63,10 +63,15 @@ public interface HardOrderService extends IService { Long cancelHardDoorOrder(Long orderId); /** - * 快速扣款,离线订单使用 + * 快速扣款 */ void fastReduceBalance(HardOrderEntity order); + /** + * 订单成功 + */ + void orderSuccess(HardOrderEntity order, Boolean isPay); + /** * 计算额外金额 */ diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java new file mode 100644 index 000000000..e939494e4 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java @@ -0,0 +1,46 @@ +package com.bsd.pjcloud.hard.service; + + +import com.bsd.pjcloud.hard.api.dto.wechat.WechatMicropayDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatQueryDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundQueryDto; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatMicropayVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatQueryVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundQueryVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundVo; +import org.springframework.http.HttpEntity; +import org.springframework.web.bind.annotation.RequestHeader; + +import java.util.Map; + +/** + * 微信支付 + */ +public interface WechatPayService { + + /** + * 付款码支付 + */ + WechatMicropayVo micropay(WechatMicropayDto dto); + + /** + * 查询订单 + */ + WechatQueryVo query(WechatQueryDto dto); + + /** + * 申请退款 + */ + WechatRefundVo refund(WechatRefundDto dto); + + /** + * 查询退款 + */ + WechatRefundQueryVo refundQuery(WechatRefundQueryDto dto); + + /** + * 退款回调 + */ + String refundCallback(HttpEntity httpEntity, @RequestHeader Map headers); +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java index 7b9becf98..5afcb52fa 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java @@ -196,14 +196,18 @@ public class HardOrderServiceImpl extends ServiceImpl walletResult = remoteWalletService.getWallet(dto.getUserId(), WalletTypeEnum.EAT); @@ -237,7 +241,7 @@ public class HardOrderServiceImpl extends ServiceImpl params) { + String apiKey = wechatPay.getApiV2Key(); + Map filtered = new TreeMap<>(); + for (Map.Entry entry : params.entrySet()) { + if (ObjectUtil.isEmpty(entry.getValue()) || ObjectUtil.equals("sign", entry.getKey())) { + continue; + } + filtered.put(entry.getKey(), String.valueOf(entry.getValue())); + } + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : filtered.entrySet()) { + sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); + } + sb.append("key=").append(apiKey); + try { + String sign = DigestUtils.md5Hex(String.valueOf(sb)); + return sign.toUpperCase(); + } catch (Exception e) { + log.error("微信支付签名生成失败", e); + } + return ""; + } + + private WechantPayConstant.Api initApi(WechantPayConstant.Api api) { + api.setBaseUrl(wechatPay.getBaseUrl()); + return api; + } + + private String getNonceStr() { + int length = 32; + return RandomUtil.randomString(length); + } + + private SSLSocketFactory createSSLSocketFactory() throws Exception { + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + FileInputStream certStream = new FileInputStream(wechatPay.getMerchantSerialPath()); + keyStore.load(certStream, wechatPay.getMerchantId().toCharArray()); + certStream.close(); + // 创建KeyManagerFactory + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, wechatPay.getMerchantId().toCharArray()); + // 创建TrustManagerFactory(信任所有证书) + TrustManager[] trustManagers = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + // 创建SSLContext + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, new SecureRandom()); + return sslContext.getSocketFactory(); + } + + /** + * 解密回调信息解密 + */ + private WechantRefunCallbackVo decrypt(String xml) { + try { + WechantRefunCallbackSoureVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(xml)), WechantRefunCallbackSoureVo.class); + String reqInfo = vo.getReq_info(); + // 1 对加密串A做base64解码,得到加密串B + byte[] encryptedBytes = Base64.decode(reqInfo); + // 2 对商户key做md5,得到32位小写key + String md5Key = DigestUtils.md5Hex(wechatPay.getApiV2Key()).toLowerCase(); + // 3. AES-256-ECB 解密 + SecretKeySpec secretKey = new SecretKeySpec(md5Key.getBytes(StandardCharsets.UTF_8), "AES"); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, secretKey); + byte[] decryptedBytes = cipher.doFinal(encryptedBytes); + String json = new String(decryptedBytes, StandardCharsets.UTF_8); + WechantRefunCallbackVo entity = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(json)), WechantRefunCallbackVo.class); + log.debug("解密回调信息,json|{}", JSONUtil.toJsonStr(entity)); + return entity; + } catch (Exception e) { + e.printStackTrace(); + log.error("解密回调信息解密异常", e); + return null; + } + } + + /** + * 付款码支付 + */ + @Override + public WechatMicropayVo micropay(WechatMicropayDto dto) { + try { + Map params = new HashMap<>(); + // 公众账号ID + params.put("appid", wechatPay.getAppId()); + // 商户号 + params.put("mch_id", wechatPay.getMerchantId()); + // 设备号-终端设备号(商户自定义,如门店编号) + params.put("device_info", dto.getMerId()); + // 随机字符串 + params.put("nonce_str", getNonceStr()); + // 签名 + params.put("sign", ""); + // 签名类型 + params.put("sign_type", "MD5"); + // 商品描述 + params.put("body", "小铺故事超市-超市"); + // 商户单号 + params.put("out_trade_no", dto.getOrderId()); + // 订单金额(分) + params.put("total_fee", dto.getPrice()); + // 终端IP + params.put("spbill_create_ip", "220.191.229.131"); + // 付款码 + params.put("auth_code", dto.getWechatQrCode()); + // 生成签名 + params.put("sign", generateSign(params)); + WechantPayConstant.Api api = initApi(WechantPayConstant.APY); + String res = api.getHttpRequest().body(XmlUtil.mapToXmlStr(params)).execute().body(); + log.debug("付款码支付,json,xml|{}", res); + if (ObjectUtil.isEmpty(res)) { + log.error("付款码支付,res为空"); + return null; + } + WechatMicropayVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)), WechatMicropayVo.class); + log.debug("付款码支付,json,res|{}", JSONUtil.toJsonStr(vo)); + if (!vo.isHttpSucess()) { + return null; + } + return vo; + } catch (Exception e) { + log.error("付款码支付,异常", e); + return null; + } + } + + /** + * 查询订单 + */ + @Override + public WechatQueryVo query(WechatQueryDto dto) { + try { + Map params = new HashMap<>(); + // 公众账号ID + params.put("appid", wechatPay.getAppId()); + // 商户号 + params.put("mch_id", wechatPay.getMerchantId()); + // 微信订单号 + params.put("transaction_id", dto.getWechantOrderId()); + // 商户订单号 + params.put("out_trade_no", dto.getOrderId()); + // 随机字符串 + params.put("nonce_str", getNonceStr()); + // 签名 + params.put("sign", ""); + // 签名类型 + params.put("sign_type", "MD5"); + // 生成签名 + params.put("sign", generateSign(params)); + WechantPayConstant.Api api = initApi(WechantPayConstant.QUERY); + String res = api.getHttpRequest().body(XmlUtil.mapToXmlStr(params)).execute().body(); + log.debug("查询订单,json,xml|{}", res); + if (ObjectUtil.isEmpty(res)) { + log.error("查询订单,res为空"); + return null; + } + WechatQueryVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)), WechatQueryVo.class); + log.debug("查询订单,json,res|{}", JSONUtil.toJsonStr(vo)); + if (!vo.isHttpSucess()) { + return null; + } + return vo; + } catch (Exception e) { + log.error("查询订单,异常", e); + return null; + } + } + + /** + * 申请退款 + */ + @Override + public WechatRefundVo refund(WechatRefundDto dto) { + try { + Map params = new HashMap<>(); + // 公众账号ID + params.put("appid", wechatPay.getAppId()); + // 商户号 + params.put("mch_id", wechatPay.getMerchantId()); + // 随机字符串 + params.put("nonce_str", getNonceStr()); + // 签名 + params.put("sign", ""); + // 签名类型 + params.put("sign_type", "MD5"); + // 微信支付订单号 + params.put("transaction_id", dto.getWechantOrderId()); + // 商户订单号 + params.put("out_trade_no", dto.getOrderId()); + // 商户退款单号 + params.put("out_refund_no", dto.getRefundId()); + // 订单金额 + params.put("total_fee", dto.getOrderPrice()); + // 退款金额 + params.put("refund_fee", dto.getRefundPrice()); + // 退款结果通知url + params.put("notify_url", wechatPay.getRefundCallbackUrl()); + // 生成签名 + params.put("sign", generateSign(params)); + WechantPayConstant.Api api = initApi(WechantPayConstant.REFUND); + api.setSslSocketFactory(createSSLSocketFactory()); + String res = api.getHttpRequest().body(XmlUtil.mapToXmlStr(params)).execute().body(); + log.debug("申请退款,json,xml|{}", res); + if (ObjectUtil.isEmpty(res)) { + log.error("申请退款,res为空"); + return null; + } + WechatRefundVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)), WechatRefundVo.class); + log.debug("申请退款,json,res|{}", JSONUtil.toJsonStr(vo)); + if (!vo.isHttpSucess()) { + return null; + } + return vo; + } catch (Exception e) { + log.error("申请退款,异常", e); + return null; + } + } + + /** + * 查询退款 + */ + @Override + public WechatRefundQueryVo refundQuery(WechatRefundQueryDto dto) { + try { + Map params = new HashMap<>(); + // 公众账号ID + params.put("appid", wechatPay.getAppId()); + // 商户号 + params.put("mch_id", wechatPay.getMerchantId()); + // 随机字符串 + params.put("nonce_str", getNonceStr()); + // 签名 + params.put("sign", ""); + // 签名类型 + params.put("sign_type", "MD5"); + // 签名类型 + params.put("out_refund_no", dto.getRefundId()); + // 生成签名 + params.put("sign", generateSign(params)); + WechantPayConstant.Api api = initApi(WechantPayConstant.REFUND_QUERY); + String res = api.getHttpRequest().body(XmlUtil.mapToXmlStr(params)).execute().body(); + log.debug("查询退款,json,xml|{}", res); + if (ObjectUtil.isEmpty(res)) { + log.error("查询退款,res为空"); + return null; + } + WechatRefundQueryVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)), WechatRefundQueryVo.class); + log.debug("查询退款,json,res|{}", JSONUtil.toJsonStr(vo)); + if (!vo.isHttpSucess()) { + return null; + } + return vo; + } catch (Exception e) { + log.error("查询退款,异常", e); + return null; + } + } + + /** + * 退款回调 + */ + @Override + public String refundCallback(HttpEntity httpEntity, Map headers) { + String body = httpEntity.getBody(); + WechantRefunCallbackVo decrypt = decrypt(body); + if (ObjectUtil.isEmpty(decrypt)) { + // 告诉微信错误 + return WechantRefunCallbackVo.wechantError(); + } + + return WechantRefunCallbackVo.wechantError(); + } +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java new file mode 100644 index 000000000..7b44a4638 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java @@ -0,0 +1,63 @@ +package com.bsd.pjcloud.hard.utils.constant; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.http.HttpRequest; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpMethod; + +import javax.net.ssl.SSLSocketFactory; + +/** + * 微信支付api + */ +public class WechantPayConstant { + + public static final Api APY = Api.builder().summary("付款码支付").url("/pay/micropay").method(HttpMethod.POST).isNeedCertificate(false).build(); + + public static final Api QUERY = Api.builder().summary("查询订单").url("/pay/orderquery").method(HttpMethod.POST).isNeedCertificate(false).build(); + + public static final Api REVERSE = Api.builder().summary("撤销订单").url("/pay/reverse").method(HttpMethod.POST).isNeedCertificate(false).build(); + + public static final Api REFUND = Api.builder().summary("申请退款").url("/secapi/pay/refund").method(HttpMethod.POST).isNeedCertificate(true).build(); + + public static final Api REFUND_QUERY = Api.builder().summary("查询退款").url("/pay/refundquery").method(HttpMethod.POST).isNeedCertificate(false).build(); + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + static public class Api { + + private String summary; + + private String baseUrl; + + private String url; + + private String fullUrl; + + private HttpMethod method; + + private boolean isNeedCertificate = false; + + private SSLSocketFactory sslSocketFactory; + + public HttpRequest getHttpRequest() { + String fullUrl = baseUrl + url; + HttpRequest req = switch (method.name()) { + case "GET" -> HttpRequest.get(fullUrl); + case "POST" -> HttpRequest.post(fullUrl); + default -> null; + }; + if (ObjectUtil.isNotEmpty(req) && ObjectUtil.isNotEmpty(sslSocketFactory) && isNeedCertificate) { + req.setSSLSocketFactory(sslSocketFactory); + } + return req; + } + + } + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/application.yml b/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/application.yml index b0027050e..58e2aa349 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/application.yml +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/application.yml @@ -24,3 +24,11 @@ spring: # 第三方回调配置 # pay-callback: # lb-mch-id: 1919673632357584898 + +wechat-pay: + merchant-id: 1718803142 + api-v2-key: EDn3OfIZZFwyS9Obx73XgQ8NHt01piUa + app-id: wx4ec0210f4bf42f9f + base-url: https://api.mch.weixin.qq.com + refund-callback-url: https://rj4jv5rwqs.by.takin.cc/hard/hard-wechant-pay/callback/refund + merchant-serial-path: /Users/dengzhangchen/Desktop/backups/pay/cert/apiclient_cert.p12 diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml index 4355abcd2..ebc2867aa 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml @@ -131,6 +131,12 @@ com.bsd pjcloud-common-idempotent + + + com.github.wechatpay-apiv3 + wechatpay-java + 0.2.17 + com.bsd pjcloud-hardware-api diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java new file mode 100644 index 000000000..120b9125f --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java @@ -0,0 +1,40 @@ +package com.bsd.pjcloud.wallet.controller.wechant; + +import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.security.annotation.Inner; +import com.bsd.pjcloud.wallet.api.dto.WalletActiveDto; +import com.bsd.pjcloud.wallet.service.WechatPayService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/wallet-wechant-pay") +@Tag(description = "wallet-wechant", name = "微信相关") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +@Validated +public class WechantPayController { + + private final WechatPayService wechatPayService; + + /* ************************************* start callback start ************************************* */ + + @Inner(value = false) + @PostMapping("/callback/refund") + @Operation(summary = "微信退款回调") + public String refundCallback(HttpEntity httpEntity, @RequestHeader Map headers) { + return wechatPayService.refundCallback(httpEntity, headers); + } + + /* ************************************* end callback end ************************************* */ + +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/WechatPayTest.java b/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/WechatPayTest.java new file mode 100644 index 000000000..c655e14d9 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/WechatPayTest.java @@ -0,0 +1,68 @@ +package com.bsd.pjcloud.wallet; + +import cn.hutool.json.JSONUtil; +import com.bsd.pjcloud.thirdparty.dto.lb.LbH5LoginDto; +import com.bsd.pjcloud.thirdparty.vo.lb.LbH5LoginVo; +import com.bsd.pjcloud.wallet.api.dto.wechat.WechatMicropayDto; +import com.bsd.pjcloud.wallet.api.dto.wechat.WechatQueryDto; +import com.bsd.pjcloud.wallet.api.dto.wechat.WechatRefundDto; +import com.bsd.pjcloud.wallet.api.vo.wechat.WechatMicropayVo; +import com.bsd.pjcloud.wallet.api.vo.wechat.WechatQueryVo; +import com.bsd.pjcloud.wallet.api.vo.wechat.WechatRefundVo; +import com.bsd.pjcloud.wallet.service.WechatPayService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * 微信支付配置 + */ +@Slf4j +@SpringBootTest(classes = WalletApp.class) +public class WechatPayTest { + + @Resource + private WechatPayService wechatPayService; + + @Test + public void micropay() throws Exception { + long currentTimeMillis = System.currentTimeMillis(); + + WechatMicropayDto dto = new WechatMicropayDto(); + dto.setMerId(currentTimeMillis); + dto.setOrderId(currentTimeMillis); + dto.setPrice(1L); + dto.setWechatQrCode("132796932599913148"); + + WechatMicropayVo micropay = wechatPayService.micropay(dto); + if (micropay.isAllSuccess()) { + log.info("支付成功json:{}", JSONUtil.toJsonStr(micropay)); + } + } + + @Test + public void query() throws Exception { + WechatQueryDto dto = new WechatQueryDto(); + dto.setWechantOrderId("4200002719202506059568204561"); + + WechatQueryVo micropay = wechatPayService.query(dto); + } + + @Test + public void rerfund() throws Exception { + String currentOrderId = "4200002648202506062041165177"; + + WechatRefundDto dto = new WechatRefundDto(); + dto.setWechantOrderId(currentOrderId); + dto.setRefundId("refund_" + currentOrderId); + dto.setOrderPrice(1L); + dto.setRefundPrice(1L); + + WechatRefundVo micropay = wechatPayService.refund(dto); + if (micropay.isAllSuccess()) { + log.info("退款成功json:{}", JSONUtil.toJsonStr(micropay)); + } + } + +} From 84c10d7f4f3f6474d56555cfa37fa7b3b4f438e6 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Fri, 6 Jun 2025 15:43:31 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat:=E5=AE=8C=E6=88=90=E4=BB=98=E6=AC=BE?= =?UTF-8?q?=E7=A0=81=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/dto/wechat/WechantReverseDto.java | 21 ++++++++ .../api/dto/wechat/WechatMicropayDto.java | 8 +++- .../hard/api/dto/wechat/WechatRefundDto.java | 6 +++ .../hard/api/vo/wechat/WechantReverseVo.java | 44 +++++++++++++++++ .../hard/service/HardOrderService.java | 3 ++ .../hard/service/WechatPayService.java | 15 +++--- .../impl/order/HardOrderServiceImpl.java | 26 ++++++++-- .../impl/wechat/WechatPayServiceImpl.java | 48 +++++++++++++++++-- .../utils/constant/WechantPayConstant.java | 2 +- .../com/bsd/pjcloud/hard}/WechatPayTest.java | 23 +++++---- .../wechant/WechantPayController.java | 40 ---------------- 11 files changed, 167 insertions(+), 69 deletions(-) create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechantReverseDto.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantReverseVo.java rename {pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet => pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard}/WechatPayTest.java (71%) delete mode 100644 pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechantReverseDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechantReverseDto.java new file mode 100644 index 000000000..71e2ca977 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechantReverseDto.java @@ -0,0 +1,21 @@ +package com.bsd.pjcloud.hard.api.dto.wechat; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 撤销订单入参 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WechantReverseDto { + + private Long orderId; + + private String wechantOrderId; + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java index 79b1b40d4..cdcecd72b 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatMicropayDto.java @@ -1,8 +1,14 @@ package com.bsd.pjcloud.hard.api.dto.wechat; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class WechatMicropayDto { /** @@ -18,7 +24,7 @@ public class WechatMicropayDto { /** * 支付金额(分) */ - private Long price; + private Integer price; /** * 微信付款码code diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java index b3e67c85c..5fa3552c4 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java @@ -1,11 +1,17 @@ package com.bsd.pjcloud.hard.api.dto.wechat; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 退款入参 */ @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class WechatRefundDto { private String orderId; diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantReverseVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantReverseVo.java new file mode 100644 index 000000000..b9bd73a5c --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantReverseVo.java @@ -0,0 +1,44 @@ +package com.bsd.pjcloud.hard.api.vo.wechat; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; + +/** + * 撤销订单返回 + */ +@Data +public class WechantReverseVo { + public static final String SUCCESS = "SUCCESS"; + + private String return_code; + + private String return_msg; + + private String appid; + + private String mch_id; + + private String nonce_str; + + private String sign; + + private String result_code; + + private String err_code; + + private String err_code_des; + + private String recall; + + public boolean isHttpSucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, return_code); + } + + public boolean isPaySucess() { + return ObjectUtil.equals(WechatMicropayVo.SUCCESS, result_code); + } + + public boolean isAllSuccess() { + return isHttpSucess() && isPaySucess(); + } +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java index 0cc4b93f6..9e04e2013 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java @@ -35,6 +35,9 @@ public interface HardOrderService extends IService { HardOrderVo join(Long id); + /** + * 创建订单 + */ Long createOrder(HardCreateOrderDto dto); /** diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java index e939494e4..f2f85f0a6 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/WechatPayService.java @@ -1,14 +1,8 @@ package com.bsd.pjcloud.hard.service; -import com.bsd.pjcloud.hard.api.dto.wechat.WechatMicropayDto; -import com.bsd.pjcloud.hard.api.dto.wechat.WechatQueryDto; -import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundDto; -import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundQueryDto; -import com.bsd.pjcloud.hard.api.vo.wechat.WechatMicropayVo; -import com.bsd.pjcloud.hard.api.vo.wechat.WechatQueryVo; -import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundQueryVo; -import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundVo; +import com.bsd.pjcloud.hard.api.dto.wechat.*; +import com.bsd.pjcloud.hard.api.vo.wechat.*; import org.springframework.http.HttpEntity; import org.springframework.web.bind.annotation.RequestHeader; @@ -29,6 +23,11 @@ public interface WechatPayService { */ WechatQueryVo query(WechatQueryDto dto); + /** + * 撤销订单 + */ + WechantReverseVo reverse(WechantReverseDto dto); + /** * 申请退款 */ diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java index 5afcb52fa..29ee720d5 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java @@ -34,6 +34,9 @@ import com.bsd.pjcloud.hard.api.dto.order.HardCreateCarDto; import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto; import com.bsd.pjcloud.hard.api.dto.order.app.HardAppCreateOrderDto; import com.bsd.pjcloud.hard.api.dto.spu.DeductionSpuStockDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechantReverseDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatMicropayDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundDto; import com.bsd.pjcloud.hard.api.entity.HardApptEntity; import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity; import com.bsd.pjcloud.hard.api.entity.order.HardCarEntity; @@ -45,6 +48,9 @@ import com.bsd.pjcloud.hard.api.vo.HardDoorFlowVo; import com.bsd.pjcloud.hard.api.vo.manager.HardManagerVo; import com.bsd.pjcloud.hard.api.vo.order.HardCarVo; import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechantReverseVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatMicropayVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundVo; import com.bsd.pjcloud.hard.mapper.manager.HardManagerMapper; import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper; import com.bsd.pjcloud.hard.service.*; @@ -105,6 +111,7 @@ public class HardOrderServiceImpl extends ServiceImpl params = new HashMap<>(); + // 公众账号ID + params.put("appid", wechatPay.getAppId()); + // 商户号 + params.put("mch_id", wechatPay.getMerchantId()); + // 微信订单号 + params.put("transaction_id", dto.getWechantOrderId()); + // 商户订单号 + params.put("out_trade_no", dto.getOrderId()); + // 随机字符串 + params.put("nonce_str", getNonceStr()); + // 签名 + params.put("sign", ""); + // 签名类型 + params.put("sign_type", "MD5"); + // 生成签名 + params.put("sign", generateSign(params)); + WechantPayConstant.Api api = initApi(WechantPayConstant.REVERSE); + api.setSslSocketFactory(createSSLSocketFactory()); + String res = api.getHttpRequest().body(XmlUtil.mapToXmlStr(params)).execute().body(); + log.debug("撤销订单,json,xml|{}", res); + if (ObjectUtil.isEmpty(res)) { + log.error("撤销订单,res为空"); + return null; + } + WechantReverseVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)), WechantReverseVo.class); + log.debug("撤销订单,json,res|{}", JSONUtil.toJsonStr(vo)); + if (!vo.isHttpSucess()) { + return null; + } + return vo; + } catch (Exception e) { + log.error("撤销订单,异常", e); + return null; + } + } + /** * 申请退款 */ diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java index 7b44a4638..551b87bca 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/utils/constant/WechantPayConstant.java @@ -19,7 +19,7 @@ public class WechantPayConstant { public static final Api QUERY = Api.builder().summary("查询订单").url("/pay/orderquery").method(HttpMethod.POST).isNeedCertificate(false).build(); - public static final Api REVERSE = Api.builder().summary("撤销订单").url("/pay/reverse").method(HttpMethod.POST).isNeedCertificate(false).build(); + public static final Api REVERSE = Api.builder().summary("撤销订单").url("/secapi/pay/reverse").method(HttpMethod.POST).isNeedCertificate(true).build(); public static final Api REFUND = Api.builder().summary("申请退款").url("/secapi/pay/refund").method(HttpMethod.POST).isNeedCertificate(true).build(); diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/WechatPayTest.java b/pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard/WechatPayTest.java similarity index 71% rename from pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/WechatPayTest.java rename to pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard/WechatPayTest.java index c655e14d9..a47d09da5 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/WechatPayTest.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard/WechatPayTest.java @@ -1,15 +1,14 @@ -package com.bsd.pjcloud.wallet; +package hard.com.bsd.pjcloud.hard; import cn.hutool.json.JSONUtil; -import com.bsd.pjcloud.thirdparty.dto.lb.LbH5LoginDto; -import com.bsd.pjcloud.thirdparty.vo.lb.LbH5LoginVo; -import com.bsd.pjcloud.wallet.api.dto.wechat.WechatMicropayDto; -import com.bsd.pjcloud.wallet.api.dto.wechat.WechatQueryDto; -import com.bsd.pjcloud.wallet.api.dto.wechat.WechatRefundDto; -import com.bsd.pjcloud.wallet.api.vo.wechat.WechatMicropayVo; -import com.bsd.pjcloud.wallet.api.vo.wechat.WechatQueryVo; -import com.bsd.pjcloud.wallet.api.vo.wechat.WechatRefundVo; -import com.bsd.pjcloud.wallet.service.WechatPayService; +import com.bsd.pjcloud.hard.HardApp; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatMicropayDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatQueryDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundDto; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatMicropayVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatQueryVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundVo; +import com.bsd.pjcloud.hard.service.WechatPayService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -19,7 +18,7 @@ import org.springframework.boot.test.context.SpringBootTest; * 微信支付配置 */ @Slf4j -@SpringBootTest(classes = WalletApp.class) +@SpringBootTest(classes = HardApp.class) public class WechatPayTest { @Resource @@ -32,7 +31,7 @@ public class WechatPayTest { WechatMicropayDto dto = new WechatMicropayDto(); dto.setMerId(currentTimeMillis); dto.setOrderId(currentTimeMillis); - dto.setPrice(1L); + dto.setPrice(1); dto.setWechatQrCode("132796932599913148"); WechatMicropayVo micropay = wechatPayService.micropay(dto); diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java deleted file mode 100644 index 120b9125f..000000000 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/wechant/WechantPayController.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.bsd.pjcloud.wallet.controller.wechant; - -import com.bsd.pjcloud.common.core.util.R; -import com.bsd.pjcloud.common.security.annotation.Inner; -import com.bsd.pjcloud.wallet.api.dto.WalletActiveDto; -import com.bsd.pjcloud.wallet.service.WechatPayService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.security.SecurityRequirement; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springdoc.core.annotations.ParameterObject; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.Map; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/wallet-wechant-pay") -@Tag(description = "wallet-wechant", name = "微信相关") -@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) -@Validated -public class WechantPayController { - - private final WechatPayService wechatPayService; - - /* ************************************* start callback start ************************************* */ - - @Inner(value = false) - @PostMapping("/callback/refund") - @Operation(summary = "微信退款回调") - public String refundCallback(HttpEntity httpEntity, @RequestHeader Map headers) { - return wechatPayService.refundCallback(httpEntity, headers); - } - - /* ************************************* end callback end ************************************* */ - -} From c477dbf361fc9bd336017fcf8123be24704c9c40 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Fri, 6 Jun 2025 16:49:47 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=E5=BE=AE=E4=BF=A1=E4=BB=98=E6=AC=BE?= =?UTF-8?q?=E7=A0=81=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hard/api/dto/wechat/WechatRefundDto.java | 8 +- .../api/vo/wechat/WechantRefunCallbackVo.java | 6 +- .../hard/service/HardAfterSaleService.java | 6 ++ .../hard/service/HardOrderService.java | 7 ++ .../impl/order/HardAfterSaleServiceImpl.java | 98 +++++++++++++++---- .../impl/order/HardOrderServiceImpl.java | 36 +++---- .../impl/wechat/WechatPayServiceImpl.java | 9 +- 7 files changed, 127 insertions(+), 43 deletions(-) diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java index 5fa3552c4..837bc8152 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/wechat/WechatRefundDto.java @@ -14,14 +14,14 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class WechatRefundDto { - private String orderId; + private Long orderId; private String wechantOrderId; - private String refundId; + private Long refundId; - private Long orderPrice; + private Integer orderPrice; - private Long refundPrice; + private Integer refundPrice; } diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java index bd00563b5..cf289e298 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/wechat/WechantRefunCallbackVo.java @@ -63,14 +63,14 @@ public class WechantRefunCallbackVo { public static String wechantError() { return "" + "" + - "" + + "" + ""; } public static String wechantSuccess() { return "" + - "" + - "" + + " " + + " \n" + ""; } diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java index d6cd18b1b..19b9fc66f 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java @@ -10,6 +10,7 @@ import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity; import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleLogEntity; import com.bsd.pjcloud.hard.api.vo.order.HardAfterSaleVo; import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechantRefunCallbackVo; import java.util.List; @@ -43,6 +44,11 @@ public interface HardAfterSaleService extends IService { void refund(Long afterSaleId, String prefixStr); + /** + * 微信退款回调通知 + */ + boolean wechatRefundCallback(WechantRefunCallbackVo decrypt); + /** * 同意售后 */ diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java index 9e04e2013..ba614d93b 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardOrderService.java @@ -7,6 +7,8 @@ import com.bsd.pjcloud.admin.api.entity.SysUser; import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum; import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.security.service.PjcloudUser; +import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum; +import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum; import com.bsd.pjcloud.hard.api.dto.hard.HandCancelCodeDto; import com.bsd.pjcloud.hard.api.dto.hard.HardCreateOrderDto; import com.bsd.pjcloud.hard.api.dto.order.HardCreateCarDto; @@ -106,4 +108,9 @@ public interface HardOrderService extends IService { * 创建订单后发送mq消息 */ void createOrderAfterSendMqMsg(Long orderId, UserInfo userInfo); + + /** + * 是否需要支付 + */ + boolean isPay(HardOrderTypeEnum type, HardPayTypeEnum payType); } \ No newline at end of file diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java index 9d684f1e2..c1bebfa72 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java @@ -21,6 +21,7 @@ import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.security.service.PjcloudUser; import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum; import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum; +import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum; import com.bsd.pjcloud.hard.api.constant.refund.HardAfterSaleOperateTypeEnum; import com.bsd.pjcloud.hard.api.constant.refund.HardRefundStatusEnum; import com.bsd.pjcloud.hard.api.constant.refund.HardSaleStatusEnum; @@ -29,17 +30,21 @@ import com.bsd.pjcloud.hard.api.dto.order.HardAdminRefundDto; import com.bsd.pjcloud.hard.api.dto.order.HardAfterSaleDto; import com.bsd.pjcloud.hard.api.dto.order.HardDisagreeDto; import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto; +import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundDto; import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity; import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleLogEntity; import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity; import com.bsd.pjcloud.hard.api.utils.HardUtil; import com.bsd.pjcloud.hard.api.vo.order.HardAfterSaleVo; import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechantRefunCallbackVo; +import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundVo; import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleLogMapper; import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleMapper; import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper; import com.bsd.pjcloud.hard.service.HardAfterSaleService; import com.bsd.pjcloud.hard.service.HardOrderService; +import com.bsd.pjcloud.hard.service.WechatPayService; import com.bsd.pjcloud.thirdparty.constant.pay.ThirdPayVoStatusEnum; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto; import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargeService; @@ -57,9 +62,6 @@ import java.util.Map; /** * 售后订单 - * - * @author dzc - * @date 2025-01-07 17:23:08 */ @Validated @Slf4j @@ -71,6 +73,7 @@ public class HardAfterSaleServiceImpl extends ServiceImpl walletRefundResult = walletRechargeService.refund(hardRefundDto); - if (walletRefundResult.getCode() != 0 || ObjectUtil.isEmpty(walletRefundResult.getData())) { - throw new RuntimeException("钱包退款错误"); + HardOrderTypeEnum hardOrderType = HardOrderTypeEnum.valueOfByType(order.getOrderType()); + HardPayTypeEnum hardPayType = HardPayTypeEnum.valueOfByType(order.getPayType()); + // 是否钱包支付 + boolean isWalletPay = hardOrderService.isPay(hardOrderType, hardPayType); + // 是否微信支付 + boolean isWeChatPay = ObjectUtil.equals(order.getPayType(), HardPayTypeEnum.WECHANT_SELF_QR_CODE_PAY.getType()); + // 是否支付宝支付 + boolean isAliPay = ObjectUtil.equals(order.getPayType(), HardPayTypeEnum.ALI_SELF_QR_CODE_PAY.getType()); + if (isWalletPay) { + WalletRechargeRefundDto hardRefundDto = WalletRechargeRefundDto.builder().walletId(order.getWalletId()).orderId(order.getId()).afterSaleId(afterSale.getId()).refundCode(refundCode).reason("订单退款").price(refundPrice).build(); + R walletRefundResult = walletRechargeService.refund(hardRefundDto); + if (walletRefundResult.getCode() != 0 || ObjectUtil.isEmpty(walletRefundResult.getData())) { + throw new RuntimeException("钱包退款错误"); + } + WalletRechargeVo walletRefund = walletRefundResult.getData(); + HardOrderEntity updateObj = HardOrderEntity.builder() + .id(order.getId()) + .orderStatus(HardOrderStatusEnum.REFUND.getType()) + .refundStatus(HardRefundStatusEnum.SUCCESS.getStatus()) + .payRefundId(walletRefund.getId()) + .refundPrice(refundTotalPrice + refundPrice) + .refundTime(LocalDateTime.now()) + .build(); + hardOrderService.updateById(updateObj); + } else if (isWeChatPay) { + WechatRefundDto refundDto = WechatRefundDto.builder().orderId(order.getId()).refundId(afterSale.getId()).orderPrice(refundPrice).refundPrice(refundPrice).build(); + WechatRefundVo refundVo = wechatPayService.refund(refundDto); + if (ObjectUtil.isEmpty(refundVo)) { + throw new RuntimeException("微信退款错误"); + } + if (!refundVo.isAllSuccess()) { + throw new RuntimeException(refundVo.getErr_code_des()); + } + } else if (isAliPay) { + throw new RuntimeException("支付宝退款暂不支持"); + } + } + + /** + * 微信退款回调通知 + */ + @Override + public boolean wechatRefundCallback(WechantRefunCallbackVo decrypt) { + try { + Long orderId = Long.valueOf(decrypt.getOut_trade_no()); + Long refunId = Long.valueOf(decrypt.getOut_refund_no()); + // 查询订单 + HardOrderEntity order = hardOrderService.getById(orderId); + if (ObjectUtil.isEmpty(order)) { + log.error("微信退款回调通知,订单不存在orderId:{}", orderId); + return false; + } + // 查询售后单 + HardAfterSaleEntity afterSale = baseMapper.selectById(refunId); + if (ObjectUtil.isEmpty(afterSale)) { + log.error("微信退款回调通知,售后单不存在refunId:{}", refunId); + return false; + } + if (ObjectUtil.equals(afterSale.getStatus(), HardSaleStatusEnum.COMPLETE.getStatus())) { + log.error("微信退款回调通知,售后单已处理完成refunId:{}", refunId); + return false; + } + HardOrderEntity updateObj = HardOrderEntity.builder() + .id(order.getId()) + .orderStatus(HardOrderStatusEnum.REFUND.getType()) + .refundStatus(HardRefundStatusEnum.SUCCESS.getStatus()) + .payRefundId(orderId) + .refundPrice(Integer.valueOf(decrypt.getRefund_fee())) + .refundTime(LocalDateTime.now()) + .build(); + hardOrderService.updateById(updateObj); + return true; + } catch (Exception e) { + log.error("微信退款回调通知失败", e); + return false; } - WalletRechargeVo walletRefund = walletRefundResult.getData(); - HardOrderEntity updateObj = HardOrderEntity.builder() - .id(order.getId()) - .orderStatus(HardOrderStatusEnum.REFUND.getType()) - .refundStatus(HardRefundStatusEnum.SUCCESS.getStatus()) - .payRefundId(walletRefund.getId()) - .refundPrice(refundTotalPrice + refundPrice) - .refundTime(LocalDateTime.now()) - .build(); - hardOrderService.updateById(updateObj); } @Override diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java index 29ee720d5..a6f1cba06 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java @@ -301,7 +301,6 @@ public class HardOrderServiceImpl extends ServiceImpl Date: Fri, 6 Jun 2025 20:06:07 +0800 Subject: [PATCH 5/6] 11 --- .../com/bsd/pjcloud/hard/controller/HardApptController.java | 1 - .../bsd/pjcloud/hard/controller/HardBroadcastController.java | 2 -- .../hard/service/impl/order/HardAfterSaleServiceImpl.java | 1 - 3 files changed, 4 deletions(-) diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardApptController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardApptController.java index 20b43bbc2..68b73b41a 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardApptController.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardApptController.java @@ -22,7 +22,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Objects; /** * 设备预约管理 diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardBroadcastController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardBroadcastController.java index 990dc108b..e1f54df10 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardBroadcastController.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/HardBroadcastController.java @@ -2,7 +2,6 @@ package com.bsd.pjcloud.hard.controller; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.collection.CollUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum; @@ -26,7 +25,6 @@ import org.springframework.web.bind.annotation.*; import java.time.LocalDate; import java.util.List; -import java.util.Objects; /** * 设备广播 diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java index c1bebfa72..73611f8c3 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java @@ -45,7 +45,6 @@ import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper; import com.bsd.pjcloud.hard.service.HardAfterSaleService; import com.bsd.pjcloud.hard.service.HardOrderService; import com.bsd.pjcloud.hard.service.WechatPayService; -import com.bsd.pjcloud.thirdparty.constant.pay.ThirdPayVoStatusEnum; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto; import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargeService; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo; From 4ed7fe3136d048c086b616d038b0856f64f5939d Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Fri, 6 Jun 2025 21:39:53 +0800 Subject: [PATCH 6/6] 11 --- .../java/hard/com/bsd/pjcloud/hard/WechatPayTest.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard/WechatPayTest.java b/pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard/WechatPayTest.java index a47d09da5..bb5bfe763 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard/WechatPayTest.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/test/java/hard/com/bsd/pjcloud/hard/WechatPayTest.java @@ -51,17 +51,6 @@ public class WechatPayTest { @Test public void rerfund() throws Exception { String currentOrderId = "4200002648202506062041165177"; - - WechatRefundDto dto = new WechatRefundDto(); - dto.setWechantOrderId(currentOrderId); - dto.setRefundId("refund_" + currentOrderId); - dto.setOrderPrice(1L); - dto.setRefundPrice(1L); - - WechatRefundVo micropay = wechatPayService.refund(dto); - if (micropay.isAllSuccess()) { - log.info("退款成功json:{}", JSONUtil.toJsonStr(micropay)); - } } }