ruoyi-modules/ruoyi-order/pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/miniapp/NotifyController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/dto/WXPayNotifyDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/dto/WXPayNotifyResourceDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ruoyi-modules/ruoyi-order/pom.xml
@@ -114,6 +114,12 @@ <version>0.4.9</version> </dependency> <dependency> <groupId>com.github.wechatpay-apiv3</groupId> <artifactId>wechatpay-java</artifactId> <version>0.2.10</version> </dependency> <!-- 爬虫工具,抓取和解析html https://mvnrepository.com/artifact/org.jsoup/jsoup --> <dependency> <groupId>org.jsoup</groupId> ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/miniapp/NotifyController.java
New file @@ -0,0 +1,132 @@ package com.ruoyi.order.controller.miniapp; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.order.domain.dto.AppSureOrderDto; import com.ruoyi.order.domain.dto.WXPayNotifyDto; import com.ruoyi.order.domain.vo.AppSureOrderVo; import com.ruoyi.order.service.order.OrderService; import com.wechat.pay.contrib.apache.httpclient.notification.Notification; import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler; import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.core.RSAConfig; import com.wechat.pay.java.core.cipher.PrivacyEncryptor; import com.wechat.pay.java.core.notification.NotificationConfig; import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.core.notification.RequestParam; import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import net.bytebuddy.asm.Advice; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; /** * @program: ruoyi * @author: linqingsong * @create: 2023-07-22 17:20 * @description: 成都软思同创科技有限公司 **/ @Api(value = "微信通知控制", tags = "微信通知控制", description = "微信通知控制") @RestController @RequestMapping("/app/notify") public class NotifyController extends BaseController { /** 商户号 */ public static String merchantId = ""; /** 商户API私钥路径 */ public static String privateKeyPath = ""; /** 商户证书序列号 */ public static String merchantSerialNumber = ""; /** 微信支付平台证书路径 */ public static String wechatPayCertificatePath = ""; /** 商户APIV3密钥 */ public static String apiV3key = "..."; @Resource private OrderService orderService; @RequestMapping(value = "/payNotify", method = RequestMethod.POST) @ApiOperation(value = "微信支付通知") public Map payNotify(HttpServletRequest request, HttpServletResponse response) { Config config = new RSAConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .wechatPayCertificatesFromPath(wechatPayCertificatePath) .build(); PrivacyEncryptor encryptor = config.createEncryptor(); String wechatPayCertificateSerialNumber = encryptor.getWechatpaySerial(); String nonoc=request.getHeader("Wechatpay-Nonce"); String signature=request.getHeader("Wechatpay-Signature"); String timestamp=request.getHeader("Wechatpay-Timestamp"); String serial=request.getHeader("Wechatpay-Serial"); String signatureType=request.getHeader("Wechatpay-Signature-Type"); String requestBody=""; try { BufferedReader reader = request.getReader(); String line = ""; StringBuffer inputString = new StringBuffer(); while ( (line = reader.readLine()) != null ) { inputString.append(line); } if(inputString!=null && !"".equals(inputString)) { requestBody = inputString.toString(); } reader.close(); } catch (IOException e) { e.printStackTrace(); } RequestParam requestParam = new RequestParam.Builder() .serialNumber(wechatPayCertificateSerialNumber) .nonce(nonoc) .signature(signature) .timestamp(timestamp) .body(requestBody) .build(); NotificationConfig notifiConfig = new RSAAutoCertificateConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .apiV3Key(apiV3key) .build(); NotificationParser parser = new NotificationParser(notifiConfig); Transaction transaction = parser.parse(requestParam, Transaction.class); String tradeStateEnum=transaction.getTradeState().toString(); if(tradeStateEnum.equals("success")){ String outTradeNo=transaction.getOutTradeNo(); orderService.payBack(outTradeNo); } Map map=new HashMap(); map.put("code","SUCCESS"); map.put("message","成功"); return map; } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/dto/WXPayNotifyDto.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.order.domain.dto; import lombok.Data; /** * @program: ruoyi * @author: linqingsong * @create: 2023-07-22 17:23 * @description: 成都软思同创科技有限公司 **/ @Data public class WXPayNotifyDto { private String id; private String create_time; private String event_type; private String resource_type; private WXPayNotifyResourceDto resource; private String summary; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/dto/WXPayNotifyResourceDto.java
New file @@ -0,0 +1,14 @@ package com.ruoyi.order.domain.dto; /** * @program: ruoyi * @author: linqingsong * @create: 2023-07-22 17:25 * @description: 成都软思同创科技有限公司 **/ public class WXPayNotifyResourceDto { private String algorithm; private String ciphertext; private String associated_datal; private String nonce; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java
@@ -14,6 +14,7 @@ import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.order.domain.dto.*; import com.ruoyi.order.domain.pojo.account.OrderRefund; import com.ruoyi.order.domain.pojo.account.PaymentMessage; import com.ruoyi.order.domain.pojo.order.ConsumerGoods; import com.ruoyi.order.domain.pojo.order.Order; import com.ruoyi.order.domain.pojo.order.OrderGoods; @@ -24,6 +25,8 @@ import com.ruoyi.order.service.order.OrderGoodsService; import com.ruoyi.order.service.order.OrderService; import com.ruoyi.order.service.order.UserServiceRecordService; import com.ruoyi.order.tools.request.pay.combine.CombineTransactionsJsRequest; import com.ruoyi.order.tools.service.ProfitsSharingService; import com.ruoyi.system.api.constant.AppErrorConstant; import com.ruoyi.system.api.constant.DelayTaskEnum; import com.ruoyi.system.api.constant.SecurityConstant; @@ -39,6 +42,8 @@ import com.ruoyi.system.api.domain.poji.sys.SysUser; import com.ruoyi.system.api.domain.vo.*; import com.ruoyi.system.api.service.*; import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; import com.wechat.pay.java.service.payments.jsapi.model.*; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; @@ -52,6 +57,10 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAConfig; import com.wechat.pay.java.service.payments.jsapi.JsapiService; /** * <p> @@ -106,8 +115,28 @@ @Resource private RedisService redisService; @Resource private ProfitsSharingService profitsSharingService; @Autowired private RedissonClient redissonClient; /** 商户号 */ public static String merchantId = ""; /** 商户API私钥路径 */ public static String privateKeyPath = ""; /** 商户证书序列号 */ public static String merchantSerialNumber = ""; /** 微信支付平台证书路径 */ public static String wechatPayCertificatePath = ""; /** 微信支付 APIv3 密钥 */ public static String apiV3Key = ""; /** 微信支付APPID */ public static String appId=""; /** 微信支付商户ID */ public static String mchId=""; /** 通知地址 */ public static String notifyUrl=""; /** * @description: buyGoods @@ -664,6 +693,37 @@ appPlaceOrderVo.setOrderId(orderId); appPlaceOrderVo.setOrderNo(orderNo); // 调用支付 /* CombineTransactionsJsRequest request=new CombineTransactionsJsRequest(); request.setCombineAppid(); request.setCombineMchid(); profitsSharingService.combineTransactions(request);*/ //构建预下单支付对象 PrepayRequest request = new PrepayRequest(); Amount amount = new Amount(); amount.setTotal(Integer.parseInt(order.getPayMoney().multiply(new BigDecimal(100)).toString())); request.setAmount(amount); request.setAppid(this.appId); request.setMchid(this.mchId); request.setDescription(order.getGoodsInfo()); request.setNotifyUrl(this.notifyUrl); request.setOutTradeNo(order.getOrderId()); Payer payer = new Payer(); payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********"); request.setPayer(payer); //返回前端唤醒支付结果信息 PrepayWithRequestPaymentResponse res = this.getJsApIResponse(request); appPlaceOrderVo.setAppId(this.appId); appPlaceOrderVo.setTimeStamp(res.getTimeStamp()); appPlaceOrderVo.setNonceStr(res.getNonceStr()); appPlaceOrderVo.setPackageStr(res.getPackageVal()); appPlaceOrderVo.setTradeType(res.getSignType()); appPlaceOrderVo.setPaySign(res.getPaySign()); //减去优惠券 if(memberCouponSJ!=null){ remoteCouponService.useMemberCoupon(memberCouponSJ.toString()); @@ -684,6 +744,79 @@ } /** * * 功能描述: 预下单,返回支付数据prePayId * * 构建对象参考 * PrepayRequest request = new PrepayRequest(); * Amount amount = new Amount(); * amount.setTotal(100); * request.setAmount(amount); * request.setAppid("wxa9d9651ae******"); * request.setMchid("190000****"); * request.setDescription("测试商品标题"); * request.setNotifyUrl("https://notify_url"); * request.setOutTradeNo("out_trade_no_001"); * Payer payer = new Payer(); * payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********"); * request.setPayer(payer); * * @auther: linqingsong * @date: 2023/7/22 16:13 */ /*public String getPrePayId(PrepayRequest request) { Config config = new RSAConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .wechatPayCertificatesFromPath(wechatPayCertificatePath) .build(); JsapiService service = new JsapiService.Builder().config(config).build(); PrepayResponse response = service.prepay(request); return response.getPrepayId(); }*/ /** * * 功能描述: 预下单,并返回前端需要换起支付的字符串 * * 构建对象参考 * * PrepayRequest request = new PrepayRequest(); * * Amount amount = new Amount(); * * amount.setTotal(100); * * request.setAmount(amount); * * request.setAppid("wxa9d9651ae******"); * * request.setMchid("190000****"); * * request.setDescription("测试商品标题"); * * request.setNotifyUrl("https://notify_url"); * * request.setOutTradeNo("out_trade_no_001"); * * Payer payer = new Payer(); * * payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********"); * * request.setPayer(payer); * * * @auther: linqingsong * @date: 2023/7/22 16:53 */ public PrepayWithRequestPaymentResponse getJsApIResponse(PrepayRequest request){ Config config = new RSAConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .wechatPayCertificatesFromPath(wechatPayCertificatePath) .build(); JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build(); PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request); return response; } /** * @param appPlaceActivityDto * @return AppPlaceOrderVo * @description 创建活动订单