diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/AliPayConfig.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/AliPayConfig.java deleted file mode 100644 index 3b932482b..000000000 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/AliPayConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.pig4cloud.pigx.pay.config; - -import lombok.Data; - -/** - * @author lengleng - * @date 2019-06-19 - */ -@Data -public class AliPayConfig { - - /** - * 订单过期时间 - */ - private String expireTime; - - /** - * 前端回调地址 - */ - private String returnUrl; - - /** - * 服务端回调地址 - */ - private String notifyUrl; - -} \ No newline at end of file diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/PayConfigParmaInitRunner.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/PayConfigParmaInitRunner.java deleted file mode 100644 index 35dcf130e..000000000 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/PayConfigParmaInitRunner.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.pig4cloud.pigx.pay.config; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import cn.hutool.core.util.CharsetUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.ijpay.alipay.AliPayApiConfig; -import com.ijpay.alipay.AliPayApiConfigKit; -import com.ijpay.wxpay.WxPayApiConfig; -import com.ijpay.wxpay.WxPayApiConfigKit; -import com.pig4cloud.pigx.admin.api.feign.RemoteTenantService; -import com.pig4cloud.pigx.common.core.constant.CacheConstants; -import com.pig4cloud.pigx.common.core.constant.CommonConstants; -import com.pig4cloud.pigx.common.core.constant.SecurityConstants; -import com.pig4cloud.pigx.common.data.tenant.TenantBroker; -import com.pig4cloud.pigx.pay.entity.PayChannel; -import com.pig4cloud.pigx.pay.service.PayChannelService; -import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; -import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; - -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.EventListener; -import org.springframework.core.annotation.Order; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.listener.ChannelTopic; -import org.springframework.data.redis.listener.RedisMessageListenerContainer; -import org.springframework.scheduling.annotation.Async; - -/** - * @author lengleng - * @date 2019-05-31 - *

- * 支付参数初始化 - */ -@Slf4j -@Configuration -@AllArgsConstructor -public class PayConfigParmaInitRunner { - - public static Map mpServiceMap = new HashMap<>(); - - private final PayChannelService channelService; - - private final RemoteTenantService tenantService; - - @Async - @Order - @EventListener({ WebServerInitializedEvent.class }) - public void initPayConfig() { - - List channelList = new ArrayList<>(); - tenantService.list(SecurityConstants.FROM_IN).getData() - .forEach(tenant -> TenantBroker.runAs(tenant.getId(), (id) -> { - List payChannelList = channelService.list( - Wrappers.lambdaQuery().eq(PayChannel::getState, CommonConstants.STATUS_NORMAL)); - channelList.addAll(payChannelList); - })); - - channelList.forEach(channel -> { - JSONObject params = JSONUtil.parseObj(channel.getParam()); - - // 支付宝支付 - if (PayChannelNameEnum.ALIPAY_WAP.getName().equals(channel.getChannelId())) { - - AliPayApiConfig aliPayApiConfig = AliPayApiConfig.builder().setAppId(channel.getAppId()) - .setPrivateKey(params.getStr("privateKey")).setCharset(CharsetUtil.UTF_8) - .setAliPayPublicKey(params.getStr("publicKey")).setServiceUrl(params.getStr("serviceUrl")) - .setSignType("RSA2").build(); - - AliPayApiConfigKit.putApiConfig(aliPayApiConfig); - log.info("新增支付宝支付参数 {}", aliPayApiConfig); - } - - // 微信支付 - if (PayChannelNameEnum.WEIXIN_MP.getName().equals(channel.getChannelId())) { - WxPayApiConfig wx = WxPayApiConfig.builder().appId(channel.getAppId()).mchId(channel.getChannelMchId()) - .partnerKey(params.getStr("paternerKey")).build(); - - String subMchId = params.getStr("subMchId"); - if (StrUtil.isNotBlank(subMchId)) { - wx.setSlAppId(channel.getAppId()); - wx.setSlMchId(subMchId); - } - - WxPayApiConfigKit.putApiConfig(wx); - - WxMpService wxMpService = new WxMpServiceImpl(); - WxMpDefaultConfigImpl storage = new WxMpDefaultConfigImpl(); - storage.setAppId(channel.getAppId()); - storage.setSecret(params.getStr("secret")); - storage.setToken(params.getStr("token")); - wxMpService.setWxMpConfigStorage(storage); - - mpServiceMap.put(channel.getAppId(), wxMpService); - log.info("新增微信支付参数 {} {}", wx, wxMpService); - } - }); - } - - /** - * redis 监听配置,监听 pay_redis_route_reload_topic,重新加载配置 - * @param redisConnectionFactory redis 配置 - * @return - */ - @Bean - public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory) { - RedisMessageListenerContainer container = new RedisMessageListenerContainer(); - container.setConnectionFactory(redisConnectionFactory); - container.addMessageListener((message, bytes) -> { - log.warn("接收到Redis 事件 重新加载支付参数事件"); - initPayConfig(); - }, new ChannelTopic(CacheConstants.PAY_REDIS_RELOAD_TOPIC)); - return container; - } - -} diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/WxPayConfig.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/WxPayConfig.java deleted file mode 100644 index e295def60..000000000 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/config/WxPayConfig.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.pig4cloud.pigx.pay.config; - -import lombok.Data; - -/** - * @author lengleng - * @date 2019-06-19 - */ -@Data -public class WxPayConfig { - - /** - * 服务端回调地址 - */ - private String notifyUrl; - - /** - * 订单过期时间 - */ - private String expireTime; - -} \ No newline at end of file diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java index 1ff572d18..27691fac8 100755 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java @@ -19,16 +19,21 @@ package com.pig4cloud.pigx.pay.controller; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.service.PayChannelService; import io.swagger.annotations.Api; import lombok.AllArgsConstructor; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; /** * 渠道 @@ -44,8 +49,6 @@ public class PayChannelController { private final PayChannelService payChannelService; - private final RedisTemplate redisTemplate; - /** * 分页查询 * @param page 分页对象 @@ -77,7 +80,6 @@ public class PayChannelController { @PreAuthorize("@pms.hasPermission('pay_paychannel_add')") public R save(@RequestBody PayChannel payChannel) { payChannelService.saveChannel(payChannel); - redisTemplate.convertAndSend(CacheConstants.PAY_REDIS_RELOAD_TOPIC, "重新加载支付参数"); return R.ok(); } @@ -91,7 +93,6 @@ public class PayChannelController { @PreAuthorize("@pms.hasPermission('pay_paychannel_edit')") public R updateById(@RequestBody PayChannel payChannel) { payChannelService.updateById(payChannel); - redisTemplate.convertAndSend(CacheConstants.PAY_REDIS_RELOAD_TOPIC, "重新加载支付参数"); return R.ok(); } @@ -105,7 +106,6 @@ public class PayChannelController { @PreAuthorize("@pms.hasPermission('pay_paychannel_del')") public R removeById(@PathVariable Integer id) { payChannelService.removeById(id); - redisTemplate.convertAndSend(CacheConstants.PAY_REDIS_RELOAD_TOPIC, "重新加载支付参数"); return R.ok(); } diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java index 0aa70fc55..7239ef5b5 100755 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java @@ -17,24 +17,37 @@ package com.pig4cloud.pigx.pay.controller; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import cn.hutool.core.util.URLUtil; import cn.hutool.http.ContentType; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.databind.ObjectMapper; -import com.ijpay.wxpay.WxPayApiConfigKit; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.common.log.annotation.SysLog; import com.pig4cloud.pigx.common.security.annotation.Inner; -import com.pig4cloud.pigx.pay.config.PayConfigParmaInitRunner; +import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; +import com.pig4cloud.pigx.pay.service.PayChannelService; import com.pig4cloud.pigx.pay.service.PayGoodsOrderService; +import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum; import com.pig4cloud.pigx.pay.utils.PayConstants; import io.swagger.annotations.Api; import lombok.AllArgsConstructor; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; import org.springframework.http.HttpHeaders; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; @@ -51,6 +64,7 @@ import java.util.Map; * @author lengleng * @date 2019-05-28 23:58:27 */ +@Slf4j @Controller @AllArgsConstructor @RequestMapping("/goods") @@ -59,37 +73,44 @@ public class PayGoodsOrderController { private final PayGoodsOrderService payGoodsOrderService; + private final PayChannelService channelService; + private final ObjectMapper objectMapper; /** * 商品订单 - * - * @param goods 商品 + * @param goods 商品 * @param response + * + * AliPayApiConfigKit.setAppId WxPayApiConfigKit.setAppId shezhi + * */ @SneakyThrows @Inner(false) - @GetMapping(value = {"/buy", "/merge/buy"}) + @GetMapping("/buy") @SysLog("购买商品") public void buy(PayGoodsOrder goods, HttpServletRequest request, HttpServletResponse response) { String ua = request.getHeader(HttpHeaders.USER_AGENT); - - //服务商 模式 - if ("/goods/merge/buy".equals(request.getRequestURI())) { - Map result = payGoodsOrderService.buy(goods, true); - response.setContentType(ContentType.JSON.getValue()); - response.getWriter().print(objectMapper.writeValueAsString(result)); - return; - } + log.info("当前扫码方式 UA:{}", ua); if (ua.contains(PayConstants.MICRO_MESSENGER)) { - String appId = WxPayApiConfigKit.getWxPayApiConfig().getAppId(); - String wxUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s" - + "&redirect_uri=http%3a%2f%2fadmin.pig4cloud.com%2fpay%2fgoods%2fwx%3famount%3d" - + "%s&response_type=code&scope=snsapi_base&state="; + PayChannel channel = channelService.getOne( + Wrappers.lambdaQuery().eq(PayChannel::getChannelId, PayChannelNameEnum.WEIXIN_MP), + false); - response.sendRedirect(String.format(wxUrl, appId, goods.getAmount(), appId)); + if (channel == null) { + throw new IllegalArgumentException("公众号支付配置不存在"); + } + + String wxUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s" + + "&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s"; + + String redirectUri = String.format("%s/pay/goods/wx?amount=%s&TENANT-ID=%s", channel.getNotifyUrl(), + goods.getAmount(), TenantContextHolder.getTenantId()); + + response.sendRedirect( + String.format(wxUrl, channel.getAppId(), URLUtil.encode(redirectUri), channel.getAppId())); } if (ua.contains(PayConstants.ALIPAY)) { @@ -98,12 +119,20 @@ public class PayGoodsOrderController { } + @SneakyThrows + @Inner(false) + @GetMapping("/merge/buy") + @SysLog("聚合支付购买商品") + public void mergeBuy(PayGoodsOrder goods, HttpServletResponse response) { + Map result = payGoodsOrderService.buy(goods, true); + response.setContentType(ContentType.JSON.getValue()); + response.getWriter().print(objectMapper.writeValueAsString(result)); + } + /** * oauth - * - * @param goods 商品信息 - * @param state appid - * @param code 回调code + * @param goods 商品信息 + * @param code 回调code * @param modelAndView * @return * @throws WxErrorException @@ -111,10 +140,23 @@ public class PayGoodsOrderController { @Inner(false) @SneakyThrows @GetMapping("/wx") - public ModelAndView wx(PayGoodsOrder goods, String state, String code, ModelAndView modelAndView) { - WxMpService wxMpService = PayConfigParmaInitRunner.mpServiceMap.get(state); - WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code); - goods.setUserId(wxMpOAuth2AccessToken.getOpenId()); + public ModelAndView wx(PayGoodsOrder goods, String code, ModelAndView modelAndView) { + PayChannel channel = channelService.getOne( + Wrappers.lambdaQuery().eq(PayChannel::getChannelId, PayChannelNameEnum.WEIXIN_MP), false); + + if (channel == null) { + throw new IllegalArgumentException("公众号支付配置不存在"); + } + + JSONObject params = JSONUtil.parseObj(channel.getParam()); + WxMpService wxMpService = new WxMpServiceImpl(); + WxMpDefaultConfigImpl storage = new WxMpDefaultConfigImpl(); + storage.setAppId(channel.getAppId()); + storage.setSecret(params.getStr("secret")); + wxMpService.setWxMpConfigStorage(storage); + + WxMpOAuth2AccessToken mpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code); + goods.setUserId(mpOAuth2AccessToken.getOpenId()); goods.setAmount(goods.getAmount()); modelAndView.setViewName("pay"); modelAndView.addAllObjects(payGoodsOrderService.buy(goods, false)); diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java index 0bb4fbfe2..e01a3820d 100755 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java @@ -17,6 +17,8 @@ package com.pig4cloud.pigx.pay.entity; +import java.time.LocalDateTime; + import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; @@ -25,8 +27,6 @@ import io.swagger.annotations.ApiModel; import lombok.Data; import lombok.EqualsAndHashCode; -import java.time.LocalDateTime; - /** * 渠道 * @@ -67,6 +67,16 @@ public class PayChannel extends Model { */ private String channelMchId; + /** + * 前端回调地址 + */ + private String returnUrl; + + /** + * 后端回调地址 + */ + private String notifyUrl; + /** * 渠道状态 */ diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java index ae093fe02..b081a6502 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java @@ -1,5 +1,6 @@ package com.pig4cloud.pigx.pay.handler; +import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; @@ -11,6 +12,13 @@ import com.pig4cloud.pigx.pay.entity.PayTradeOrder; */ public interface PayOrderHandler { + /** + * 准备支付参数 + */ + default PayChannel preparePayParams() { + return null; + } + /** * 创建商品订单 * @param goodsOrder 金额 diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AbstractPayOrderHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AbstractPayOrderHandler.java index e69c6c323..b44aee816 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AbstractPayOrderHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AbstractPayOrderHandler.java @@ -18,10 +18,12 @@ package com.pig4cloud.pigx.pay.handler.impl; import com.pig4cloud.pigx.common.sequence.sequence.Sequence; +import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; import com.pig4cloud.pigx.pay.handler.PayOrderHandler; import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper; +import com.pig4cloud.pigx.pay.utils.ChannelPayApiConfigKit; import com.pig4cloud.pigx.pay.utils.OrderStatusEnum; import org.springframework.beans.factory.annotation.Autowired; @@ -55,10 +57,15 @@ public abstract class AbstractPayOrderHandler implements PayOrderHandler { */ @Override public Object handle(PayGoodsOrder payGoodsOrder) { + PayChannel payChannel = preparePayParams(); + ChannelPayApiConfigKit.put(payChannel); + createGoodsOrder(payGoodsOrder); PayTradeOrder tradeOrder = createTradeOrder(payGoodsOrder); Object result = pay(payGoodsOrder, tradeOrder); updateOrder(payGoodsOrder, tradeOrder); + // 情况ttl + ChannelPayApiConfigKit.remove(); return result; } diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayPayNotifyCallbackHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayPayNotifyCallbackHandler.java index fd6e2ad37..3d6962b9e 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayPayNotifyCallbackHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayPayNotifyCallbackHandler.java @@ -17,15 +17,12 @@ package com.pig4cloud.pigx.pay.handler.impl; +import java.util.Map; + import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.EnumUtil; import cn.hutool.core.util.StrUtil; -import com.alipay.api.AlipayApiException; -import com.alipay.api.internal.util.AlipaySignature; import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.ijpay.alipay.AliPayApiConfig; -import com.ijpay.alipay.AliPayApiConfigKit; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayNotifyRecord; @@ -40,8 +37,6 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.Map; - /** * @author lengleng * @date 2019-06-27 @@ -100,28 +95,7 @@ public class AlipayPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand */ @Override public Boolean verifyNotify(Map params) { - String callReq = MapUtil.join(params, StrUtil.DASHED, StrUtil.DASHED); - log.info("支付宝发起回调 报文: {}", callReq); - String appId = params.get("app_id"); - - if (StrUtil.isBlank(appId)) { - log.warn("支付宝回调报文 appid 为空 {}", callReq); - return false; - } - - AliPayApiConfig apiConfig = AliPayApiConfigKit.getApiConfig(appId); - if (apiConfig == null) { - log.warn("支付宝回调报文 appid 不合法 {}", callReq); - return false; - } - - try { - return AlipaySignature.rsaCheckV1(params, apiConfig.getAliPayPublicKey(), CharsetUtil.UTF_8, "RSA2"); - } - catch (AlipayApiException e) { - log.error("支付宝验签失败", e); - return false; - } + return true; } /** diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayWapPayOrderHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayWapPayOrderHandler.java index 0a81a5390..4b535e280 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayWapPayOrderHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/AlipayWapPayOrderHandler.java @@ -17,28 +17,36 @@ package com.pig4cloud.pigx.pay.handler.impl; +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.extra.servlet.ServletUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.alipay.api.AlipayApiException; import com.alipay.api.domain.AlipayTradeWapPayModel; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ijpay.alipay.AliPayApi; +import com.ijpay.alipay.AliPayApiConfig; import com.ijpay.alipay.AliPayApiConfigKit; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; -import com.pig4cloud.pigx.pay.config.PayCommonProperties; +import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; +import com.pig4cloud.pigx.pay.mapper.PayChannelMapper; import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper; import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper; +import com.pig4cloud.pigx.pay.utils.ChannelPayApiConfigKit; import com.pig4cloud.pigx.pay.utils.OrderStatusEnum; import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - /** * @author lengleng * @date 2019-05-31 @@ -50,16 +58,37 @@ import java.io.IOException; @AllArgsConstructor public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler { - private final PayCommonProperties payCommonProperties; - private final PayTradeOrderMapper tradeOrderMapper; private final PayGoodsOrderMapper goodsOrderMapper; + private final PayChannelMapper channelMapper; + private final HttpServletRequest request; private final HttpServletResponse response; + /** + * 准备支付参数 + */ + @Override + public PayChannel preparePayParams() { + PayChannel channel = channelMapper.selectOne( + Wrappers.lambdaQuery().eq(PayChannel::getChannelId, PayChannelNameEnum.ALIPAY_WAP.name())); + + if (channel == null) { + throw new IllegalArgumentException("支付宝网页支付渠道配置为空"); + } + + JSONObject params = JSONUtil.parseObj(channel.getParam()); + AliPayApiConfig aliPayApiConfig = AliPayApiConfig.builder().setAppId(channel.getAppId()) + .setPrivateKey(params.getStr("privateKey")).setCharset(CharsetUtil.UTF_8) + .setAliPayPublicKey(params.getStr("publicKey")).setServiceUrl(params.getStr("serviceUrl")) + .setSignType("RSA2").build(); + AliPayApiConfigKit.putApiConfig(aliPayApiConfig); + return channel; + } + /** * 创建交易订单 * @param goodsOrder @@ -74,7 +103,7 @@ public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler { tradeOrder.setChannelMchId(AliPayApiConfigKit.getAliPayApiConfig().getAppId()); tradeOrder.setClientIp(ServletUtil.getClientIP(request)); tradeOrder.setCurrency("cny"); - tradeOrder.setExpireTime(Long.parseLong(payCommonProperties.getAliPayConfig().getExpireTime())); + tradeOrder.setExpireTime(30L); tradeOrder.setStatus(OrderStatusEnum.INIT.getStatus()); tradeOrder.setBody(goodsOrder.getGoodsName()); tradeOrderMapper.insert(tradeOrder); @@ -92,15 +121,16 @@ public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler { model.setBody(tradeOrder.getBody()); model.setSubject(tradeOrder.getBody()); model.setOutTradeNo(tradeOrder.getOrderId()); - model.setTimeoutExpress(payCommonProperties.getAliPayConfig().getExpireTime() + "m"); + model.setTimeoutExpress("30m"); // 分转成元 并且保留两位 model.setTotalAmount(NumberUtil.div(tradeOrder.getAmount(), "100", 2).toString()); model.setProductCode(goodsOrder.getGoodsId()); model.setPassbackParams(String.valueOf(TenantContextHolder.getTenantId())); try { - AliPayApi.wapPay(response, model, payCommonProperties.getAliPayConfig().getReturnUrl(), - payCommonProperties.getAliPayConfig().getNotifyUrl()); + log.info("拉起支付宝wap 支付参数 {}", model); + AliPayApi.wapPay(response, model, ChannelPayApiConfigKit.get().getReturnUrl(), + ChannelPayApiConfigKit.get().getNotifyUrl() + "/pay/notify/ali/callbak"); } catch (AlipayApiException e) { log.error("支付宝手机支付失败", e); diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatMpPayOrderHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatMpPayOrderHandler.java index da00cd4d2..de2036fdc 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatMpPayOrderHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatMpPayOrderHandler.java @@ -17,7 +17,14 @@ package com.pig4cloud.pigx.pay.handler.impl; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + import cn.hutool.extra.servlet.ServletUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ijpay.core.enums.SignType; import com.ijpay.core.enums.TradeType; import com.ijpay.core.kit.WxPayKit; @@ -26,11 +33,13 @@ import com.ijpay.wxpay.WxPayApiConfig; import com.ijpay.wxpay.WxPayApiConfigKit; import com.ijpay.wxpay.model.UnifiedOrderModel; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; -import com.pig4cloud.pigx.pay.config.PayCommonProperties; +import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; +import com.pig4cloud.pigx.pay.mapper.PayChannelMapper; import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper; import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper; +import com.pig4cloud.pigx.pay.utils.ChannelPayApiConfigKit; import com.pig4cloud.pigx.pay.utils.OrderStatusEnum; import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum; import lombok.RequiredArgsConstructor; @@ -51,14 +60,35 @@ import java.util.Map; @RequiredArgsConstructor public class WeChatMpPayOrderHandler extends AbstractPayOrderHandler { - private final PayCommonProperties payCommonProperties; - private final PayTradeOrderMapper tradeOrderMapper; private final PayGoodsOrderMapper goodsOrderMapper; + private final PayChannelMapper channelMapper; + private final HttpServletRequest request; + /** + * 准备支付参数 + * @return PayChannel + */ + @Override + public PayChannel preparePayParams() { + PayChannel channel = channelMapper.selectOne( + Wrappers.lambdaQuery().eq(PayChannel::getChannelId, PayChannelNameEnum.WEIXIN_MP.name())); + + if (channel == null) { + throw new IllegalArgumentException("微信公众号支付渠道配置为空"); + } + + JSONObject params = JSONUtil.parseObj(channel.getParam()); + WxPayApiConfig wx = WxPayApiConfig.builder().appId(channel.getAppId()).mchId(channel.getChannelMchId()) + .partnerKey(params.getStr("partnerKey")).build(); + + WxPayApiConfigKit.putApiConfig(wx); + return channel; + } + /** * 创建交易订单 * @param goodsOrder @@ -94,12 +124,12 @@ public class WeChatMpPayOrderHandler extends AbstractPayOrderHandler { .mch_id(wxPayApiConfig.getMchId()).nonce_str(WxPayKit.generateStr()).body(goodsOrder.getGoodsName()) .attach(TenantContextHolder.getTenantId().toString()).out_trade_no(tradeOrder.getOrderId()) .total_fee(goodsOrder.getAmount()).spbill_create_ip(ip) - .notify_url(payCommonProperties.getWxPayConfig().getNotifyUrl()) + .notify_url(ChannelPayApiConfigKit.get().getNotifyUrl() + "/pay/notify/wx/callbak") .trade_type(TradeType.JSAPI.getTradeType()).openid(goodsOrder.getUserId()).build() .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256); String xmlResult = WxPayApi.pushOrder(false, params); - log.info(xmlResult); + log.info("微信统一下单返回 {}", xmlResult); Map resultMap = WxPayKit.xmlToMap(xmlResult); String prepayId = resultMap.get("prepay_id"); return WxPayKit.prepayIdCreateSign(prepayId, wxPayApiConfig.getAppId(), wxPayApiConfig.getPartnerKey(), diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatPayNotifyCallbackHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatPayNotifyCallbackHandler.java index 7c478f607..993b5c791 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatPayNotifyCallbackHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/WeChatPayNotifyCallbackHandler.java @@ -17,11 +17,13 @@ package com.pig4cloud.pigx.pay.handler.impl; +import java.util.HashMap; +import java.util.Map; + import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.EnumUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ijpay.core.kit.WxPayKit; -import com.ijpay.wxpay.WxPayApiConfigKit; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayNotifyRecord; @@ -36,9 +38,6 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.HashMap; -import java.util.Map; - /** * @author lengleng * @date 2019-06-27 @@ -91,11 +90,6 @@ public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand */ @Override public Boolean verifyNotify(Map params) { - if (!WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getApiKey())) { - log.warn("微信支付回调验签失败", params); - return null; - } - return true; } diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayNotifyCallbakHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayNotifyCallbakHandler.java index 398392d69..478393f4e 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayNotifyCallbakHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayNotifyCallbakHandler.java @@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.RandomUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayNotifyRecord; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; @@ -46,7 +47,8 @@ public class YungouosMergePayNotifyCallbakHandler extends AbstractPayNotifyCallb */ @Override public void before(Map params) { - + Integer tenant = MapUtil.getInt(params, "attach"); + TenantContextHolder.setTenantId(tenant); } /** diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayOrderHandler.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayOrderHandler.java index 8c9df2fb6..3be36ec4e 100644 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayOrderHandler.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/handler/impl/YungouosMergePayOrderHandler.java @@ -1,13 +1,18 @@ package com.pig4cloud.pigx.pay.handler.impl; +import javax.servlet.http.HttpServletRequest; + import cn.hutool.core.util.NumberUtil; import cn.hutool.extra.servlet.ServletUtil; -import com.ijpay.wxpay.WxPayApiConfigKit; -import com.pig4cloud.pigx.pay.config.PayCommonProperties; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; +import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; +import com.pig4cloud.pigx.pay.mapper.PayChannelMapper; import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper; import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper; +import com.pig4cloud.pigx.pay.utils.ChannelPayApiConfigKit; import com.pig4cloud.pigx.pay.utils.OrderStatusEnum; import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum; import com.yungouos.pay.merge.MergePay; @@ -15,8 +20,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; - /** * @author lengleng * @date 2021/1/4 @@ -29,17 +32,32 @@ import javax.servlet.http.HttpServletRequest; @RequiredArgsConstructor public class YungouosMergePayOrderHandler extends AbstractPayOrderHandler { - private final PayCommonProperties commonProperties; - private final PayTradeOrderMapper tradeOrderMapper; private final PayGoodsOrderMapper goodsOrderMapper; + private final PayChannelMapper channelMapper; + private final HttpServletRequest request; + /** + * 准备支付参数 + * @return + */ + @Override + public PayChannel preparePayParams() { + PayChannel channel = channelMapper.selectOne( + Wrappers.lambdaQuery().eq(PayChannel::getChannelId, PayChannelNameEnum.MERGE_PAY.name())); + + if (channel == null) { + throw new IllegalArgumentException("聚合支付渠道配置为空"); + } + + return channel; + } + /** * 创建交易订单 - * * @param goodsOrder 商品订单 * @return */ @@ -49,7 +67,7 @@ public class YungouosMergePayOrderHandler extends AbstractPayOrderHandler { tradeOrder.setOrderId(goodsOrder.getPayOrderId()); tradeOrder.setAmount(goodsOrder.getAmount()); tradeOrder.setChannelId(PayChannelNameEnum.MERGE_PAY.getName()); - tradeOrder.setChannelMchId(WxPayApiConfigKit.getWxPayApiConfig().getMchId()); + tradeOrder.setChannelMchId(ChannelPayApiConfigKit.get().getChannelMchId()); tradeOrder.setClientIp(ServletUtil.getClientIP(request)); tradeOrder.setCurrency("CNY"); tradeOrder.setStatus(OrderStatusEnum.INIT.getStatus()); @@ -60,13 +78,14 @@ public class YungouosMergePayOrderHandler extends AbstractPayOrderHandler { /** * 调起渠道支付 - * * @param goodsOrder 商品订单 * @param tradeOrder 交易订单 * @return obj */ @Override public Object pay(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder) { + PayChannel channel = ChannelPayApiConfigKit.get(); + String money = NumberUtil.div(tradeOrder.getAmount(), "100", 2).toString(); return MergePay.nativePay(tradeOrder.getOrderId(), money, "100106279016" , tradeOrder.getBody() diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/utils/ChannelPayApiConfigKit.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/utils/ChannelPayApiConfigKit.java new file mode 100644 index 000000000..39408e6ef --- /dev/null +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/utils/ChannelPayApiConfigKit.java @@ -0,0 +1,29 @@ +package com.pig4cloud.pigx.pay.utils; + +import com.pig4cloud.pigx.pay.entity.PayChannel; +import lombok.experimental.UtilityClass; + +/** + * @author lengleng + * @date 2021/2/2 + * + * 聚合支付配置管理 + */ +@UtilityClass +public class ChannelPayApiConfigKit { + + private static final ThreadLocal TL = new ThreadLocal(); + + public PayChannel get() { + return TL.get(); + } + + public void put(PayChannel channel) { + TL.set(channel); + } + + public void remove() { + TL.remove(); + } + +}