diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java index b8384c3e9..1af2d3a0a 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java @@ -27,6 +27,7 @@ import com.pig4cloud.pigx.common.data.tenant.PigxTenantHandler; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -62,6 +63,7 @@ public class MybatisPlusConfig { */ @Bean @ConditionalOnMissingBean + @ConditionalOnProperty(name = "mybatisPlus.tenantEnable", havingValue = "true", matchIfMissing = true) public PaginationInterceptor paginationInterceptor(PigxTenantHandler tenantHandler) { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); List sqlParserList = new ArrayList<>(); diff --git a/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/common/sequence/properties/SequenceDbProperties.java b/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/common/sequence/properties/SequenceDbProperties.java index 016314f1f..bd94caad6 100644 --- a/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/common/sequence/properties/SequenceDbProperties.java +++ b/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/common/sequence/properties/SequenceDbProperties.java @@ -17,7 +17,7 @@ import org.springframework.stereotype.Component; */ @Data @Component -@ConfigurationProperties(prefix = "xsequence.db") +@ConfigurationProperties(prefix = "pigx.xsequence.db") public class SequenceDbProperties extends BaseSequenceProperties { /** * 表名称 diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteTenantService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteTenantService.java new file mode 100644 index 000000000..49d935a7f --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteTenantService.java @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + * + */ + +package com.pig4cloud.pigx.admin.api.feign; + +import com.pig4cloud.pigx.admin.api.entity.SysTenant; +import com.pig4cloud.pigx.common.core.constant.SecurityConstants; +import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants; +import com.pig4cloud.pigx.common.core.util.R; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; + +import java.util.List; + +/** + * @author lengleng + * @date 2019/6/19 + *

+ * 租户接口 + */ +@FeignClient(contextId = "remoteTenantService", value = ServiceNameConstants.UMPS_SERVICE) +public interface RemoteTenantService { + /** + * 查询全部有效租户 + * + * @param from 内部标志 + * @return + */ + @GetMapping("/tenant/list") + R> list(@RequestHeader(SecurityConstants.FROM) String from); + +} diff --git a/pigx-visual/pigx-daemon-quartz/src/test/java/com/pig4cloud/pigx/common/data/tenant/TenantContextHolderTest.java b/pigx-visual/pigx-daemon-quartz/src/test/java/com/pig4cloud/pigx/common/data/tenant/TenantContextHolderTest.java new file mode 100644 index 000000000..dbe7f5fe9 --- /dev/null +++ b/pigx-visual/pigx-daemon-quartz/src/test/java/com/pig4cloud/pigx/common/data/tenant/TenantContextHolderTest.java @@ -0,0 +1,22 @@ +package com.pig4cloud.pigx.common.data.tenant; + +import cn.hutool.core.thread.ThreadUtil; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author lengleng + * @date 2019-06-18 + */ +public class TenantContextHolderTest { + + public static void main(String[] args) { + TenantContextHolder.setTenantId(10000); + System.out.println(TenantContextHolder.getTenantId()); + + ThreadUtil.execAsync(() -> { + System.out.println(TenantContextHolder.getTenantId()); + }); + } +} \ No newline at end of file diff --git a/pigx-visual/pigx-pay/pom.xml b/pigx-visual/pigx-pay/pom.xml index 01cda2a9d..9e4802e1f 100755 --- a/pigx-visual/pigx-pay/pom.xml +++ b/pigx-visual/pigx-pay/pom.xml @@ -48,6 +48,11 @@ com.pig4cloud pigx-common-sequence + + + com.pig4cloud + pigx-upms-api + com.pig4cloud @@ -73,6 +78,10 @@ alipay-sdk-java 3.0.52.ALL + + com.github.binarywang + weixin-java-mp + org.springframework.boot @@ -83,6 +92,10 @@ org.springframework.boot spring-boot-starter-undertow + + org.springframework.boot + spring-boot-starter-freemarker + diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/AliPayConfig.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/AliPayConfig.java new file mode 100644 index 000000000..f1e484e88 --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/AliPayConfig.java @@ -0,0 +1,25 @@ +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/src/main/java/com/pig4cloud/pigx/pay/config/PayCommonProperties.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/PayCommonProperties.java new file mode 100644 index 000000000..df912b613 --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/PayCommonProperties.java @@ -0,0 +1,30 @@ +package com.pig4cloud.pigx.pay.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * @author lengleng + * @date 2019-06-18 + */ +@Data +@RefreshScope +@Configuration +@ConfigurationProperties(prefix = "pigx.pay") +public class PayCommonProperties { + /** + * 支付宝支付参数 + */ + private AliPayConfig aliPayConfig; + + /** + * 微信支付参数 + */ + private WxPayConfig wxPayConfig; + + + private String test; + +} \ No newline at end of file diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/PayConfigParmaInitRunner.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/PayConfigParmaInitRunner.java index 94d004024..3006bfdda 100644 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/PayConfigParmaInitRunner.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/PayConfigParmaInitRunner.java @@ -1,16 +1,38 @@ package com.pig4cloud.pigx.pay.config; +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.annotation.SqlParser; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.jpay.alipay.AliPayApiConfig; import com.jpay.alipay.AliPayApiConfigKit; +import com.jpay.weixin.api.WxPayApiConfig; +import com.jpay.weixin.api.WxPayApiConfigKit; +import com.pig4cloud.pigx.admin.api.feign.RemoteTenantService; +import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import com.pig4cloud.pigx.common.core.constant.SecurityConstants; +import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; +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.WxMpInMemoryConfigStorage; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; import org.springframework.core.annotation.Order; import org.springframework.scheduling.annotation.Async; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * @author lengleng * @date 2019-05-31 @@ -21,21 +43,69 @@ import org.springframework.scheduling.annotation.Async; @Configuration @AllArgsConstructor public class PayConfigParmaInitRunner { + public static Map mpServiceMap = new HashMap<>(); private final PayChannelService channelService; + private final RemoteTenantService tenantService; + @Async @Order + @SqlParser(filter = true) @EventListener({WebServerInitializedEvent.class}) public void initPayConfig() { - AliPayApiConfig rsa2 = AliPayApiConfig.New() - .setAppId("2016102000727659") - .setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkejVpiLJlece9KLb8gG/+WODkpe5SRfr65n3aUAvRPoouDUp/URBAtt24mzHFdGkaU/Il7ZxG7KUjLaFNTfq8t/bHEF7HBt7MZidpEjVaDxeG/hkA+xc+X2ePAJXVhy7v1tH+XRrxuggTj+d4q7vVGD7r1mtgX4d5hK9TTKnyhO6IUcthPOUSn07wx+5wlbv4/51ggj4Ku4AWCGaCWiebDFy4VZ/FmOMP5u3O7TocCGSy5UtaFZaVMM1nH603DG6NJ8fG+zKum9IvrdQMMmBWPT8rpy0U9ztchcd+0gTNrTfE/NOCgl/RF6z7Qic7NiTKjLxkGRq73XPzfJx0hyfpAgMBAAECggEAa2/sndAN/90JjNUgmlVnUnRKCvEceJ9/rw6KXOV2oqrAZg6GgB26iRsqP6EYZMuCsBDvlrjcITQJNq5is/Vg+I8OYr+duVISjN+ZlLexI+/BxYsLWCmr6DE3myCdvwn7rezb5NR6ejWzetvALoG3Qx4AU9sO7rfX7ZevUrE8Pc5pa/rTCHOIec9P7Hfm4xrXd0DPmbAwFvUQ4spcC9xjcBhLJ3tfmkoEU11jC6Y/J7N0/TZZxqNC+HcYftSNEmbO3vxYfz/9mbabx7Uzp8xs4qHPJACmaP5tcWOCf1qJVOwP53Cd3H9J9Be9cAvlxKfT48s1ghoxLn7QB27p0UwntQKBgQDzTpCCFDoUH328B3iGTkwZq24DOUh5ZwhMG6VIFPLHwJYK6HVM473SX0nJWkbiBYFG4WiQWUZnOhz/qjTH1vvE/nzJwQ79zZahren2b8XulXKM6S/mafiBAHKl/FArcr14iAWkh+scZKWFKrNf6Hp8rQ6zu0fWdwzUOlaQFaSnTwKBgQCtDtpIagRPyNj0J39uMRJqsaY0TdJ53TD4bflf5UiFhNFH2Dikgw/uX8Pom2qtIvf3xnO2bzmJW2+OSkF7U0fL+UXkAaBHW+7YVcs8pWARSd5LWBXGWysV2wUALwynZSdwtgpgrzMQnuzklQ3hNR9LBSEGN7yJwkU83ZRWPzbvRwKBgQDU3E8g/oExSbu+3Opc1fNOIeTFfUAitjlUHHulbG5aw+qA8I5vDm/rtOHg/tI0u4w2bs4EO5aUiQsFwesbSsJJvjt+ZyCue0blfDnMGE2aRbVKAlidxOhcNAAZp3ycBm4tHROStjbDSGpm7syvg7xlhyHtrFNVFiJrKf7BX64FkQKBgCA8lAzJMuRp1YAlm2c7XOLjFMLJfFuXCHg+hCWI4Gl+xD1N2b9LarxMuoGp8cUurmJJZWSmc2FS1wT6cBg4+zbTyGEgrGqehW9nC+TQKYUO7Ym7btL0SKJZmiTenszP2vjz8Bryh+CguiAaY+t/qcSfv/cYitZeiec8n1UxkVohAoGAa8YwnzkEGBgz0TpdrGFxVBCqMIriMH4PQs2tWZ1nEBk6A7GrODRcRL0FQnRpHyf3mY5N/iEiNQ5GhQ5p1lifTvolTkVkdHpTGFhVfnYegaEAOznigi7dWJPoYlloN36AROxirGJKRIm+Od2bsybM/dNPJfoTDBDPFWGBH/klEBs=") - .setCharset("UTF-8") - .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuPkP2VJMR6vWCX8RwSFqNIa3klCdvRFJbuS1PN1anzQeeL9eOwtU7kGdI85yxb0dcdPzOYlG+jf9go8W9hBlgjxSRoXxLx03Yfl7cLmzJO9l9vIM1+HmNF0Ctm+el4Yi9dGs/P6q7lcHPUqs/RXGfeLrg33GMVwJbLmRcDZYeIcqPAA1OVF/4SHYr+f+O7glDOd60z+veOOexyoHmvUzYWlEz5+R4kOCNM/Z0w7KGgEYvHbZopexuTuFgUWy/9tYlNrnX+cZUWXVTskLUgD1UGWM1dS5+qfriqY9MPEwJjetcPJkoCK7A4IReE4q1DffUY9KS50/1ML+7na3R/p/UQIDAQAB") - .setServiceUrl("https://openapi.alipaydev.com/gateway.do") - .setSignType("RSA2") - .build(); - AliPayApiConfigKit.putApiConfig(rsa2); + List channelList = new ArrayList<>(); + tenantService.list(SecurityConstants.FROM_IN).getData() + .forEach(tenant -> { + TenantContextHolder.setTenantId(tenant.getId()); + 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.New() + .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); + } + + // 微信支付 + if (PayChannelNameEnum.WEIXIN_MP.getName().equals(channel.getChannelId())) { + WxPayApiConfig wx = WxPayApiConfig.New() + .setAppId(channel.getAppId()) + .setMchId(channel.getChannelMchId()) + .setPaternerKey(params.getStr("paternerKey")) + .setPayModel(WxPayApiConfig.PayModel.BUSINESSMODEL); + + String subMchId = params.getStr("subMchId"); + if (StrUtil.isNotBlank(subMchId)) { + wx.setPayModel(WxPayApiConfig.PayModel.SERVICEMODE); + wx.setSubMchId(subMchId); + } + + WxPayApiConfigKit.putApiConfig(wx); + + WxMpService wxMpService = new WxMpServiceImpl(); + WxMpInMemoryConfigStorage storage = new WxMpInMemoryConfigStorage(); + storage.setAppId(channel.getAppId()); + storage.setSecret(params.getStr("secret")); + storage.setToken(params.getStr("token")); + wxMpService.setWxMpConfigStorage(storage); + mpServiceMap.put(channel.getAppId(), wxMpService); + } + }); } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/WxPayConfig.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/WxPayConfig.java new file mode 100644 index 000000000..7c4da0b9d --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/config/WxPayConfig.java @@ -0,0 +1,20 @@ +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/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java index 7695ec207..1e8660d86 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayChannelController.java @@ -21,6 +21,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.pay.config.PayConfigParmaInitRunner; import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.service.PayChannelService; import io.swagger.annotations.Api; @@ -40,6 +41,7 @@ import org.springframework.web.bind.annotation.*; @RequestMapping("/paychannel") @Api(value = "paychannel", tags = "paychannel管理") public class PayChannelController { + private final PayConfigParmaInitRunner parmaInitRunner; private final PayChannelService payChannelService; /** @@ -76,7 +78,9 @@ public class PayChannelController { @PostMapping @PreAuthorize("@pms.hasPermission('pay_paychannel_add')") public R save(@RequestBody PayChannel payChannel) { - return R.ok(payChannelService.saveChannel(payChannel)); + payChannelService.saveChannel(payChannel); + parmaInitRunner.initPayConfig(); + return R.ok(); } /** @@ -89,7 +93,9 @@ public class PayChannelController { @PutMapping @PreAuthorize("@pms.hasPermission('pay_paychannel_edit')") public R updateById(@RequestBody PayChannel payChannel) { - return R.ok(payChannelService.updateById(payChannel)); + payChannelService.updateById(payChannel); + parmaInitRunner.initPayConfig(); + return R.ok(); } /** @@ -102,7 +108,9 @@ public class PayChannelController { @DeleteMapping("/{id}") @PreAuthorize("@pms.hasPermission('pay_paychannel_del')") public R removeById(@PathVariable Integer id) { - return R.ok(payChannelService.removeById(id)); + payChannelService.removeById(id); + parmaInitRunner.initPayConfig(); + return R.ok(); } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java index c392bb301..01f0a7ab1 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java @@ -17,17 +17,27 @@ package com.pig4cloud.pigx.pay.controller; -import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jpay.weixin.api.WxPayApiConfigKit; import com.pig4cloud.pigx.common.core.util.R; 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.PayGoodsOrder; import com.pig4cloud.pigx.pay.service.PayGoodsOrderService; +import com.pig4cloud.pigx.pay.utils.PayConstants; import io.swagger.annotations.Api; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import org.springframework.http.HttpHeaders; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; @@ -38,7 +48,7 @@ import javax.servlet.http.HttpServletRequest; * @author lengleng * @date 2019-05-28 23:58:27 */ -@RestController +@Controller @AllArgsConstructor @RequestMapping("/goods") @Api(value = "goods", tags = "商品订单管理") @@ -50,17 +60,112 @@ public class PayGoodsOrderController { /** * 商品订单 * - * @param amount 金额 + * @param goods 商品 + * @param modelAndView * @return R */ @Inner(false) @GetMapping("/buy") - @SysLog("新增商品订单") - public R save(Long amount, HttpServletRequest request) { + @SysLog("购买商品") + public ModelAndView buy(PayGoodsOrder goods, HttpServletRequest request, ModelAndView modelAndView) { String ua = request.getHeader(HttpHeaders.USER_AGENT); - if (StrUtil.isBlank(ua)) { - return R.failed("终端不合法"); + if (ua.contains(PayConstants.MICRO_MESSENGER)) { + String appId = WxPayApiConfigKit.getWxPayApiConfig().getAppId(); + modelAndView.setViewName("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + + "&redirect_uri=http%3a%2f%2fpigx.huaxiadaowei.com%2fpay%2fgoods%2fwx%3famount%3d" + goods.getAmount() + + "&response_type=code&scope=snsapi_base&state=" + appId); + return modelAndView; } - return payGoodsOrderService.buy(amount); + + modelAndView.setViewName("pay"); + modelAndView.addAllObjects(payGoodsOrderService.buy(goods)); + return modelAndView; } + + /** + * oauth + * + * @param goods 商品信息 + * @param state appid + * @param code 回调code + * @param modelAndView + * @return + * @throws WxErrorException + */ + @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.oauth2getAccessToken(code); + goods.setUserId(wxMpOAuth2AccessToken.getOpenId()); + goods.setAmount(goods.getAmount()); + modelAndView.setViewName("pay"); + modelAndView.addAllObjects(payGoodsOrderService.buy(goods)); + return modelAndView; + } + + /** + * 分页查询 + * + * @param page 分页对象 + * @param payGoodsOrder 商品订单表 + * @return + */ + @GetMapping("/page") + public R getPayGoodsOrderPage(Page page, PayGoodsOrder payGoodsOrder) { + return R.ok(payGoodsOrderService.page(page, Wrappers.query(payGoodsOrder))); + } + + + /** + * 通过id查询商品订单表 + * + * @param goodsOrderId id + * @return R + */ + @GetMapping("/{goodsOrderId}") + public R getById(@PathVariable("goodsOrderId") Integer goodsOrderId) { + return R.ok(payGoodsOrderService.getById(goodsOrderId)); + } + + /** + * 新增商品订单表 + * + * @param payGoodsOrder 商品订单表 + * @return R + */ + @SysLog("新增商品订单表") + @PostMapping + @PreAuthorize("@pms.hasPermission('generator_paygoodsorder_add')") + public R save(@RequestBody PayGoodsOrder payGoodsOrder) { + return R.ok(payGoodsOrderService.save(payGoodsOrder)); + } + + /** + * 修改商品订单表 + * + * @param payGoodsOrder 商品订单表 + * @return R + */ + @SysLog("修改商品订单表") + @PutMapping + @PreAuthorize("@pms.hasPermission('generator_paygoodsorder_edit')") + public R updateById(@RequestBody PayGoodsOrder payGoodsOrder) { + return R.ok(payGoodsOrderService.updateById(payGoodsOrder)); + } + + /** + * 通过id删除商品订单表 + * + * @param goodsOrderId id + * @return R + */ + @SysLog("删除商品订单表") + @DeleteMapping("/{goodsOrderId}") + @PreAuthorize("@pms.hasPermission('generator_paygoodsorder_del')") + public R removeById(@PathVariable Integer goodsOrderId) { + return R.ok(payGoodsOrderService.removeById(goodsOrderId)); + } + } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayNotifyRecordController.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayNotifyRecordController.java index d2ae2f1fa..7d8799f7c 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayNotifyRecordController.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayNotifyRecordController.java @@ -19,17 +19,27 @@ package com.pig4cloud.pigx.pay.controller; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jpay.alipay.AliPayApi; +import com.jpay.ext.kit.HttpKit; +import com.jpay.ext.kit.PaymentKit; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.common.security.annotation.Inner; import com.pig4cloud.pigx.pay.entity.PayNotifyRecord; +import com.pig4cloud.pigx.pay.handler.MessageDuplicateCheckerHandler; import com.pig4cloud.pigx.pay.service.PayNotifyRecordService; -import org.springframework.security.access.prepost.PreAuthorize; +import com.pig4cloud.pigx.pay.utils.PayConstants; import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + /** * 异步通知记录 @@ -37,70 +47,120 @@ import org.springframework.web.bind.annotation.*; * @author lengleng * @date 2019-05-28 23:57:23 */ +@Slf4j @RestController @AllArgsConstructor -@RequestMapping("/paynotifyrecord" ) -@Api(value = "paynotifyrecord", tags = "paynotifyrecord管理") +@RequestMapping("/notify") +@Api(value = "notify", tags = "notify管理") public class PayNotifyRecordController { + private final MessageDuplicateCheckerHandler duplicateCheckerHandler; + private final PayNotifyRecordService payNotifyRecordService; - private final PayNotifyRecordService payNotifyRecordService; - - /** - * 分页查询 - * @param page 分页对象 - * @param payNotifyRecord 异步通知记录 - * @return - */ - @GetMapping("/page" ) - public R getPayNotifyRecordPage(Page page, PayNotifyRecord payNotifyRecord) { - return R.ok(payNotifyRecordService.page(page, Wrappers.query(payNotifyRecord))); - } + /** + * 分页查询 + * + * @param page 分页对象 + * @param payNotifyRecord 异步通知记录 + * @return + */ + @GetMapping("/page") + public R getPayNotifyRecordPage(Page page, PayNotifyRecord payNotifyRecord) { + return R.ok(payNotifyRecordService.page(page, Wrappers.query(payNotifyRecord))); + } - /** - * 通过id查询异步通知记录 - * @param id id - * @return R - */ - @GetMapping("/{id}" ) - public R getById(@PathVariable("id" ) Long id) { - return R.ok(payNotifyRecordService.getById(id)); - } + /** + * 通过id查询异步通知记录 + * + * @param id id + * @return R + */ + @GetMapping("/{id}") + public R getById(@PathVariable("id") Long id) { + return R.ok(payNotifyRecordService.getById(id)); + } - /** - * 新增异步通知记录 - * @param payNotifyRecord 异步通知记录 - * @return R - */ - @SysLog("新增异步通知记录" ) - @PostMapping - @PreAuthorize("@pms.hasPermission('pay_paynotifyrecord_add')" ) - public R save(@RequestBody PayNotifyRecord payNotifyRecord) { - return R.ok(payNotifyRecordService.save(payNotifyRecord)); - } + /** + * 新增异步通知记录 + * + * @param payNotifyRecord 异步通知记录 + * @return R + */ + @SysLog("新增异步通知记录") + @PostMapping + @PreAuthorize("@pms.hasPermission('pay_paynotifyrecord_add')") + public R save(@RequestBody PayNotifyRecord payNotifyRecord) { + return R.ok(payNotifyRecordService.save(payNotifyRecord)); + } - /** - * 修改异步通知记录 - * @param payNotifyRecord 异步通知记录 - * @return R - */ - @SysLog("修改异步通知记录" ) - @PutMapping - @PreAuthorize("@pms.hasPermission('pay_paynotifyrecord_edit')" ) - public R updateById(@RequestBody PayNotifyRecord payNotifyRecord) { - return R.ok(payNotifyRecordService.updateById(payNotifyRecord)); - } + /** + * 修改异步通知记录 + * + * @param payNotifyRecord 异步通知记录 + * @return R + */ + @SysLog("修改异步通知记录") + @PutMapping + @PreAuthorize("@pms.hasPermission('pay_paynotifyrecord_edit')") + public R updateById(@RequestBody PayNotifyRecord payNotifyRecord) { + return R.ok(payNotifyRecordService.updateById(payNotifyRecord)); + } - /** - * 通过id删除异步通知记录 - * @param id id - * @return R - */ - @SysLog("删除异步通知记录" ) - @DeleteMapping("/{id}" ) - @PreAuthorize("@pms.hasPermission('pay_paynotifyrecord_del')" ) - public R removeById(@PathVariable Long id) { - return R.ok(payNotifyRecordService.removeById(id)); - } + /** + * 通过id删除异步通知记录 + * + * @param id id + * @return R + */ + @SysLog("删除异步通知记录") + @DeleteMapping("/{id}") + @PreAuthorize("@pms.hasPermission('pay_paynotifyrecord_del')") + public R removeById(@PathVariable Long id) { + return R.ok(payNotifyRecordService.removeById(id)); + } + + /** + * 渠道异步回调 + * + * @param request 渠道请求 + * @return + */ + @Inner(false) + @SneakyThrows + @PostMapping("/ali/callbak") + public void aliCallbak(HttpServletRequest request, HttpServletResponse response) { + // 解析回调信息 + Map params = AliPayApi.toMap(request); + // 判断10秒内是否已经回调处理 + if (!duplicateCheckerHandler.isDuplicate(params.get(PayConstants.OUT_TRADE_NO))) { + log.warn("支付宝订单重复回调 {} 不做处理", params); + payNotifyRecordService.saveAliRecord(params, ""); + return; + } + String result = payNotifyRecordService.aliCallbak(params); + payNotifyRecordService.saveAliRecord(params, result); + //写出处理结果 + response.getWriter().print(result); + } + + @Inner(false) + @SneakyThrows + @ResponseBody + @PostMapping("/wx/callbak") + public String wxCallbak(HttpServletRequest request, HttpServletResponse response) { + String xmlMsg = HttpKit.readData(request); + log.info("微信订单回调信息:{}", xmlMsg); + Map params = PaymentKit.xmlToMap(xmlMsg); + + // 判断10秒内是否已经回调处理 + if (!duplicateCheckerHandler.isDuplicate(params.get(PayConstants.OUT_TRADE_NO))) { + log.warn("微信订单重复回调 {} 不做处理", params); + payNotifyRecordService.saveAliRecord(params, ""); + return null; + } + String result = payNotifyRecordService.wxCallbak(params); + payNotifyRecordService.saveAliRecord(params, result); + return result; + } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayTradeOrderController.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayTradeOrderController.java index a51cdf3fd..56f795438 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayTradeOrderController.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/controller/PayTradeOrderController.java @@ -23,11 +23,9 @@ import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; import com.pig4cloud.pigx.pay.service.PayTradeOrderService; -import org.springframework.security.access.prepost.PreAuthorize; import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; import lombok.AllArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -39,8 +37,8 @@ import org.springframework.web.bind.annotation.*; */ @RestController @AllArgsConstructor -@RequestMapping("/paytradeorder" ) -@Api(value = "paytradeorder", tags = "paytradeorder管理") +@RequestMapping("/order" ) +@Api(value = "order", tags = "订单") public class PayTradeOrderController { private final PayTradeOrderService payTradeOrderService; diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java index 323021f3f..35c334e31 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayChannel.java @@ -45,6 +45,10 @@ public class PayChannel extends Model { */ @TableId private Integer id; + /** + * 应用ID + */ + private String appId; /** * 渠道ID */ @@ -57,10 +61,6 @@ public class PayChannel extends Model { * 渠道商户ID */ private String channelMchId; - /** - * 内部商户ID - */ - private String mchId; /** * 渠道状态 */ diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayGoodsOrder.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayGoodsOrder.java index 947a5ba82..761407492 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayGoodsOrder.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayGoodsOrder.java @@ -56,7 +56,7 @@ public class PayGoodsOrder extends Model { /** * 金额,单位分 */ - private Long amount; + private String amount; /** * 用户ID */ diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayRefundOrder.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayRefundOrder.java index cae0c0ec3..c147fd5b6 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayRefundOrder.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayRefundOrder.java @@ -66,9 +66,9 @@ public class PayRefundOrder extends Model { */ private String channelId; /** - * 支付金额,单位分 + * 支付金额,单位元 */ - private Long payAmount; + private String payAmount; /** * 退款金额,单位分 */ diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayTradeOrder.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayTradeOrder.java index 079c39696..718a5d5da 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayTradeOrder.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/entity/PayTradeOrder.java @@ -51,9 +51,9 @@ public class PayTradeOrder extends Model { */ private String channelId; /** - * 支付金额,单位分 + * 支付金额,单位元 */ - private Long amount; + private String amount; /** * 三位货币代码,人民币:cny */ diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AbstractPayOrderHandler.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AbstractPayOrderHandler.java index b5cbc30e8..feb3a0677 100644 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AbstractPayOrderHandler.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AbstractPayOrderHandler.java @@ -3,7 +3,7 @@ package com.pig4cloud.pigx.pay.handler; import com.pig4cloud.common.sequence.sequence.Sequence; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; -import com.pig4cloud.pigx.pay.service.PayGoodsOrderService; +import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper; import com.pig4cloud.pigx.pay.utils.OrderStatusEnum; import org.springframework.beans.factory.annotation.Autowired; @@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; */ public abstract class AbstractPayOrderHandler implements PayOrderHandler { @Autowired - private PayGoodsOrderService goodsOrderService; + private PayGoodsOrderMapper goodsOrderMapper; @Autowired private Sequence paySequence; @@ -28,17 +28,20 @@ public abstract class AbstractPayOrderHandler implements PayOrderHandler { public void createGoodsOrder(PayGoodsOrder goodsOrder) { goodsOrder.setPayOrderId(paySequence.nextNo()); goodsOrder.setStatus(OrderStatusEnum.INIT.getStatus()); - goodsOrderService.save(goodsOrder); + goodsOrderMapper.insert(goodsOrder); } /** * 调用入口 + * + * @return */ @Override - public void handle(PayGoodsOrder payGoodsOrder) { + public Object handle(PayGoodsOrder payGoodsOrder) { createGoodsOrder(payGoodsOrder); PayTradeOrder tradeOrder = createTradeOrder(payGoodsOrder); - pay(payGoodsOrder, tradeOrder); + Object result = pay(payGoodsOrder, tradeOrder); updateOrder(payGoodsOrder, tradeOrder); + return result; } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AlipayWapPayOrderHandler.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AlipayWapPayOrderHandler.java index de93897fd..2767d6f8c 100644 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AlipayWapPayOrderHandler.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/AlipayWapPayOrderHandler.java @@ -1,15 +1,20 @@ package com.pig4cloud.pigx.pay.handler; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.URLUtil; import cn.hutool.extra.servlet.ServletUtil; import com.alipay.api.AlipayApiException; import com.alipay.api.domain.AlipayTradeWapPayModel; import com.jpay.alipay.AliPayApi; +import com.jpay.alipay.AliPayApiConfigKit; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; +import com.pig4cloud.pigx.pay.config.PayCommonProperties; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; -import com.pig4cloud.pigx.pay.service.PayGoodsOrderService; -import com.pig4cloud.pigx.pay.service.PayTradeOrderService; +import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper; +import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper; 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; @@ -28,8 +33,9 @@ import java.io.IOException; @Service("ALIPAY_WAP") @AllArgsConstructor public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler { - private final PayTradeOrderService tradeOrderService; - private final PayGoodsOrderService goodsOrderService; + private final PayCommonProperties payCommonProperties; + private final PayTradeOrderMapper tradeOrderMapper; + private final PayGoodsOrderMapper goodsOrderMapper; private final HttpServletRequest request; private final HttpServletResponse response; @@ -44,14 +50,14 @@ public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler { PayTradeOrder tradeOrder = new PayTradeOrder(); tradeOrder.setOrderId(goodsOrder.getPayOrderId()); tradeOrder.setAmount(goodsOrder.getAmount()); - tradeOrder.setChannelId("ALIPAY_WAP"); - tradeOrder.setChannelMchId("1517584931"); + tradeOrder.setChannelId(PayChannelNameEnum.ALIPAY_WAP.getName()); + tradeOrder.setChannelMchId(AliPayApiConfigKit.getAliPayApiConfig().getAppId()); tradeOrder.setClientIp(ServletUtil.getClientIP(request)); tradeOrder.setCurrency("cny"); - tradeOrder.setExpireTime(30L); + tradeOrder.setExpireTime(Long.parseLong(payCommonProperties.getAliPayConfig().getReturnUrl())); tradeOrder.setStatus(OrderStatusEnum.INIT.getStatus()); - tradeOrder.setBody("测试商品"); - tradeOrderService.save(tradeOrder); + tradeOrder.setBody(goodsOrder.getGoodsName()); + tradeOrderMapper.insert(tradeOrder); return tradeOrder; } @@ -67,12 +73,15 @@ public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler { model.setBody(tradeOrder.getBody()); model.setSubject(tradeOrder.getBody()); model.setOutTradeNo(tradeOrder.getOrderId()); - model.setTimeoutExpress(tradeOrder.getExpireTime() + "m"); - model.setTotalAmount(String.valueOf(tradeOrder.getAmount())); - model.setPassbackParams(String.valueOf(TenantContextHolder.getTenantId())); + model.setTimeoutExpress(payCommonProperties.getAliPayConfig().getExpireTime() + "m"); + + //分转成元 并且保留两位 + model.setTotalAmount(NumberUtil.div(tradeOrder.getAmount(), "100", 2).toString()); model.setProductCode(goodsOrder.getGoodsId()); + model.setPassbackParams(URLUtil.encode(String.format("tenant=%s", TenantContextHolder.getTenantId()))); try { - AliPayApi.wapPay(response, model, "http://www.baidu.com", "/alipay/notify_url"); + AliPayApi.wapPay(response, model, payCommonProperties.getAliPayConfig().getReturnUrl() + , payCommonProperties.getAliPayConfig().getNotifyUrl()); } catch (AlipayApiException e) { log.warn("支付宝支付失败 {} {}", e.getErrCode(), e.getErrMsg()); tradeOrder.setErrMsg(e.getErrMsg()); @@ -96,7 +105,7 @@ public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler { */ @Override public void updateOrder(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder) { - tradeOrderService.updateById(tradeOrder); - goodsOrderService.updateById(goodsOrder); + tradeOrderMapper.updateById(tradeOrder); + goodsOrderMapper.updateById(goodsOrder); } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/MessageDuplicateCheckerHandler.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/MessageDuplicateCheckerHandler.java new file mode 100644 index 000000000..8dae7d7ce --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/MessageDuplicateCheckerHandler.java @@ -0,0 +1,17 @@ +package com.pig4cloud.pigx.pay.handler; + +/** + * @author lengleng + * @date 2019-06-14 + *

+ * 消息去重 + */ +public interface MessageDuplicateCheckerHandler { + /** + * 判断回调消息是否重复. + * + * @param messageId messageId需要根据上面讲的方式构造 + * @return 如果是重复消息,返回false,否则返回true + */ + boolean isDuplicate(String messageId); +} diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/MessageRedisDuplicateCheckerHandler.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/MessageRedisDuplicateCheckerHandler.java new file mode 100644 index 000000000..89d2815f9 --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/MessageRedisDuplicateCheckerHandler.java @@ -0,0 +1,31 @@ +package com.pig4cloud.pigx.pay.handler; + +import lombok.AllArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.time.Duration; + +/** + * @author lengleng + * @date 2019-06-14 + *

+ * 消息去重 + */ +@Service +@AllArgsConstructor +public class MessageRedisDuplicateCheckerHandler implements MessageDuplicateCheckerHandler { + private final RedisTemplate redisTemplate; + + /** + * 判断回调消息是否重复. + * + * @param messageId messageId需要根据上面讲的方式构造 + * @return 如果是重复消息,返回false,否则返回true + */ + @Override + public boolean isDuplicate(String messageId) { + return redisTemplate.opsForValue() + .setIfAbsent(messageId, messageId, Duration.ofSeconds(10L)); + } +} diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java index 6784b0df7..ed50a7ca5 100644 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/PayOrderHandler.java @@ -33,7 +33,7 @@ public interface PayOrderHandler { * @param goodsOrder 商品订单 * @param tradeOrder 交易订单 */ - PayTradeOrder pay(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder); + Object pay(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder); /** * 更新订单信息 @@ -44,6 +44,7 @@ public interface PayOrderHandler { * 调用入口 * * @param goodsOrde 商品订单 + * @return */ - void handle(PayGoodsOrder goodsOrde); + Object handle(PayGoodsOrder goodsOrde); } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/WeChatMpPayOrderHandler.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/WeChatMpPayOrderHandler.java new file mode 100644 index 000000000..dbd18bb58 --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/handler/WeChatMpPayOrderHandler.java @@ -0,0 +1,98 @@ +package com.pig4cloud.pigx.pay.handler; + +import cn.hutool.extra.servlet.ServletUtil; +import com.jpay.ext.kit.PaymentKit; +import com.jpay.weixin.api.WxPayApi; +import com.jpay.weixin.api.WxPayApiConfigKit; +import com.pig4cloud.pigx.pay.config.PayCommonProperties; +import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; +import com.pig4cloud.pigx.pay.entity.PayTradeOrder; +import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper; +import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper; +import com.pig4cloud.pigx.pay.utils.OrderStatusEnum; +import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * @author lengleng + * @date 2019-05-31 + *

+ * 微信公众号支付 + */ +@Slf4j +@Service("WEIXIN_MP") +public class WeChatMpPayOrderHandler extends AbstractPayOrderHandler { + @Autowired + private PayCommonProperties payCommonProperties; + @Autowired + private PayTradeOrderMapper tradeOrderMapper; + @Autowired + private PayGoodsOrderMapper goodsOrderMapper; + @Autowired + private HttpServletRequest request; + + /** + * 创建交易订单 + * + * @param goodsOrder + * @return + */ + @Override + public PayTradeOrder createTradeOrder(PayGoodsOrder goodsOrder) { + PayTradeOrder tradeOrder = new PayTradeOrder(); + tradeOrder.setOrderId(goodsOrder.getPayOrderId()); + tradeOrder.setAmount(goodsOrder.getAmount()); + tradeOrder.setChannelId(PayChannelNameEnum.WEIXIN_MP.getName()); + tradeOrder.setChannelMchId(WxPayApiConfigKit.getWxPayApiConfig().getMchId()); + tradeOrder.setClientIp(ServletUtil.getClientIP(request)); + tradeOrder.setCurrency("CNY"); + tradeOrder.setStatus(OrderStatusEnum.INIT.getStatus()); + tradeOrder.setBody(goodsOrder.getGoodsName()); + tradeOrderMapper.insert(tradeOrder); + return tradeOrder; + } + + /** + * 调起渠道支付 + * + * @param goodsOrder 商品订单 + * @param tradeOrder 交易订单 + */ + @Override + public Object pay(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder) { + String ip = ServletUtil.getClientIP(request); + Map params = WxPayApiConfigKit.getWxPayApiConfig() + .setAttach(goodsOrder.getGoodsId()) + .setBody(goodsOrder.getGoodsName()) + .setSpbillCreateIp(ip) + .setTotalFee(goodsOrder.getAmount()) + .setOpenId(goodsOrder.getUserId()) + .setTradeType(WxPayApi.TradeType.JSAPI) + .setNotifyUrl(payCommonProperties.getWxPayConfig().getNotifyUrl()) + .setOutTradeNo(tradeOrder.getOrderId()) + .build(); + + String xmlResult = WxPayApi.pushOrder(false, params); + log.info(xmlResult); + Map resultMap = PaymentKit.xmlToMap(xmlResult); + String prepayId = resultMap.get("prepay_id"); + return PaymentKit.prepayIdCreateSign(prepayId); + } + + /** + * 更新订单信息 + * + * @param goodsOrder 商品订单 + * @param tradeOrder 交易订单 + */ + @Override + public void updateOrder(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder) { + tradeOrderMapper.updateById(tradeOrder); + goodsOrderMapper.updateById(goodsOrder); + } +} diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayGoodsOrderService.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayGoodsOrderService.java index 97883e30b..e57506654 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayGoodsOrderService.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayGoodsOrderService.java @@ -18,9 +18,10 @@ package com.pig4cloud.pigx.pay.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.pay.entity.PayGoodsOrder; +import java.util.Map; + /** * 商品 * @@ -32,8 +33,15 @@ public interface PayGoodsOrderService extends IService { /** * 购买商品 * - * @param amount + * @param goodsOrder goods * @return */ - R buy(Long amount); + Map buy(PayGoodsOrder goodsOrder); + + /** + * 更新订单 + * + * @param params + */ + void updateOrder(Map params); } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayNotifyRecordService.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayNotifyRecordService.java index 6daab7bc9..356e150cd 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayNotifyRecordService.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayNotifyRecordService.java @@ -20,6 +20,8 @@ package com.pig4cloud.pigx.pay.service; import com.baomidou.mybatisplus.extension.service.IService; import com.pig4cloud.pigx.pay.entity.PayNotifyRecord; +import java.util.Map; + /** * 异步通知记录 * @@ -28,4 +30,27 @@ import com.pig4cloud.pigx.pay.entity.PayNotifyRecord; */ public interface PayNotifyRecordService extends IService { + /** + * 处理支付宝渠道回调 + * + * @param params + * @return + */ + String aliCallbak(Map params); + + /** + * 保存支付宝回调结果 + * + * @param params + * @param result + */ + void saveAliRecord(Map params, String result); + + /** + * 处理微信渠道回调 + * + * @param params + * @return + */ + String wxCallbak(Map params); } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayTradeOrderService.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayTradeOrderService.java index eab0776a2..0756d0bf4 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayTradeOrderService.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/PayTradeOrderService.java @@ -20,6 +20,8 @@ package com.pig4cloud.pigx.pay.service; import com.baomidou.mybatisplus.extension.service.IService; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; +import java.util.Map; + /** * 支付 * @@ -28,4 +30,10 @@ import com.pig4cloud.pigx.pay.entity.PayTradeOrder; */ public interface PayTradeOrderService extends IService { + /** + * 更新支付订单 + * + * @param params + */ + void updateOrder(Map params); } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayChannelServiceImpl.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayChannelServiceImpl.java index c29ccbd34..b8231e00e 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayChannelServiceImpl.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayChannelServiceImpl.java @@ -17,7 +17,6 @@ package com.pig4cloud.pigx.pay.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.pig4cloud.common.sequence.sequence.Sequence; import com.pig4cloud.pigx.pay.entity.PayChannel; import com.pig4cloud.pigx.pay.mapper.PayChannelMapper; import com.pig4cloud.pigx.pay.service.PayChannelService; @@ -33,7 +32,6 @@ import org.springframework.stereotype.Service; @Service @AllArgsConstructor public class PayChannelServiceImpl extends ServiceImpl implements PayChannelService { - private final Sequence channelSequence; /** * 新增支付渠道 @@ -43,7 +41,6 @@ public class PayChannelServiceImpl extends ServiceImpl implements PayGoodsOrderService { - private final PayTradeOrderService tradeOrderService; - private static final String WX = "MicroMessenger"; + private final Map orderHandlerMap; private final HttpServletRequest request; - private final HttpServletResponse response; - private final Sequence paySequence; /** - * 购买商品 - *

- * 1、 新增商品订单 - * 2、 根据UA 去下单 - * 3、构建支付订单 + * 下单购买 * - * @param amount + * @param goodsOrder * @return */ @Override @Transactional(rollbackFor = Exception.class) - public R buy(Long amount) { - return null; + public Map buy(PayGoodsOrder goodsOrder) { + String ua = request.getHeader(HttpHeaders.USER_AGENT); + Enum channel = PayChannelNameEnum.getChannel(ua); + PayOrderHandler orderHandler = orderHandlerMap.get(channel.name()); + goodsOrder.setGoodsName("测试产品"); + goodsOrder.setGoodsId("10001"); + Object params = orderHandler.handle(goodsOrder); + + Map result = new HashMap<>(4); + result.put("channel", channel.name()); + result.put("goods", goodsOrder); + result.put("params", params); + return result; } + /** + * 异步更新商品订单 + * + * @param params + */ + @Async + @Override + @Transactional(rollbackFor = Exception.class) + public void updateOrder(Map params) { + PayGoodsOrder goodsOrder = new PayGoodsOrder(); + Integer tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get("trade_status")).getStatus(); + goodsOrder.setStatus(tradeStatus); + this.baseMapper.update(goodsOrder, Wrappers.lambdaQuery() + .eq(PayGoodsOrder::getPayOrderId, params. + get(PayConstants.OUT_TRADE_NO))); + } + + } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayNotifyRecordServiceImpl.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayNotifyRecordServiceImpl.java index 75cc6e05e..3be8fada2 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayNotifyRecordServiceImpl.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayNotifyRecordServiceImpl.java @@ -16,19 +16,126 @@ */ package com.pig4cloud.pigx.pay.service.impl; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.alipay.api.AlipayApiException; +import com.alipay.api.internal.util.AlipaySignature; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.jpay.alipay.AliPayApiConfig; +import com.jpay.alipay.AliPayApiConfigKit; +import com.jpay.ext.kit.PaymentKit; +import com.jpay.weixin.api.WxPayApiConfigKit; import com.pig4cloud.pigx.pay.entity.PayNotifyRecord; import com.pig4cloud.pigx.pay.mapper.PayNotifyRecordMapper; +import com.pig4cloud.pigx.pay.service.PayGoodsOrderService; import com.pig4cloud.pigx.pay.service.PayNotifyRecordService; +import com.pig4cloud.pigx.pay.service.PayTradeOrderService; +import com.pig4cloud.pigx.pay.utils.TradeStatusEnum; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import java.util.HashMap; +import java.util.Map; + /** * 异步通知记录 * * @author lengleng * @date 2019-05-28 23:57:23 */ +@Slf4j @Service +@AllArgsConstructor public class PayNotifyRecordServiceImpl extends ServiceImpl implements PayNotifyRecordService { + private final PayTradeOrderService tradeOrderService; + private final PayGoodsOrderService goodsOrderService; + + /** + * 处理微信渠道回调 + * + * @param params + * @return + */ + @Override + public String wxCallbak(Map params) { + if (!PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())) { + log.warn("微信支付回调验签失败", params); + return null; + } + + params.put("trade_status", TradeStatusEnum.TRADE_SUCCESS.getDescription()); + + goodsOrderService.updateOrder(params); + tradeOrderService.updateOrder(params); + + Map xml = new HashMap<>(4); + xml.put("return_code", "SUCCESS"); + xml.put("return_msg", "OK"); + return PaymentKit.toXml(xml); + } + + /** + * 处理渠道回调 + * + * @param params + * @return + */ + @Override + public String aliCallbak(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 "failure"; + } + + AliPayApiConfig apiConfig = AliPayApiConfigKit.getApiConfig(appId); + if (apiConfig == null) { + log.warn("支付宝回调报文 appid 不合法 {}", callReq); + return "failure"; + } + + boolean verifyResult; + try { + verifyResult = AlipaySignature.rsaCheckV1(params, apiConfig.getAlipayPublicKey(), CharsetUtil.UTF_8, + "RSA2"); + } catch (AlipayApiException e) { + log.warn("验签异常 {} {}", e.getErrCode(), e.getErrMsg()); + return "failure"; + } + + if (!verifyResult) { + log.warn("支付宝回调验签:{}", MapUtil.join(params, StrUtil.DASHED, StrUtil.DASHED)); + return "failure"; + } + + goodsOrderService.updateOrder(params); + tradeOrderService.updateOrder(params); + return "success"; + } + + /** + * 保存支付宝回调结果 + * + * @param params + * @param result + */ + @Async + @Override + public void saveAliRecord(Map params, String result) { + PayNotifyRecord record = new PayNotifyRecord(); + String notifyId = params.get("notify_id"); + record.setNotifyId(notifyId); + String orderNo = params.get("out_trade_no"); + record.setOrderNo(orderNo); + record.setRequest(MapUtil.join(params, StrUtil.DASHED, StrUtil.DASHED)); + record.setResponse(result); + this.baseMapper.insert(record); + } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayTradeOrderServiceImpl.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayTradeOrderServiceImpl.java index 9b9042c79..3997031f4 100755 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayTradeOrderServiceImpl.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/service/impl/PayTradeOrderServiceImpl.java @@ -20,7 +20,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.pig4cloud.pigx.pay.entity.PayTradeOrder; import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper; import com.pig4cloud.pigx.pay.service.PayTradeOrderService; +import com.pig4cloud.pigx.pay.utils.PayConstants; +import com.pig4cloud.pigx.pay.utils.TradeStatusEnum; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; /** * 支付 @@ -31,4 +37,18 @@ import org.springframework.stereotype.Service; @Service public class PayTradeOrderServiceImpl extends ServiceImpl implements PayTradeOrderService { + /** + * 更新支付订单 + * + * @param params + */ + @Async + @Override + @Transactional(rollbackFor = Exception.class) + public void updateOrder(Map params) { + PayTradeOrder payTradeOrder = this.baseMapper.selectById(params.get(PayConstants.OUT_TRADE_NO)); + payTradeOrder.setStatus(TradeStatusEnum.TRADE_SUCCESS.getStatus()); + payTradeOrder.setChannelOrderNo(params.get("trade_no")); + this.baseMapper.updateById(payTradeOrder); + } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/PayChannelNameEnum.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/PayChannelNameEnum.java index 35ecfdeb2..e4ae636dc 100644 --- a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/PayChannelNameEnum.java +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/PayChannelNameEnum.java @@ -9,30 +9,46 @@ import lombok.Getter; *

* 支付渠道名称 */ -@Getter @AllArgsConstructor public enum PayChannelNameEnum { /** - * 支付宝 + * 支付宝wap支付 */ - ALIPAY("alipay", "支付宝"), + ALIPAY_WAP("ALIPAY_WAP", "支付宝手机支付"), /** - * 微信支付 + * 微信H5支付 */ - WXPAY("wxpay", "微信支付"), + WEIXIN_WAP("WEIXIN_WAP", "微信H5支付"), /** - * 微信服务商支付 + * 微信公众号支付 */ - WESUBPAY("wxsubpay", "微信服务商支付"); + WEIXIN_MP("WEIXIN_MP", "微信公众号支付"); /** * 名称 */ + @Getter private String name; /** * 描述 */ private String description; + + /** + * 通过ua 判断所属渠道 + * + * @param ua 浏览器类型 + * @return + */ + public static Enum getChannel(String ua) { + if (ua.contains(PayConstants.ALIPAY)) { + return PayChannelNameEnum.ALIPAY_WAP; + } else if (ua.contains(PayConstants.MICRO_MESSENGER)) { + return PayChannelNameEnum.WEIXIN_MP; + } else { + return PayChannelNameEnum.WEIXIN_WAP; + } + } } diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/PayConstants.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/PayConstants.java new file mode 100644 index 000000000..d4dbd012d --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/PayConstants.java @@ -0,0 +1,26 @@ +package com.pig4cloud.pigx.pay.utils; + +/** + * @author lengleng + * @date 2019-06-14 + *

+ * 支付相关的常量 + */ +public interface PayConstants { + + /** + * 支付宝商户交易编号 + */ + String OUT_TRADE_NO = "out_trade_no"; + + /** + * 支付宝浏览器标志 + */ + String ALIPAY = "Alipay"; + + /** + * 微信浏览器标志 + */ + String MICRO_MESSENGER = "MicroMessenger"; + +} diff --git a/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/TradeStatusEnum.java b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/TradeStatusEnum.java new file mode 100644 index 000000000..253d68d73 --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/java/com/pig4cloud/pigx/pay/utils/TradeStatusEnum.java @@ -0,0 +1,42 @@ +package com.pig4cloud.pigx.pay.utils; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author lengleng + * @date 2019-06-14 + */ +@Getter +@AllArgsConstructor +public enum TradeStatusEnum { + /** + * 交易完成 + */ + WAIT_BUYER_PAY("TRADE_FINISHED", OrderStatusEnum.INIT.getStatus()), + + /** + * TRADE_CLOSED + */ + TRADE_CLOSED("TRADE_CLOSED", OrderStatusEnum.FAIL.getStatus()), + + /** + * TRADE_SUCCESS + */ + TRADE_SUCCESS("TRADE_SUCCESS", OrderStatusEnum.SUCCESS.getStatus()), + + /** + * 交易关闭 + */ + TRADE_FINISHED("TRADE_FINISHED", OrderStatusEnum.COMPLETE.getStatus()); + + + /** + * 描述 + */ + private String description; + /** + * 描述 + */ + private Integer status; +} diff --git a/pigx-visual/pigx-pay/src/main/resources/logback-spring.xml b/pigx-visual/pigx-pay/src/main/resources/logback-spring.xml new file mode 100644 index 000000000..964ca8735 --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/resources/logback-spring.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + ${log.path}/debug.log + + ${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz + 50MB + 30 + + + %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n + + + + + + ${log.path}/error.log + + ${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz + 50MB + 30 + + + %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n + + + ERROR + + + + + + + + + + + + + + + + + diff --git a/pigx-visual/pigx-pay/src/main/resources/mapper/PayChannelMapper.xml b/pigx-visual/pigx-pay/src/main/resources/mapper/PayChannelMapper.xml index c85d2d2a7..718a49b9f 100755 --- a/pigx-visual/pigx-pay/src/main/resources/mapper/PayChannelMapper.xml +++ b/pigx-visual/pigx-pay/src/main/resources/mapper/PayChannelMapper.xml @@ -25,10 +25,10 @@ - + - + diff --git a/pigx-visual/pigx-pay/src/main/resources/templates/pay.ftl b/pigx-visual/pigx-pay/src/main/resources/templates/pay.ftl new file mode 100644 index 000000000..ae429272d --- /dev/null +++ b/pigx-visual/pigx-pay/src/main/resources/templates/pay.ftl @@ -0,0 +1,58 @@ + + + + + + Title + + + + +<#if channel == 'WEIXIN_WAP'> + 确认购买 + + + +<#if channel == 'WEIXIN_MP'> + + +<#if channel == 'WEIXIN_WAP'> + + diff --git a/pom.xml b/pom.xml index 60e8432ef..4395ab56d 100644 --- a/pom.xml +++ b/pom.xml @@ -35,14 +35,15 @@ lengleng wangiegie@gmail.com - - leader - + + + lisb + 121838632@qq.com - 2.1.5.RELEASE + 2.1.6.RELEASE Greenwich.SR1 Cairo-SR8 UTF-8 @@ -50,7 +51,7 @@ 1.8 2.1.5 1.1.2-beta5 - 4.5.10 + 4.5.12 0.0.9 2.9.2 1.9.4