pom.xml
@@ -330,6 +330,12 @@ <artifactId>poi-ooxml-schemas</artifactId> <version>3.8</version> </dependency> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-pay</artifactId> <version>4.4.0</version> </dependency> </dependencies> <build> src/main/java/cc/mrbird/febs/FebsShiroApplication.java
@@ -4,6 +4,7 @@ import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.annotation.EnableTransactionManagement; src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
@@ -18,6 +18,7 @@ import cc.mrbird.febs.pay.model.AgreementPayDto; import cc.mrbird.febs.pay.model.AgreementSignDto; import cc.mrbird.febs.pay.model.UnipayDto; import cc.mrbird.febs.pay.service.IAliPayService; import cc.mrbird.febs.pay.service.IPayService; import cc.mrbird.febs.pay.service.UnipayService; import cc.mrbird.febs.rabbit.producter.AgentProducer; @@ -68,9 +69,10 @@ private final RedisUtils redisUtils; private final AgentProducer agentProducer; private final IPayService payService; private final IAliPayService payService; private final IMallAchieveService mallAchieveService; private final UnipayService unipayService; private final IPayService wechatPayService; private final MallMemberBankSignMapper mallMemberBankSignMapper; private final MallMemberBankMapper mallMemberBankMapper; @@ -277,30 +279,15 @@ String rcResult = ""; switch (payOrderDto.getType()) { case "1": UnipayDto unipayDtoWx = new UnipayDto(); // unipayDto.setAmount(new BigDecimal("0.01")); unipayDtoWx.setAmount(orderInfo.getAmount()); unipayDtoWx.setFrpCode("WEIXIN_APP3"); unipayDtoWx.setTradeMerchantNo("777180800385820"); unipayDtoWx.setOrderNo(orderInfo.getOrderNo()); List<MallOrderItem> itemsWx = orderInfo.getItems(); if(CollUtil.isEmpty(itemsWx)){ unipayDtoWx.setProductName("商品"); orderInfo.setName("商品"); }else{ unipayDtoWx.setProductName(itemsWx.get(0).getGoodsName()); orderInfo.setName(itemsWx.get(0).getGoodsName()); } String unipayStrWx = unipayService.unipay(unipayDtoWx); if("fail" == unipayStrWx){ throw new FebsException("支付失败"); }else{ // JSONUtil.parseObj(unipayStr); JSONObject jsonObject = JSONUtil.parseObj(unipayStrWx); payResultStr = (String) jsonObject.get("r7_TrxNo"); rcResult = (String) jsonObject.get("rc_Result"); } payResultStr = wechatPayService.pay(orderInfo); orderInfo.setPayOrderNo(payResultStr); // orderInfo.setPayOrderNo(payOrderDto.getPayOrderNo()); // orderInfo.setPayImage(payOrderDto.getPayImage()); orderInfo.setPayMethod("微信支付"); break; case "2": src/main/java/cc/mrbird/febs/pay/configure/WxPayConfiguration.java
New file @@ -0,0 +1,42 @@ package cc.mrbird.febs.pay.configure; import cc.mrbird.febs.pay.properties.WxPayProperties; import cn.hutool.core.util.StrUtil; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import lombok.AllArgsConstructor; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author wzy * @date 2023-04-07 **/ @Configuration @ConditionalOnClass(WxPayService.class) @EnableConfigurationProperties(WxPayProperties.class) @AllArgsConstructor public class WxPayConfiguration { private WxPayProperties properties; @Bean @ConditionalOnMissingBean public WxPayService wxService() { WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(StrUtil.trim(this.properties.getAppId())); payConfig.setMchId(StrUtil.trim(this.properties.getMchId())); payConfig.setMchKey(StrUtil.trim(this.properties.getMchKey())); payConfig.setKeyPath(StrUtil.trim(this.properties.getKeyPath())); // 可以指定是否使用沙箱环境 payConfig.setUseSandboxEnv(false); WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; } } src/main/java/cc/mrbird/febs/pay/controller/PayCallBackController.java
@@ -2,17 +2,20 @@ import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.pay.properties.AliPayProperties; import cc.mrbird.febs.pay.service.IAliPayService; import cc.mrbird.febs.pay.service.IPayService; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.internal.util.AlipaySignature; import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.ijpay.alipay.AliPayApi; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.service.WxService; import org.springframework.beans.factory.annotation.Autowired; 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.RestController; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -28,10 +31,16 @@ public class PayCallBackController { @Autowired private IPayService payService; private IAliPayService payService; @Autowired private IPayService wechatPayService; @Resource private AliPayProperties aliPayProperties; @Autowired private WxPayService wxPayService; @RequestMapping("/aliCallBack") public String aliPayCallBack(HttpServletRequest request){ @@ -59,4 +68,13 @@ return "failure"; } } @PostMapping(value = "/wxPayCallBack") public String wxPayCallBack(@RequestBody String xmlData) throws WxPayException { log.info("=======微信回调:{}========", xmlData); WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData); wechatPayService.payCallback(notifyResult.toMap()); return WxPayNotifyResponse.success("成功"); } } src/main/java/cc/mrbird/febs/pay/properties/WxPayProperties.java
New file @@ -0,0 +1,32 @@ package cc.mrbird.febs.pay.properties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; /** * @author wzy * @date 2023-04-07 **/ @Data @ConfigurationProperties(prefix = "pay.wx") public class WxPayProperties { /** * 设置微信公众号或者小程序等的appid */ private String appId; /** * 微信支付商户号 */ private String mchId; /** * 微信支付商户密钥 */ private String mchKey; private String keyPath; private String noticeUrl; } src/main/java/cc/mrbird/febs/pay/service/IAliPayService.java
New file @@ -0,0 +1,16 @@ package cc.mrbird.febs.pay.service; import cc.mrbird.febs.mall.entity.MallOrderInfo; import java.util.Map; /** * @author wzy * @date 2021-09-27 **/ public interface IAliPayService { String aliPay(MallOrderInfo orderInfo); void aliCallback(Map<String, String> params); } src/main/java/cc/mrbird/febs/pay/service/IPayService.java
@@ -4,13 +4,9 @@ import java.util.Map; /** * @author wzy * @date 2021-09-27 **/ public interface IPayService { String aliPay(MallOrderInfo orderInfo); String pay(MallOrderInfo orderInfo); void aliCallback(Map<String, String> params); void payCallback(Map<String, String> params); } src/main/java/cc/mrbird/febs/pay/service/impl/AliPayServiceImpl.java
File was renamed from src/main/java/cc/mrbird/febs/pay/service/impl/PayServiceImpl.java @@ -12,7 +12,8 @@ import cc.mrbird.febs.mall.service.IApiMallOrderInfoService; import cc.mrbird.febs.pay.model.AliPayPassbackModel; import cc.mrbird.febs.pay.properties.AliPayProperties; import cc.mrbird.febs.pay.service.IPayService; import cc.mrbird.febs.pay.service.IAliPayService; import cc.mrbird.febs.pay.service.IAliPayService; import cc.mrbird.febs.rabbit.producter.AgentProducer; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; @@ -36,7 +37,7 @@ **/ @Slf4j @Service public class PayServiceImpl implements IPayService { public class AliPayServiceImpl implements IAliPayService { @Resource private AliPayProperties aliPayProperties; src/main/java/cc/mrbird/febs/pay/service/impl/WxPayServiceImpl.java
New file @@ -0,0 +1,100 @@ package cc.mrbird.febs.pay.service.impl; import cc.mrbird.febs.common.enumerates.AgentLevelEnum; import cc.mrbird.febs.common.enumerates.OrderStatusEnum; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.mall.entity.MallMember; import cc.mrbird.febs.mall.entity.MallOrderInfo; import cc.mrbird.febs.mall.mapper.MallOrderInfoMapper; import cc.mrbird.febs.mall.service.IApiMallMemberService; import cc.mrbird.febs.pay.properties.WxPayProperties; import cc.mrbird.febs.pay.service.IPayService; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.Date; import java.util.Map; /** * @author wzy * @date 2023-04-07 **/ @Slf4j @Service("wechatPayService") @RequiredArgsConstructor public class WxPayServiceImpl implements IPayService { @Autowired private IApiMallMemberService memberService; @Autowired private MallOrderInfoMapper orderInfoMapper; @Autowired private WxPayService wxPayService; @Autowired private WxPayProperties wxPayProperties; @Value("${spring.profiles.active}") private String active; @Override public String pay(MallOrderInfo orderInfo) { WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); request.setAppid(wxPayProperties.getAppId()); request.setMchId(wxPayProperties.getMchId()); request.setNotifyUrl(wxPayProperties.getNoticeUrl()); request.setBody(orderInfo.getName()); request.setOutTradeNo(orderInfo.getOrderNo()); request.setTimeExpire(DateUtil.format(DateUtil.offset(new Date(), DateField.MINUTE, 15), DatePattern.PURE_DATETIME_PATTERN)); request.setSpbillCreateIp("127.0.0.1"); request.setTradeType("APP"); if ("dev".equals(active) || "test".equals(active)) { request.setTotalFee(1); } else { request.setTotalFee(orderInfo.getAmount().multiply(new BigDecimal(100)).intValue()); } try { WxPayAppOrderResult result = wxPayService.createOrder(request); return JSONObject.toJSONString(result); } catch (WxPayException e) { e.printStackTrace(); throw new FebsException("支付异常, 请检查"); } } @Override public void payCallback(Map<String, String> params) { String orderNo = params.get("outTradeNo"); LambdaQueryWrapper<MallOrderInfo> query = new LambdaQueryWrapper<>(); query.eq(MallOrderInfo::getOrderNo, orderNo); MallOrderInfo orderInfo = this.orderInfoMapper.selectOne(query); if ("1".equals(orderInfo.getPayResult())) { return; } orderInfo.setStatus(OrderStatusEnum.WAIT_SHIPPING.getValue()); orderInfo.setPayResult("1"); orderInfo.setPayTime(new Date()); orderInfo.setPayTradeNo(params.get("transaction_id")); orderInfoMapper.updateById(orderInfo); } } src/main/resources/application-dev.yml
@@ -15,24 +15,20 @@ datasource: # 数据源-1,名称为 base base: username: db_mall_hongloumeng password: hongloumeng123!@#123 username: ct_test password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://47.111.90.145:3306/db_mall_hongloumeng?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true&allowMultiQueries=true # username: db_mall # password: mall!@#123 # driver-class-name: com.mysql.cj.jdbc.Driver # url: jdbc:mysql://47.111.90.145:3306/db_mall?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8 url: jdbc:mysql://120.27.238.55:3406/db_hongloumeng?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8 redis: # Redis数据库索引(默认为 0) database: 8 database: 3 # Redis服务器地址 host: 121.37.162.173 host: 120.27.238.55 # Redis服务器连接端口 port: 6379 port: 6479 # Redis 密码 password: d32ncxe@i3#!dV password: d3y6dsdl;f.327 lettuce: pool: # 连接池中的最小空闲连接 @@ -46,10 +42,10 @@ # 连接超时时间(毫秒) timeout: 5000 rabbitmq: host: 47.111.90.145 host: 120.27.238.55 port: 5672 username: zj_mall password: zj_mall123 username: ct_rabbit password: 123456 publisher-confirm-type: correlated pay: @@ -62,3 +58,9 @@ # 回调地址 noticeUrl: http://120.27.238.55:8801/api/pay/aliCallBack domain: https://openapi.alipaydev.com/gateway.do wx: appId: wx051693799db39540 mchId: 1641389321 mchKey: wqri51aCfiG31o4IcdX3dW12qnX3u4hp keyPath: classpath:cert/apiclient_cert.p12 noticeUrl: http://120.27.238.55:8185/api/pay/wxPayCallBack src/main/resources/application-prod.yml
@@ -58,3 +58,9 @@ # 回调地址 noticeUrl: http://120.27.238.55:8801/api/pay/aliCallBack domain: https://openapi.alipay.com/gateway.do wx: appId: wx051693799db39540 mchId: 1641389321 mchKey: wqri51aCfiG31o4IcdX3dW12qnX3u4hp keyPath: classpath:cert/apiclient_cert.p12 noticeUrl: http://localhost src/main/resources/application-test.yml
@@ -18,7 +18,7 @@ username: ct_test password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://120.27.238.55:3306/db_amz?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8 url: jdbc:mysql://120.27.238.55:3406/db_hongloumeng?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8 redis: # Redis数据库索引(默认为 0) @@ -26,9 +26,9 @@ # Redis服务器地址 host: 120.27.238.55 # Redis服务器连接端口 port: 6379 port: 6479 # Redis 密码 password: xcong123 password: d3y6dsdl;f.327 lettuce: pool: # 连接池中的最小空闲连接 @@ -42,7 +42,7 @@ # 连接超时时间(毫秒) timeout: 5000 rabbitmq: host: 120.27.238.55 host: 127.0.0.1 port: 5672 username: ct_rabbit password: 123456 @@ -58,3 +58,9 @@ # 回调地址 noticeUrl: http://120.27.238.55:8801/api/pay/aliCallBack domain: https://openapi.alipaydev.com/gateway.do wx: appId: wx051693799db39540 mchId: 1641389321 mchKey: wqri51aCfiG31o4IcdX3dW12qnX3u4hp keyPath: classpath:cert/apiclient_cert.p12 noticeUrl: http://120.27.238.55:8185/api/pay/wxPayCallBack src/main/resources/application.yml
src/main/resources/cert/apiclient_cert.p12Binary files differ
src/test/java/cc/mrbird/febs/PayTest.java
@@ -1,12 +1,22 @@ package cc.mrbird.febs; import cc.mrbird.febs.pay.properties.WxPayProperties; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.UUID; import cn.hutool.core.util.RandomUtil; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.domain.AlipayTradeAppPayModel; import com.alipay.api.response.AlipayTradeAppPayResponse; import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.ijpay.alipay.AliPayApi; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; /** @@ -30,4 +40,30 @@ AlipayTradeAppPayResponse resp = AliPayApi.appPayToResponse(model, ""); log.info("=====>>>{}", JSONObject.toJSONString(resp)); } @Autowired private WxPayService wxPayService; @Autowired private WxPayProperties wxPayProperties; @Test public void wxPayTest() { WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); request.setAppid(wxPayProperties.getAppId()); request.setMchId(wxPayProperties.getMchId()); request.setNotifyUrl(wxPayProperties.getNoticeUrl()); request.setBody("这是body"); request.setOutTradeNo(RandomUtil.randomString(32)); request.setTimeExpire("20230407114500"); request.setSpbillCreateIp("127.0.0.1"); request.setTradeType("APP"); request.setTotalFee(1); try { WxPayAppOrderResult result = wxPayService.createOrder(request); System.out.println(1111); } catch (WxPayException e) { e.printStackTrace(); } } }