Commit 65220cfeeffdbd45574f880099a0d53a8863acf9
1 parent
07f54ce2
upgrade after testing
Showing
33 changed files
with
575 additions
and
127 deletions
cashier-boss/src/main/java/com/diligrp/cashier/boss/Constants.java
| @@ -3,6 +3,8 @@ package com.diligrp.cashier.boss; | @@ -3,6 +3,8 @@ package com.diligrp.cashier.boss; | ||
| 3 | public final class Constants { | 3 | public final class Constants { |
| 4 | // 商户信息缓存Key | 4 | // 商户信息缓存Key |
| 5 | public static final String MERCHANT_REDIS_KEY = "cashier:merchant:%s"; | 5 | public static final String MERCHANT_REDIS_KEY = "cashier:merchant:%s"; |
| 6 | + // 商户信息过期时长-单位秒 - 1个小时 | ||
| 7 | + public static final int MERCHANT_TIMEOUT_SECONDS = 60 * 60; | ||
| 6 | // TOKEN信息缓存Key | 8 | // TOKEN信息缓存Key |
| 7 | public static final String TOKEN_REDIS_KEY = "cashier:token:%s"; | 9 | public static final String TOKEN_REDIS_KEY = "cashier:token:%s"; |
| 8 | // TOKEN参数名称 | 10 | // TOKEN参数名称 |
| @@ -11,8 +13,8 @@ public final class Constants { | @@ -11,8 +13,8 @@ public final class Constants { | ||
| 11 | public static final String TOKEN_SIGN_ALGORITHM = "HmacSHA256"; | 13 | public static final String TOKEN_SIGN_ALGORITHM = "HmacSHA256"; |
| 12 | // TOKEN的签名长度 | 14 | // TOKEN的签名长度 |
| 13 | public static final int TOKEN_SIGN_LENGTH = 8; | 15 | public static final int TOKEN_SIGN_LENGTH = 8; |
| 14 | - // TOKEN过期时长,单位秒 | ||
| 15 | - public static final long TOKEN_TIMEOUT_SECONDS = 60; | 16 | + // TOKEN过期时长,单位秒 - 两分钟 |
| 17 | + public static final long TOKEN_TIMEOUT_SECONDS = 120; | ||
| 16 | 18 | ||
| 17 | public final static String CONTENT_TYPE = "application/json;charset=UTF-8"; | 19 | public final static String CONTENT_TYPE = "application/json;charset=UTF-8"; |
| 18 | 20 |
cashier-boss/src/main/java/com/diligrp/cashier/boss/controller/CashierDeskController.java
| @@ -35,6 +35,7 @@ public class CashierDeskController { | @@ -35,6 +35,7 @@ public class CashierDeskController { | ||
| 35 | AssertUtils.notNull(request.getAmount(), "amount missed"); | 35 | AssertUtils.notNull(request.getAmount(), "amount missed"); |
| 36 | AssertUtils.isTrue(request.getAmount() > 0, "Invalid amount"); | 36 | AssertUtils.isTrue(request.getAmount() > 0, "Invalid amount"); |
| 37 | AssertUtils.notEmpty(request.getOutTradeNo(), "outTradeNo missed"); | 37 | AssertUtils.notEmpty(request.getOutTradeNo(), "outTradeNo missed"); |
| 38 | + AssertUtils.notEmpty(request.getRedirectUrl(), "redirectUrl missed"); | ||
| 38 | 39 | ||
| 39 | CashierOrder cashierOrder = CashierOrderConverter.INSTANCE.convert(request); | 40 | CashierOrder cashierOrder = CashierOrderConverter.INSTANCE.convert(request); |
| 40 | Merchant merchant = merchantService.loadCashierMerchant(request.getMchId()); | 41 | Merchant merchant = merchantService.loadCashierMerchant(request.getMchId()); |
cashier-boss/src/main/java/com/diligrp/cashier/boss/domain/CashierOrderDTO.java
| @@ -17,6 +17,8 @@ public class CashierOrderDTO { | @@ -17,6 +17,8 @@ public class CashierOrderDTO { | ||
| 17 | private String outTradeNo; | 17 | private String outTradeNo; |
| 18 | // 回调地址 | 18 | // 回调地址 |
| 19 | private String notifyUrl; | 19 | private String notifyUrl; |
| 20 | + // 页面回调地址 | ||
| 21 | + private String redirectUrl; | ||
| 20 | // 交易描述 | 22 | // 交易描述 |
| 21 | private String description; | 23 | private String description; |
| 22 | // 附加数据 | 24 | // 附加数据 |
| @@ -86,6 +88,14 @@ public class CashierOrderDTO { | @@ -86,6 +88,14 @@ public class CashierOrderDTO { | ||
| 86 | this.notifyUrl = notifyUrl; | 88 | this.notifyUrl = notifyUrl; |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 91 | + public String getRedirectUrl() { | ||
| 92 | + return redirectUrl; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + public void setRedirectUrl(String redirectUrl) { | ||
| 96 | + this.redirectUrl = redirectUrl; | ||
| 97 | + } | ||
| 98 | + | ||
| 89 | public String getDescription() { | 99 | public String getDescription() { |
| 90 | return description; | 100 | return description; |
| 91 | } | 101 | } |
cashier-boss/src/main/java/com/diligrp/cashier/boss/domain/CashierOrderToken.java
| @@ -21,6 +21,8 @@ public class CashierOrderToken { | @@ -21,6 +21,8 @@ public class CashierOrderToken { | ||
| 21 | private Integer cashierType; | 21 | private Integer cashierType; |
| 22 | // 业务系统用户标识 | 22 | // 业务系统用户标识 |
| 23 | private String userId; | 23 | private String userId; |
| 24 | + // 页面回调地址 | ||
| 25 | + private String redirectUrl; | ||
| 24 | 26 | ||
| 25 | public static String encode(Long tokenId, SecretKeySpec secretKey) { | 27 | public static String encode(Long tokenId, SecretKeySpec secretKey) { |
| 26 | try { | 28 | try { |
| @@ -70,11 +72,12 @@ public class CashierOrderToken { | @@ -70,11 +72,12 @@ public class CashierOrderToken { | ||
| 70 | public CashierOrderToken() { | 72 | public CashierOrderToken() { |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | - public CashierOrderToken(Long mchId, String tradeId, Integer cashierType, String userId) { | 75 | + public CashierOrderToken(Long mchId, String tradeId, Integer cashierType, String userId, String redirectUrl) { |
| 74 | this.mchId = mchId; | 76 | this.mchId = mchId; |
| 75 | this.tradeId = tradeId; | 77 | this.tradeId = tradeId; |
| 76 | this.cashierType = cashierType; | 78 | this.cashierType = cashierType; |
| 77 | this.userId = userId; | 79 | this.userId = userId; |
| 80 | + this.redirectUrl = redirectUrl; | ||
| 78 | } | 81 | } |
| 79 | 82 | ||
| 80 | public Long getMchId() { | 83 | public Long getMchId() { |
| @@ -109,6 +112,14 @@ public class CashierOrderToken { | @@ -109,6 +112,14 @@ public class CashierOrderToken { | ||
| 109 | this.userId = userId; | 112 | this.userId = userId; |
| 110 | } | 113 | } |
| 111 | 114 | ||
| 115 | + public String getRedirectUrl() { | ||
| 116 | + return redirectUrl; | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + public void setRedirectUrl(String redirectUrl) { | ||
| 120 | + this.redirectUrl = redirectUrl; | ||
| 121 | + } | ||
| 122 | + | ||
| 112 | @Override | 123 | @Override |
| 113 | public String toString() { | 124 | public String toString() { |
| 114 | return JsonUtils.toJsonString(this); | 125 | return JsonUtils.toJsonString(this); |
cashier-boss/src/main/java/com/diligrp/cashier/boss/domain/CashierOrderInfo.java renamed to cashier-boss/src/main/java/com/diligrp/cashier/boss/domain/CashierOrderVO.java
| 1 | package com.diligrp.cashier.boss.domain; | 1 | package com.diligrp.cashier.boss.domain; |
| 2 | 2 | ||
| 3 | +import com.diligrp.cashier.pipeline.type.ChannelType; | ||
| 4 | + | ||
| 3 | import java.util.List; | 5 | import java.util.List; |
| 4 | 6 | ||
| 5 | -public class CashierOrderInfo { | 7 | +public class CashierOrderVO { |
| 6 | // 业务系统用户标识 | 8 | // 业务系统用户标识 |
| 7 | private final String userId; | 9 | private final String userId; |
| 10 | + // 页面回调地址 | ||
| 11 | + private final String redirectUrl; | ||
| 8 | // 支付通道 | 12 | // 支付通道 |
| 9 | private final List<PaymentPipeline> pipelines; | 13 | private final List<PaymentPipeline> pipelines; |
| 10 | 14 | ||
| 11 | - public CashierOrderInfo(String userId, List<PaymentPipeline> pipelines) { | 15 | + public CashierOrderVO(String userId, String redirectUrl, List<PaymentPipeline> pipelines) { |
| 12 | this.userId = userId; | 16 | this.userId = userId; |
| 17 | + this.redirectUrl = redirectUrl; | ||
| 13 | this.pipelines = pipelines; | 18 | this.pipelines = pipelines; |
| 14 | } | 19 | } |
| 15 | 20 | ||
| @@ -17,6 +22,10 @@ public class CashierOrderInfo { | @@ -17,6 +22,10 @@ public class CashierOrderInfo { | ||
| 17 | return userId; | 22 | return userId; |
| 18 | } | 23 | } |
| 19 | 24 | ||
| 25 | + public String getRedirectUrl() { | ||
| 26 | + return redirectUrl; | ||
| 27 | + } | ||
| 28 | + | ||
| 20 | public List<PaymentPipeline> getPipelines() { | 29 | public List<PaymentPipeline> getPipelines() { |
| 21 | return pipelines; | 30 | return pipelines; |
| 22 | } | 31 | } |
| @@ -27,9 +36,12 @@ public class CashierOrderInfo { | @@ -27,9 +36,12 @@ public class CashierOrderInfo { | ||
| 27 | // 支付渠道 | 36 | // 支付渠道 |
| 28 | private final Integer channelId; | 37 | private final Integer channelId; |
| 29 | 38 | ||
| 30 | - public PaymentPipeline(Long pipelineId, Integer channelId) { | 39 | + private final String channelName; |
| 40 | + | ||
| 41 | + public PaymentPipeline(Long pipelineId, ChannelType channelType) { | ||
| 31 | this.pipelineId = pipelineId; | 42 | this.pipelineId = pipelineId; |
| 32 | - this.channelId = channelId; | 43 | + this.channelId = channelType.getCode(); |
| 44 | + this.channelName = channelType.getName(); | ||
| 33 | } | 45 | } |
| 34 | 46 | ||
| 35 | public Long getPipelineId() { | 47 | public Long getPipelineId() { |
| @@ -39,5 +51,9 @@ public class CashierOrderInfo { | @@ -39,5 +51,9 @@ public class CashierOrderInfo { | ||
| 39 | public Integer getChannelId() { | 51 | public Integer getChannelId() { |
| 40 | return channelId; | 52 | return channelId; |
| 41 | } | 53 | } |
| 54 | + | ||
| 55 | + public String getChannelName() { | ||
| 56 | + return channelName; | ||
| 57 | + } | ||
| 42 | } | 58 | } |
| 43 | } | 59 | } |
cashier-boss/src/main/java/com/diligrp/cashier/boss/service/ICashierDeskService.java
| 1 | package com.diligrp.cashier.boss.service; | 1 | package com.diligrp.cashier.boss.service; |
| 2 | 2 | ||
| 3 | -import com.diligrp.cashier.boss.domain.CashierOrderInfo; | 3 | +import com.diligrp.cashier.boss.domain.CashierOrderVO; |
| 4 | import com.diligrp.cashier.boss.domain.CashierPaymentUrl; | 4 | import com.diligrp.cashier.boss.domain.CashierPaymentUrl; |
| 5 | import com.diligrp.cashier.pipeline.domain.OnlinePaymentStatus; | 5 | import com.diligrp.cashier.pipeline.domain.OnlinePaymentStatus; |
| 6 | import com.diligrp.cashier.trade.domain.*; | 6 | import com.diligrp.cashier.trade.domain.*; |
| @@ -18,7 +18,7 @@ public interface ICashierDeskService { | @@ -18,7 +18,7 @@ public interface ICashierDeskService { | ||
| 18 | /** | 18 | /** |
| 19 | * 根据收银台TOKEN信息获取订单信息 | 19 | * 根据收银台TOKEN信息获取订单信息 |
| 20 | */ | 20 | */ |
| 21 | - CashierOrderInfo getCashierOrderByToken(String token); | 21 | + CashierOrderVO getCashierOrderByToken(String token); |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * 提交收银台支付 | 24 | * 提交收银台支付 |
cashier-boss/src/main/java/com/diligrp/cashier/boss/service/impl/CashierDeskManager.java
0 → 100644
| 1 | +package com.diligrp.cashier.boss.service.impl; | ||
| 2 | + | ||
| 3 | +import com.diligrp.cashier.boss.domain.CashierPaymentUrl; | ||
| 4 | +import com.diligrp.cashier.boss.service.ICashierDeskService; | ||
| 5 | +import com.diligrp.cashier.boss.service.IMerchantService; | ||
| 6 | +import com.diligrp.cashier.boss.util.CashierOrderConverter2; | ||
| 7 | +import com.diligrp.cashier.boss.util.OnlineRefundConverter; | ||
| 8 | +import com.diligrp.cashier.shared.spi.ICashierDeskManager; | ||
| 9 | +import com.diligrp.cashier.shared.spi.domain.CashierOrderBO; | ||
| 10 | +import com.diligrp.cashier.shared.spi.domain.CashierRefundBO; | ||
| 11 | +import com.diligrp.cashier.shared.spi.domain.PaymentUrlBO; | ||
| 12 | +import com.diligrp.cashier.shared.spi.domain.RefundResultBO; | ||
| 13 | +import com.diligrp.cashier.shared.util.AssertUtils; | ||
| 14 | +import com.diligrp.cashier.trade.domain.CashierOrder; | ||
| 15 | +import com.diligrp.cashier.trade.domain.Merchant; | ||
| 16 | +import com.diligrp.cashier.trade.domain.OnlineRefundDTO; | ||
| 17 | +import com.diligrp.cashier.trade.domain.OnlineRefundResult; | ||
| 18 | +import jakarta.annotation.Resource; | ||
| 19 | +import org.springframework.stereotype.Service; | ||
| 20 | + | ||
| 21 | +@Service("cashierDeskManager") | ||
| 22 | +public class CashierDeskManager implements ICashierDeskManager { | ||
| 23 | + | ||
| 24 | + @Resource | ||
| 25 | + private ICashierDeskService cashierDeskService; | ||
| 26 | + | ||
| 27 | + @Resource | ||
| 28 | + private IMerchantService merchantService; | ||
| 29 | + | ||
| 30 | + @Override | ||
| 31 | + public PaymentUrlBO submitOrder(CashierOrderBO request) { | ||
| 32 | + // 基本参数校验 | ||
| 33 | + AssertUtils.notNull(request.getMchId(), "mchId missed"); | ||
| 34 | + AssertUtils.notEmpty(request.getUserId(), "userId missed"); | ||
| 35 | + AssertUtils.notNull(request.getCashierType(), "cashierType missed"); | ||
| 36 | + AssertUtils.notEmpty(request.getGoods(), "goods missed"); | ||
| 37 | + AssertUtils.notNull(request.getAmount(), "amount missed"); | ||
| 38 | + AssertUtils.isTrue(request.getAmount() > 0, "Invalid amount"); | ||
| 39 | + AssertUtils.notEmpty(request.getOutTradeNo(), "outTradeNo missed"); | ||
| 40 | + AssertUtils.notEmpty(request.getRedirectUrl(), "redirectUrl missed"); | ||
| 41 | + | ||
| 42 | + CashierOrder cashierOrder = CashierOrderConverter2.INSTANCE.convert(request); | ||
| 43 | + Merchant merchant = merchantService.loadCashierMerchant(request.getMchId()); | ||
| 44 | + CashierPaymentUrl paymentUrl = cashierDeskService.doSubmit(merchant, cashierOrder); | ||
| 45 | + return new PaymentUrlBO(paymentUrl.tradeId(), paymentUrl.paymentUrl()); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + public RefundResultBO doRefund(CashierRefundBO request) { | ||
| 50 | + AssertUtils.notEmpty(request.getTradeId(), "tradeId missed"); | ||
| 51 | + AssertUtils.notNull(request.getAmount(), "amount missed"); | ||
| 52 | + AssertUtils.isTrue(request.getAmount() > 0, "Invalid amount"); | ||
| 53 | + | ||
| 54 | + OnlineRefundDTO onlineRefund = OnlineRefundConverter.INSTANCE.convert(request); | ||
| 55 | + OnlineRefundResult response = cashierDeskService.sendRefundRequest(onlineRefund); | ||
| 56 | + return new RefundResultBO(response.getRefundId(), response.getTradeId(), response.getState(), | ||
| 57 | + response.getWhen(), response.getMessage()); | ||
| 58 | + } | ||
| 59 | +} |
cashier-boss/src/main/java/com/diligrp/cashier/boss/service/impl/CashierDeskServiceImpl.java
| @@ -2,7 +2,7 @@ package com.diligrp.cashier.boss.service.impl; | @@ -2,7 +2,7 @@ package com.diligrp.cashier.boss.service.impl; | ||
| 2 | 2 | ||
| 3 | import com.diligrp.cashier.boss.CashierDeskProperties; | 3 | import com.diligrp.cashier.boss.CashierDeskProperties; |
| 4 | import com.diligrp.cashier.boss.Constants; | 4 | import com.diligrp.cashier.boss.Constants; |
| 5 | -import com.diligrp.cashier.boss.domain.CashierOrderInfo; | 5 | +import com.diligrp.cashier.boss.domain.CashierOrderVO; |
| 6 | import com.diligrp.cashier.boss.domain.CashierOrderToken; | 6 | import com.diligrp.cashier.boss.domain.CashierOrderToken; |
| 7 | import com.diligrp.cashier.boss.domain.CashierPaymentUrl; | 7 | import com.diligrp.cashier.boss.domain.CashierPaymentUrl; |
| 8 | import com.diligrp.cashier.boss.exception.BossServiceException; | 8 | import com.diligrp.cashier.boss.exception.BossServiceException; |
| @@ -53,7 +53,8 @@ public class CashierDeskServiceImpl implements ICashierDeskService { | @@ -53,7 +53,8 @@ public class CashierDeskServiceImpl implements ICashierDeskService { | ||
| 53 | public CashierPaymentUrl doSubmit(Merchant merchant, CashierOrder order) { | 53 | public CashierPaymentUrl doSubmit(Merchant merchant, CashierOrder order) { |
| 54 | String tradeId = cashierPaymentService.doSubmit(merchant, order); | 54 | String tradeId = cashierPaymentService.doSubmit(merchant, order); |
| 55 | String token = CashierOrderToken.encode(Long.valueOf(tradeId), cashierDeskProperties.getSecretKey()); | 55 | String token = CashierOrderToken.encode(Long.valueOf(tradeId), cashierDeskProperties.getSecretKey()); |
| 56 | - CashierOrderToken orderToken = new CashierOrderToken(merchant.getMchId(), tradeId, order.getType().getCode(), order.getUserId()); | 56 | + CashierOrderToken orderToken = new CashierOrderToken(merchant.getMchId(), tradeId, order.getType().getCode(), |
| 57 | + order.getUserId(), order.getRedirectUrl()); | ||
| 57 | 58 | ||
| 58 | String tokenKey = String.format(Constants.TOKEN_REDIS_KEY, token); | 59 | String tokenKey = String.format(Constants.TOKEN_REDIS_KEY, token); |
| 59 | stringRedisTemplate.opsForValue().set(tokenKey, orderToken.toString(), Constants.TOKEN_TIMEOUT_SECONDS, TimeUnit.SECONDS); | 60 | stringRedisTemplate.opsForValue().set(tokenKey, orderToken.toString(), Constants.TOKEN_TIMEOUT_SECONDS, TimeUnit.SECONDS); |
| @@ -68,12 +69,12 @@ public class CashierDeskServiceImpl implements ICashierDeskService { | @@ -68,12 +69,12 @@ public class CashierDeskServiceImpl implements ICashierDeskService { | ||
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | @Override | 71 | @Override |
| 71 | - public CashierOrderInfo getCashierOrderByToken(String token) { | 72 | + public CashierOrderVO getCashierOrderByToken(String token) { |
| 72 | CashierOrderToken.decode(token, cashierDeskProperties.getSecretKey()); | 73 | CashierOrderToken.decode(token, cashierDeskProperties.getSecretKey()); |
| 73 | String tokenKey = String.format(Constants.TOKEN_REDIS_KEY, token); | 74 | String tokenKey = String.format(Constants.TOKEN_REDIS_KEY, token); |
| 74 | String payload = stringRedisTemplate.opsForValue().get(tokenKey); | 75 | String payload = stringRedisTemplate.opsForValue().get(tokenKey); |
| 75 | if (ObjectUtils.isEmpty(payload)) { | 76 | if (ObjectUtils.isEmpty(payload)) { |
| 76 | - throw new BossServiceException(ErrorCode.ILLEGAL_ARGUMENT_ERROR, "收银台订单超时过期,不能支付"); | 77 | + throw new BossServiceException(ErrorCode.ILLEGAL_ARGUMENT_ERROR, "TOKEN超时过期,不能完成支付"); |
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | CashierOrderToken orderToken = CashierOrderToken.decodeCashierOrder(payload); | 80 | CashierOrderToken orderToken = CashierOrderToken.decodeCashierOrder(payload); |
| @@ -85,9 +86,9 @@ public class CashierDeskServiceImpl implements ICashierDeskService { | @@ -85,9 +86,9 @@ public class CashierDeskServiceImpl implements ICashierDeskService { | ||
| 85 | if (pipelines.isEmpty()) { | 86 | if (pipelines.isEmpty()) { |
| 86 | throw new BossServiceException(ErrorCode.ILLEGAL_ARGUMENT_ERROR, "商户无可用的支付通道"); | 87 | throw new BossServiceException(ErrorCode.ILLEGAL_ARGUMENT_ERROR, "商户无可用的支付通道"); |
| 87 | } | 88 | } |
| 88 | - List<CashierOrderInfo.PaymentPipeline> pipelineList = pipelines.stream().map(pipeline -> | ||
| 89 | - new CashierOrderInfo.PaymentPipeline(pipeline.pipelineId(), pipeline.supportedChannel().getCode())).toList(); | ||
| 90 | - return new CashierOrderInfo(orderToken.getUserId(), pipelineList); | 89 | + List<CashierOrderVO.PaymentPipeline> pipelineList = pipelines.stream().map(pipeline -> |
| 90 | + new CashierOrderVO.PaymentPipeline(pipeline.pipelineId(), pipeline.supportedChannel())).toList(); | ||
| 91 | + return new CashierOrderVO(orderToken.getUserId(), orderToken.getRedirectUrl(), pipelineList); | ||
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | /** | 94 | /** |
cashier-boss/src/main/java/com/diligrp/cashier/boss/service/impl/MerchantServiceImpl.java
| @@ -13,6 +13,7 @@ import org.springframework.data.redis.core.StringRedisTemplate; | @@ -13,6 +13,7 @@ import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 13 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| 14 | 14 | ||
| 15 | import java.util.Objects; | 15 | import java.util.Objects; |
| 16 | +import java.util.concurrent.TimeUnit; | ||
| 16 | 17 | ||
| 17 | /** | 18 | /** |
| 18 | * 支付平台接入许可服务 | 19 | * 支付平台接入许可服务 |
| @@ -36,8 +37,8 @@ public class MerchantServiceImpl implements IMerchantService { | @@ -36,8 +37,8 @@ public class MerchantServiceImpl implements IMerchantService { | ||
| 36 | Merchant merchant = Merchant.decode(payload); | 37 | Merchant merchant = Merchant.decode(payload); |
| 37 | if (Objects.isNull(merchant)) { | 38 | if (Objects.isNull(merchant)) { |
| 38 | merchant = merchantDao.findByMchId(mchId).map(new MerchantConverter(cashierDeskProperties)::convert) | 39 | merchant = merchantDao.findByMchId(mchId).map(new MerchantConverter(cashierDeskProperties)::convert) |
| 39 | - .orElseThrow(() -> new BossServiceException(ErrorCode.OBJECT_NOT_FOUND, "商家信息未注册")); | ||
| 40 | - stringRedisTemplate.opsForValue().set(cacheKey, merchant.toString()); | 40 | + .orElseThrow(() -> new BossServiceException(ErrorCode.OBJECT_NOT_FOUND, "商户信息未注册: " + mchId)); |
| 41 | + stringRedisTemplate.opsForValue().set(cacheKey, merchant.toString(), Constants.MERCHANT_TIMEOUT_SECONDS, TimeUnit.SECONDS); | ||
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | return merchant; | 44 | return merchant; |
cashier-boss/src/main/java/com/diligrp/cashier/boss/util/CashierOrderConverter.java
| @@ -19,6 +19,7 @@ public class CashierOrderConverter implements IConverter<CashierOrderDTO, Cashie | @@ -19,6 +19,7 @@ public class CashierOrderConverter implements IConverter<CashierOrderDTO, Cashie | ||
| 19 | cashierOrder.setTimeout(cashierOrderDTO.getTimeout()); | 19 | cashierOrder.setTimeout(cashierOrderDTO.getTimeout()); |
| 20 | cashierOrder.setOutTradeNo(cashierOrderDTO.getOutTradeNo()); | 20 | cashierOrder.setOutTradeNo(cashierOrderDTO.getOutTradeNo()); |
| 21 | cashierOrder.setNotifyUrl(cashierOrderDTO.getNotifyUrl()); | 21 | cashierOrder.setNotifyUrl(cashierOrderDTO.getNotifyUrl()); |
| 22 | + cashierOrder.setRedirectUrl(cashierOrderDTO.getRedirectUrl()); | ||
| 22 | cashierOrder.setDescription(cashierOrderDTO.getDescription()); | 23 | cashierOrder.setDescription(cashierOrderDTO.getDescription()); |
| 23 | cashierOrder.setAttach(cashierOrderDTO.getAttach()); | 24 | cashierOrder.setAttach(cashierOrderDTO.getAttach()); |
| 24 | return cashierOrder; | 25 | return cashierOrder; |
cashier-boss/src/main/java/com/diligrp/cashier/boss/util/CashierOrderConverter2.java
0 → 100644
| 1 | +package com.diligrp.cashier.boss.util; | ||
| 2 | + | ||
| 3 | +import com.diligrp.cashier.pipeline.type.CashierType; | ||
| 4 | +import com.diligrp.cashier.shared.codec.IConverter; | ||
| 5 | +import com.diligrp.cashier.shared.spi.domain.CashierOrderBO; | ||
| 6 | +import com.diligrp.cashier.trade.domain.CashierOrder; | ||
| 7 | + | ||
| 8 | +public class CashierOrderConverter2 implements IConverter<CashierOrderBO, CashierOrder> { | ||
| 9 | + | ||
| 10 | + public static IConverter<CashierOrderBO, CashierOrder> INSTANCE = new CashierOrderConverter2(); | ||
| 11 | + | ||
| 12 | + @Override | ||
| 13 | + public CashierOrder convert(CashierOrderBO cashierOrderDTO) { | ||
| 14 | + CashierOrder cashierOrder = new CashierOrder(); | ||
| 15 | + cashierOrder.setUserId(cashierOrderDTO.getUserId()); | ||
| 16 | + cashierOrder.setType(CashierType.getByCode(cashierOrderDTO.getCashierType())); | ||
| 17 | + cashierOrder.setGoods(cashierOrderDTO.getGoods()); | ||
| 18 | + cashierOrder.setAmount(cashierOrderDTO.getAmount()); | ||
| 19 | + cashierOrder.setTimeout(cashierOrderDTO.getTimeout()); | ||
| 20 | + cashierOrder.setOutTradeNo(cashierOrderDTO.getOutTradeNo()); | ||
| 21 | + cashierOrder.setNotifyUrl(cashierOrderDTO.getNotifyUrl()); | ||
| 22 | + cashierOrder.setRedirectUrl(cashierOrderDTO.getRedirectUrl()); | ||
| 23 | + cashierOrder.setDescription(cashierOrderDTO.getDescription()); | ||
| 24 | + cashierOrder.setAttach(cashierOrderDTO.getAttach()); | ||
| 25 | + return cashierOrder; | ||
| 26 | + } | ||
| 27 | +} |
cashier-boss/src/main/java/com/diligrp/cashier/boss/util/OnlineRefundConverter.java
0 → 100644
| 1 | +package com.diligrp.cashier.boss.util; | ||
| 2 | + | ||
| 3 | +import com.diligrp.cashier.shared.codec.IConverter; | ||
| 4 | +import com.diligrp.cashier.shared.spi.domain.CashierRefundBO; | ||
| 5 | +import com.diligrp.cashier.trade.domain.OnlineRefundDTO; | ||
| 6 | + | ||
| 7 | +public class OnlineRefundConverter implements IConverter<CashierRefundBO, OnlineRefundDTO> { | ||
| 8 | + | ||
| 9 | + public static IConverter<CashierRefundBO, OnlineRefundDTO> INSTANCE = new OnlineRefundConverter(); | ||
| 10 | + | ||
| 11 | + @Override | ||
| 12 | + public OnlineRefundDTO convert(CashierRefundBO cashierRefund) { | ||
| 13 | + OnlineRefundDTO onlineRefund = new OnlineRefundDTO(); | ||
| 14 | + onlineRefund.setTradeId(cashierRefund.getTradeId()); | ||
| 15 | + onlineRefund.setAmount(cashierRefund.getAmount()); | ||
| 16 | + onlineRefund.setNotifyUrl(cashierRefund.getNotifyUrl()); | ||
| 17 | + onlineRefund.setDescription(cashierRefund.getDescription()); | ||
| 18 | + return onlineRefund; | ||
| 19 | + } | ||
| 20 | +} |
cashier-boss/src/main/resources/logback-spring.xml
| @@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
| 26 | </encoder> | 26 | </encoder> |
| 27 | <!-- 过滤器:只输出INFO及以上级别,减少控制台冗余 --> | 27 | <!-- 过滤器:只输出INFO及以上级别,减少控制台冗余 --> |
| 28 | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | 28 | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| 29 | - <level>INFO</level> | 29 | + <level>DEBUG</level> |
| 30 | </filter> | 30 | </filter> |
| 31 | </appender> | 31 | </appender> |
| 32 | 32 |
cashier-pipeline/src/main/java/com/diligrp/cashier/pipeline/type/ChannelType.java
| @@ -15,11 +15,11 @@ import java.util.stream.Stream; | @@ -15,11 +15,11 @@ import java.util.stream.Stream; | ||
| 15 | */ | 15 | */ |
| 16 | public enum ChannelType implements IEnumType { | 16 | public enum ChannelType implements IEnumType { |
| 17 | 17 | ||
| 18 | - WXPAY("微信渠道", 10), | 18 | + WXPAY("微信支付", 10), |
| 19 | 19 | ||
| 20 | - ALIPAY("支付宝渠道", 11), | 20 | + ALIPAY("支付宝", 11), |
| 21 | 21 | ||
| 22 | - DILIPAY("地利渠道", 19), // 地利园区卡支付 | 22 | + DILIPAY("园区卡支付", 19), |
| 23 | 23 | ||
| 24 | ICBC("工商银行", 20), | 24 | ICBC("工商银行", 20), |
| 25 | 25 |
cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/ICashierDeskManager.java
0 → 100644
| 1 | +package com.diligrp.cashier.shared.spi; | ||
| 2 | + | ||
| 3 | +import com.diligrp.cashier.shared.spi.domain.CashierOrderBO; | ||
| 4 | +import com.diligrp.cashier.shared.spi.domain.CashierRefundBO; | ||
| 5 | +import com.diligrp.cashier.shared.spi.domain.PaymentUrlBO; | ||
| 6 | +import com.diligrp.cashier.shared.spi.domain.RefundResultBO; | ||
| 7 | + | ||
| 8 | +public interface ICashierDeskManager { | ||
| 9 | + | ||
| 10 | + /** | ||
| 11 | + * 提交收银台订单 | ||
| 12 | + */ | ||
| 13 | + PaymentUrlBO submitOrder(CashierOrderBO request); | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * 交易退款 | ||
| 17 | + */ | ||
| 18 | + RefundResultBO doRefund(CashierRefundBO request); | ||
| 19 | +} |
cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/IPaymentEventListener.java
| 1 | package com.diligrp.cashier.shared.spi; | 1 | package com.diligrp.cashier.shared.spi; |
| 2 | 2 | ||
| 3 | +import com.diligrp.cashier.shared.spi.domain.PaymentResultBO; | ||
| 4 | +import com.diligrp.cashier.shared.spi.domain.RefundResultBO; | ||
| 5 | + | ||
| 3 | public interface IPaymentEventListener { | 6 | public interface IPaymentEventListener { |
| 4 | 7 | ||
| 5 | - void onEvent(PaymentEvent event); | 8 | + void onEvent(PaymentResultBO event); |
| 6 | 9 | ||
| 7 | - void onEvent(RefundEvent event); | 10 | + void onEvent(RefundResultBO event); |
| 8 | } | 11 | } |
cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/domain/CashierOrderBO.java
0 → 100644
| 1 | +package com.diligrp.cashier.shared.spi.domain; | ||
| 2 | + | ||
| 3 | +public class CashierOrderBO { | ||
| 4 | + // 接入商户 | ||
| 5 | + private Long mchId; | ||
| 6 | + // 业务系统用户标识 | ||
| 7 | + private String userId; | ||
| 8 | + // 收银台类型 - H5收银台等 | ||
| 9 | + private Integer cashierType; | ||
| 10 | + // 商品描述 | ||
| 11 | + private String goods; | ||
| 12 | + // 申请金额 | ||
| 13 | + private Long amount; | ||
| 14 | + // 超时间隔时间 - 秒 | ||
| 15 | + private Integer timeout; | ||
| 16 | + // 外部流水号 | ||
| 17 | + private String outTradeNo; | ||
| 18 | + // 回调地址 | ||
| 19 | + private String notifyUrl; | ||
| 20 | + // 页面回调地址 | ||
| 21 | + private String redirectUrl; | ||
| 22 | + // 交易描述 | ||
| 23 | + private String description; | ||
| 24 | + // 附加数据 | ||
| 25 | + private String attach; | ||
| 26 | + | ||
| 27 | + public Long getMchId() { | ||
| 28 | + return mchId; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public void setMchId(Long mchId) { | ||
| 32 | + this.mchId = mchId; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public String getUserId() { | ||
| 36 | + return userId; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + public void setUserId(String userId) { | ||
| 40 | + this.userId = userId; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public Integer getCashierType() { | ||
| 44 | + return cashierType; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public void setCashierType(Integer cashierType) { | ||
| 48 | + this.cashierType = cashierType; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + public String getGoods() { | ||
| 52 | + return goods; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public void setGoods(String goods) { | ||
| 56 | + this.goods = goods; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + public Long getAmount() { | ||
| 60 | + return amount; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + public void setAmount(Long amount) { | ||
| 64 | + this.amount = amount; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public Integer getTimeout() { | ||
| 68 | + return timeout; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + public void setTimeout(Integer timeout) { | ||
| 72 | + this.timeout = timeout; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public String getOutTradeNo() { | ||
| 76 | + return outTradeNo; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + public void setOutTradeNo(String outTradeNo) { | ||
| 80 | + this.outTradeNo = outTradeNo; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + public String getNotifyUrl() { | ||
| 84 | + return notifyUrl; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + public void setNotifyUrl(String notifyUrl) { | ||
| 88 | + this.notifyUrl = notifyUrl; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + public String getRedirectUrl() { | ||
| 92 | + return redirectUrl; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + public void setRedirectUrl(String redirectUrl) { | ||
| 96 | + this.redirectUrl = redirectUrl; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + public String getDescription() { | ||
| 100 | + return description; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + public void setDescription(String description) { | ||
| 104 | + this.description = description; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + public String getAttach() { | ||
| 108 | + return attach; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + public void setAttach(String attach) { | ||
| 112 | + this.attach = attach; | ||
| 113 | + } | ||
| 114 | +} |
cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/domain/CashierRefundBO.java
0 → 100644
| 1 | +package com.diligrp.cashier.shared.spi.domain; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 退款申请 | ||
| 5 | + */ | ||
| 6 | +public class CashierRefundBO { | ||
| 7 | + // 原支付号 | ||
| 8 | + private final String tradeId; | ||
| 9 | + // 退款金额 | ||
| 10 | + private final Long amount; | ||
| 11 | + // 回调地址 | ||
| 12 | + private final String notifyUrl; | ||
| 13 | + // 退款原因 | ||
| 14 | + private final String description; | ||
| 15 | + | ||
| 16 | + public CashierRefundBO(String tradeId, Long amount, String notifyUrl, String description) { | ||
| 17 | + this.tradeId = tradeId; | ||
| 18 | + this.amount = amount; | ||
| 19 | + this.notifyUrl = notifyUrl; | ||
| 20 | + this.description = description; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public String getTradeId() { | ||
| 24 | + return tradeId; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public Long getAmount() { | ||
| 28 | + return amount; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public String getNotifyUrl() { | ||
| 32 | + return notifyUrl; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public String getDescription() { | ||
| 36 | + return description; | ||
| 37 | + } | ||
| 38 | +} |
cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/PaymentEvent.java renamed to cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/domain/PaymentResultBO.java
| 1 | -package com.diligrp.cashier.shared.spi; | 1 | +package com.diligrp.cashier.shared.spi.domain; |
| 2 | 2 | ||
| 3 | import java.time.LocalDateTime; | 3 | import java.time.LocalDateTime; |
| 4 | 4 | ||
| 5 | -public class PaymentEvent { | 5 | +public class PaymentResultBO { |
| 6 | // 交易号 | 6 | // 交易号 |
| 7 | private final String tradeId; | 7 | private final String tradeId; |
| 8 | // 支付ID | 8 | // 支付ID |
| @@ -20,8 +20,8 @@ public class PaymentEvent { | @@ -20,8 +20,8 @@ public class PaymentEvent { | ||
| 20 | // 交易描述 | 20 | // 交易描述 |
| 21 | private final String message; | 21 | private final String message; |
| 22 | 22 | ||
| 23 | - public PaymentEvent(String tradeId, String paymentId, int state, String outTradeNo, Integer outPayType, | ||
| 24 | - String payerId, LocalDateTime when, String message) { | 23 | + public PaymentResultBO(String tradeId, String paymentId, Integer state, String outTradeNo, Integer outPayType, |
| 24 | + String payerId, LocalDateTime when, String message) { | ||
| 25 | this.tradeId = tradeId; | 25 | this.tradeId = tradeId; |
| 26 | this.paymentId = paymentId; | 26 | this.paymentId = paymentId; |
| 27 | this.state = state; | 27 | this.state = state; |
cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/domain/PaymentUrlBO.java
0 → 100644
cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/RefundEvent.java renamed to cashier-shared/src/main/java/com/diligrp/cashier/shared/spi/domain/RefundResultBO.java
| 1 | -package com.diligrp.cashier.shared.spi; | 1 | +package com.diligrp.cashier.shared.spi.domain; |
| 2 | 2 | ||
| 3 | import java.time.LocalDateTime; | 3 | import java.time.LocalDateTime; |
| 4 | 4 | ||
| 5 | -public class RefundEvent { | 5 | +public class RefundResultBO { |
| 6 | // 退款单号 | 6 | // 退款单号 |
| 7 | private final String refundId; | 7 | private final String refundId; |
| 8 | // 原支付ID | 8 | // 原支付ID |
| @@ -14,7 +14,7 @@ public class RefundEvent { | @@ -14,7 +14,7 @@ public class RefundEvent { | ||
| 14 | // 交易描述 | 14 | // 交易描述 |
| 15 | private final String message; | 15 | private final String message; |
| 16 | 16 | ||
| 17 | - public RefundEvent(String refundId, String tradeId, int state, LocalDateTime when, String message) { | 17 | + public RefundResultBO(String refundId, String tradeId, int state, LocalDateTime when, String message) { |
| 18 | this.refundId = refundId; | 18 | this.refundId = refundId; |
| 19 | this.tradeId = tradeId; | 19 | this.tradeId = tradeId; |
| 20 | this.state = state; | 20 | this.state = state; |
cashier-trade/src/main/java/com/diligrp/cashier/trade/Constants.java
| @@ -11,16 +11,19 @@ public final class Constants { | @@ -11,16 +11,19 @@ public final class Constants { | ||
| 11 | // 支付通道延时路由KEY | 11 | // 支付通道延时路由KEY |
| 12 | public static final String PAYMENT_DELAY_KEY = "cashier.payment.delayKey"; | 12 | public static final String PAYMENT_DELAY_KEY = "cashier.payment.delayKey"; |
| 13 | 13 | ||
| 14 | - // 默认订单超时时间-秒, 十分钟 | ||
| 15 | - public static final int DEFAULT_ORDER_TIMEOUT_SECONDS = 10 * 60 * 1000; | 14 | + // 默认交易订单超时时间-秒, 5分钟 |
| 15 | + public static final int DEFAULT_TRADE_TIMEOUT = 5 * 60; | ||
| 16 | 16 | ||
| 17 | - // 最小订单超时时间-秒, 一分钟 | ||
| 18 | - public static final int MIN_ORDER_TIMEOUT_SECONDS = 60 * 1000; | 17 | + // 最大交易订单超时时间-秒, 10分钟 |
| 18 | + public static final int MAX_TRADE_TIMEOUT = 10 * 60; | ||
| 19 | + | ||
| 20 | + // 最小交易订单超时时间-秒, 1分钟 | ||
| 21 | + public static final int MIN_TRADE_TIMEOUT = 60; | ||
| 19 | 22 | ||
| 20 | // 支付订单分布式锁 | 23 | // 支付订单分布式锁 |
| 21 | public static final String TRADE_LOCK_REDIS_KEY = "cashier:lock:trade:%s"; | 24 | public static final String TRADE_LOCK_REDIS_KEY = "cashier:lock:trade:%s"; |
| 22 | 25 | ||
| 23 | - // 支付订单分布式锁超时时长-秒 | ||
| 24 | - public static final int TRADE_LOCK_TIMEOUT_SECONDS = 15 * 1000; | 26 | + // 支付订单分布式锁超时时长-秒, 15秒 |
| 27 | + public static final int TRADE_LOCK_TIMEOUT = 15; | ||
| 25 | 28 | ||
| 26 | } | 29 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/domain/CashierOrder.java
| @@ -17,6 +17,8 @@ public class CashierOrder { | @@ -17,6 +17,8 @@ public class CashierOrder { | ||
| 17 | private String outTradeNo; | 17 | private String outTradeNo; |
| 18 | // 回调地址 | 18 | // 回调地址 |
| 19 | private String notifyUrl; | 19 | private String notifyUrl; |
| 20 | + // 页面回调地址 | ||
| 21 | + private String redirectUrl; | ||
| 20 | // 交易描述 | 22 | // 交易描述 |
| 21 | private String description; | 23 | private String description; |
| 22 | // 附加数据 | 24 | // 附加数据 |
| @@ -78,6 +80,14 @@ public class CashierOrder { | @@ -78,6 +80,14 @@ public class CashierOrder { | ||
| 78 | this.notifyUrl = notifyUrl; | 80 | this.notifyUrl = notifyUrl; |
| 79 | } | 81 | } |
| 80 | 82 | ||
| 83 | + public String getRedirectUrl() { | ||
| 84 | + return redirectUrl; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + public void setRedirectUrl(String redirectUrl) { | ||
| 88 | + this.redirectUrl = redirectUrl; | ||
| 89 | + } | ||
| 90 | + | ||
| 81 | public String getDescription() { | 91 | public String getDescription() { |
| 82 | return description; | 92 | return description; |
| 83 | } | 93 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/domain/MerchantParams.java
| @@ -7,7 +7,6 @@ import java.util.Objects; | @@ -7,7 +7,6 @@ import java.util.Objects; | ||
| 7 | public class MerchantParams { | 7 | public class MerchantParams { |
| 8 | // 收银台配置 | 8 | // 收银台配置 |
| 9 | private CashierParams cashier; | 9 | private CashierParams cashier; |
| 10 | - // TODO: 支付结果页面-跳转大润发使用 | ||
| 11 | 10 | ||
| 12 | public static MerchantParams decode(String params) { | 11 | public static MerchantParams decode(String params) { |
| 13 | return JsonUtils.fromJsonString(params, MerchantParams.class); | 12 | return JsonUtils.fromJsonString(params, MerchantParams.class); |
cashier-trade/src/main/java/com/diligrp/cashier/trade/domain/OnlinePaymentResult.java
| @@ -2,14 +2,30 @@ package com.diligrp.cashier.trade.domain; | @@ -2,14 +2,30 @@ package com.diligrp.cashier.trade.domain; | ||
| 2 | 2 | ||
| 3 | import com.diligrp.cashier.pipeline.type.OutPaymentType; | 3 | import com.diligrp.cashier.pipeline.type.OutPaymentType; |
| 4 | import com.diligrp.cashier.pipeline.type.PaymentState; | 4 | import com.diligrp.cashier.pipeline.type.PaymentState; |
| 5 | -import com.diligrp.cashier.shared.spi.PaymentEvent; | ||
| 6 | 5 | ||
| 7 | import java.time.LocalDateTime; | 6 | import java.time.LocalDateTime; |
| 8 | 7 | ||
| 9 | /** | 8 | /** |
| 10 | * 在线支付结果 - 用于业务系统支付结果通知 | 9 | * 在线支付结果 - 用于业务系统支付结果通知 |
| 11 | */ | 10 | */ |
| 12 | -public class OnlinePaymentResult extends PaymentEvent { | 11 | +public class OnlinePaymentResult { |
| 12 | + // 交易号 | ||
| 13 | + private final String tradeId; | ||
| 14 | + // 支付ID | ||
| 15 | + private final String paymentId; | ||
| 16 | + // 支付状态 | ||
| 17 | + private final Integer state; | ||
| 18 | + // 业务系统订单号 | ||
| 19 | + private final String outTradeNo; | ||
| 20 | + // 实际支付方式 | ||
| 21 | + private final Integer outPayType; | ||
| 22 | + // 支付人信息 | ||
| 23 | + private final String payerId; | ||
| 24 | + // 发生时间 | ||
| 25 | + private final LocalDateTime when; | ||
| 26 | + // 交易描述 | ||
| 27 | + private final String message; | ||
| 28 | + | ||
| 13 | public static OnlinePaymentResult of(String tradeId, String paymentId, PaymentState state, String outTradeNo, | 29 | public static OnlinePaymentResult of(String tradeId, String paymentId, PaymentState state, String outTradeNo, |
| 14 | OutPaymentType outPayType, String payerId, LocalDateTime when, String message) { | 30 | OutPaymentType outPayType, String payerId, LocalDateTime when, String message) { |
| 15 | Integer outPayTypeCode = outPayType != null ? outPayType.getCode() : null; | 31 | Integer outPayTypeCode = outPayType != null ? outPayType.getCode() : null; |
| @@ -18,6 +34,45 @@ public class OnlinePaymentResult extends PaymentEvent { | @@ -18,6 +34,45 @@ public class OnlinePaymentResult extends PaymentEvent { | ||
| 18 | 34 | ||
| 19 | public OnlinePaymentResult(String tradeId, String paymentId, int state, String outTradeNo, Integer outPayType, | 35 | public OnlinePaymentResult(String tradeId, String paymentId, int state, String outTradeNo, Integer outPayType, |
| 20 | String payerId, LocalDateTime when, String message) { | 36 | String payerId, LocalDateTime when, String message) { |
| 21 | - super(tradeId, paymentId, state, outTradeNo, outPayType, payerId, when, message); | 37 | + this.tradeId = tradeId; |
| 38 | + this.paymentId = paymentId; | ||
| 39 | + this.state = state; | ||
| 40 | + this.outTradeNo = outTradeNo; | ||
| 41 | + this.outPayType = outPayType; | ||
| 42 | + this.payerId = payerId; | ||
| 43 | + this.when = when; | ||
| 44 | + this.message = message; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public String getTradeId() { | ||
| 48 | + return tradeId; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + public String getPaymentId() { | ||
| 52 | + return paymentId; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public Integer getState() { | ||
| 56 | + return state; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + public String getOutTradeNo() { | ||
| 60 | + return outTradeNo; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + public Integer getOutPayType() { | ||
| 64 | + return outPayType; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public String getPayerId() { | ||
| 68 | + return payerId; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + public LocalDateTime getWhen() { | ||
| 72 | + return when; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public String getMessage() { | ||
| 76 | + return message; | ||
| 22 | } | 77 | } |
| 23 | } | 78 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/domain/OnlineRefundDTO.java
| @@ -9,7 +9,7 @@ public class OnlineRefundDTO { | @@ -9,7 +9,7 @@ public class OnlineRefundDTO { | ||
| 9 | // 退款金额 | 9 | // 退款金额 |
| 10 | private Long amount; | 10 | private Long amount; |
| 11 | // 回调地址 | 11 | // 回调地址 |
| 12 | - private String notifyUri; | 12 | + private String notifyUrl; |
| 13 | // 退款原因 | 13 | // 退款原因 |
| 14 | private String description; | 14 | private String description; |
| 15 | 15 | ||
| @@ -29,12 +29,12 @@ public class OnlineRefundDTO { | @@ -29,12 +29,12 @@ public class OnlineRefundDTO { | ||
| 29 | this.amount = amount; | 29 | this.amount = amount; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | - public String getNotifyUri() { | ||
| 33 | - return notifyUri; | 32 | + public String getNotifyUrl() { |
| 33 | + return notifyUrl; | ||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | - public void setNotifyUri(String notifyUri) { | ||
| 37 | - this.notifyUri = notifyUri; | 36 | + public void setNotifyUrl(String notifyUrl) { |
| 37 | + this.notifyUrl = notifyUrl; | ||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | public String getDescription() { | 40 | public String getDescription() { |
cashier-trade/src/main/java/com/diligrp/cashier/trade/domain/OnlineRefundResult.java
| 1 | package com.diligrp.cashier.trade.domain; | 1 | package com.diligrp.cashier.trade.domain; |
| 2 | 2 | ||
| 3 | -import com.diligrp.cashier.shared.spi.RefundEvent; | ||
| 4 | - | ||
| 5 | import java.time.LocalDateTime; | 3 | import java.time.LocalDateTime; |
| 6 | 4 | ||
| 7 | /** | 5 | /** |
| 8 | * 退款结果 | 6 | * 退款结果 |
| 9 | */ | 7 | */ |
| 10 | -public class OnlineRefundResult extends RefundEvent { | 8 | +public class OnlineRefundResult { |
| 9 | + // 退款单号 | ||
| 10 | + private final String refundId; | ||
| 11 | + // 原支付ID | ||
| 12 | + private final String tradeId; | ||
| 13 | + // 支付状态 | ||
| 14 | + private final Integer state; | ||
| 15 | + // 发生时间 | ||
| 16 | + private final LocalDateTime when; | ||
| 17 | + // 交易描述 | ||
| 18 | + private final String message; | ||
| 19 | + | ||
| 11 | public OnlineRefundResult(String refundId, String tradeId, int state, LocalDateTime when, String message) { | 20 | public OnlineRefundResult(String refundId, String tradeId, int state, LocalDateTime when, String message) { |
| 12 | - super(refundId, tradeId, state, when, message); | 21 | + this.refundId = refundId; |
| 22 | + this.tradeId = tradeId; | ||
| 23 | + this.state = state; | ||
| 24 | + this.when = when; | ||
| 25 | + this.message = message; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + public String getRefundId() { | ||
| 29 | + return refundId; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public String getTradeId() { | ||
| 33 | + return tradeId; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public Integer getState() { | ||
| 37 | + return state; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public LocalDateTime getWhen() { | ||
| 41 | + return when; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public String getMessage() { | ||
| 45 | + return message; | ||
| 13 | } | 46 | } |
| 14 | } | 47 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/manager/PaymentResultManager.java
| @@ -3,10 +3,12 @@ package com.diligrp.cashier.trade.manager; | @@ -3,10 +3,12 @@ package com.diligrp.cashier.trade.manager; | ||
| 3 | import com.diligrp.cashier.shared.service.ServiceEndpointSupport; | 3 | import com.diligrp.cashier.shared.service.ServiceEndpointSupport; |
| 4 | import com.diligrp.cashier.shared.service.ThreadPoolService; | 4 | import com.diligrp.cashier.shared.service.ThreadPoolService; |
| 5 | import com.diligrp.cashier.shared.spi.IPaymentEventListener; | 5 | import com.diligrp.cashier.shared.spi.IPaymentEventListener; |
| 6 | +import com.diligrp.cashier.shared.spi.domain.PaymentResultBO; | ||
| 7 | +import com.diligrp.cashier.shared.spi.domain.RefundResultBO; | ||
| 6 | import com.diligrp.cashier.shared.util.JsonUtils; | 8 | import com.diligrp.cashier.shared.util.JsonUtils; |
| 7 | import com.diligrp.cashier.shared.util.ObjectUtils; | 9 | import com.diligrp.cashier.shared.util.ObjectUtils; |
| 8 | -import com.diligrp.cashier.trade.domain.OnlineRefundResult; | ||
| 9 | import com.diligrp.cashier.trade.domain.OnlinePaymentResult; | 10 | import com.diligrp.cashier.trade.domain.OnlinePaymentResult; |
| 11 | +import com.diligrp.cashier.trade.domain.OnlineRefundResult; | ||
| 10 | import jakarta.annotation.Resource; | 12 | import jakarta.annotation.Resource; |
| 11 | import org.slf4j.Logger; | 13 | import org.slf4j.Logger; |
| 12 | import org.slf4j.LoggerFactory; | 14 | import org.slf4j.LoggerFactory; |
| @@ -14,6 +16,8 @@ import org.springframework.beans.factory.ObjectProvider; | @@ -14,6 +16,8 @@ import org.springframework.beans.factory.ObjectProvider; | ||
| 14 | import org.springframework.stereotype.Service; | 16 | import org.springframework.stereotype.Service; |
| 15 | 17 | ||
| 16 | import java.util.List; | 18 | import java.util.List; |
| 19 | +import java.util.concurrent.Future; | ||
| 20 | +import java.util.concurrent.TimeUnit; | ||
| 17 | 21 | ||
| 18 | @Service("paymentResultManager") | 22 | @Service("paymentResultManager") |
| 19 | public class PaymentResultManager { | 23 | public class PaymentResultManager { |
| @@ -24,34 +28,46 @@ public class PaymentResultManager { | @@ -24,34 +28,46 @@ public class PaymentResultManager { | ||
| 24 | private ObjectProvider<IPaymentEventListener> eventListeners; | 28 | private ObjectProvider<IPaymentEventListener> eventListeners; |
| 25 | 29 | ||
| 26 | /** | 30 | /** |
| 31 | + * 通知业务系统在线支付通道处理结果,并阻塞一段时间保证通知完成 | ||
| 32 | + */ | ||
| 33 | + public void notifyPaymentResult(String uri, OnlinePaymentResult paymentResult, long waitMillis) { | ||
| 34 | + Future<?> future = notifyPaymentResult(uri, paymentResult); | ||
| 35 | + try { | ||
| 36 | + future.get(waitMillis, TimeUnit.MILLISECONDS); | ||
| 37 | + } catch (Exception ex) { | ||
| 38 | + // Ignore exception | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + /** | ||
| 27 | * 通知业务系统在线支付通道处理结果 | 42 | * 通知业务系统在线支付通道处理结果 |
| 28 | */ | 43 | */ |
| 29 | - public void notifyPaymentResult(String uri, OnlinePaymentResult payload) { | ||
| 30 | - ThreadPoolService.getIoThreadPoll().submit(() -> { | 44 | + public Future<?> notifyPaymentResult(String uri, OnlinePaymentResult paymentResult) { |
| 45 | + return ThreadPoolService.getIoThreadPoll().submit(() -> { | ||
| 31 | List<IPaymentEventListener> lifeCycles = eventListeners.stream().toList(); | 46 | List<IPaymentEventListener> lifeCycles = eventListeners.stream().toList(); |
| 32 | - for (IPaymentEventListener listener : lifeCycles) { | ||
| 33 | - try { | ||
| 34 | - listener.onEvent(payload); | ||
| 35 | - } catch (Exception ex) { | ||
| 36 | - LOG.error("Failed to notify trade payment result", ex); | 47 | + LOG.info("Notifying online payment result: {}, {}", paymentResult.getTradeId(), paymentResult.getPaymentId()); |
| 48 | + if (!lifeCycles.isEmpty()) { | ||
| 49 | + PaymentResultBO paymentEvent = new PaymentResultBO(paymentResult.getTradeId(), paymentResult.getPaymentId(), | ||
| 50 | + paymentResult.getState(), paymentResult.getOutTradeNo(), paymentResult.getOutPayType(), | ||
| 51 | + paymentResult.getPayerId(), paymentResult.getWhen(), paymentResult.getMessage()); | ||
| 52 | + for (IPaymentEventListener listener : lifeCycles) { | ||
| 53 | + try { | ||
| 54 | + listener.onEvent(paymentEvent); | ||
| 55 | + } catch (Exception ex) { | ||
| 56 | + LOG.error("Failed to notify online payment result", ex); | ||
| 57 | + } | ||
| 37 | } | 58 | } |
| 38 | } | 59 | } |
| 39 | - }); | ||
| 40 | 60 | ||
| 41 | - if (ObjectUtils.isEmpty(uri)) { | ||
| 42 | - return; | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - ThreadPoolService.getIoThreadPoll().submit(() -> { | ||
| 46 | - try { | ||
| 47 | - String body = JsonUtils.toJsonString(payload); | ||
| 48 | - LOG.info("Notifying online trade payment result: {}", body); | ||
| 49 | - ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(body); | ||
| 50 | - if (httpResult.statusCode != 200) { | ||
| 51 | - LOG.error("Failed to notify trade payment result"); | ||
| 52 | - } | ||
| 53 | - } catch (Exception ex) { | ||
| 54 | - LOG.error("Failed to notify trade payment result", ex); | 61 | + if (ObjectUtils.isEmpty(uri)) { |
| 62 | + try { | ||
| 63 | + String payload = JsonUtils.toJsonString(paymentResult); | ||
| 64 | + ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(payload); | ||
| 65 | + if (httpResult.statusCode != 200) { | ||
| 66 | + LOG.error("Failed to notify online payment result"); | ||
| 67 | + } | ||
| 68 | + } catch (Exception ex) { | ||
| 69 | + LOG.error("Failed to notify online payment result", ex); | ||
| 70 | + }; | ||
| 55 | } | 71 | } |
| 56 | }); | 72 | }); |
| 57 | } | 73 | } |
| @@ -59,14 +75,18 @@ public class PaymentResultManager { | @@ -59,14 +75,18 @@ public class PaymentResultManager { | ||
| 59 | /** | 75 | /** |
| 60 | * 通知业务系统退款处理结果 | 76 | * 通知业务系统退款处理结果 |
| 61 | */ | 77 | */ |
| 62 | - public void notifyRefundResult(String uri, OnlineRefundResult payload) { | 78 | + public void notifyRefundResult(String uri, OnlineRefundResult refundResult) { |
| 63 | ThreadPoolService.getIoThreadPoll().submit(() -> { | 79 | ThreadPoolService.getIoThreadPoll().submit(() -> { |
| 64 | List<IPaymentEventListener> lifeCycles = eventListeners.stream().toList(); | 80 | List<IPaymentEventListener> lifeCycles = eventListeners.stream().toList(); |
| 65 | - for (IPaymentEventListener listener : lifeCycles) { | ||
| 66 | - try { | ||
| 67 | - listener.onEvent(payload); | ||
| 68 | - } catch (Exception ex) { | ||
| 69 | - LOG.error("Failed to notify trade refund result", ex); | 81 | + if (!lifeCycles.isEmpty()) { |
| 82 | + RefundResultBO refundEvent = new RefundResultBO(refundResult.getRefundId(), refundResult.getTradeId(), | ||
| 83 | + refundResult.getState(), refundResult.getWhen(), refundResult.getMessage()); | ||
| 84 | + for (IPaymentEventListener listener : lifeCycles) { | ||
| 85 | + try { | ||
| 86 | + listener.onEvent(refundEvent); | ||
| 87 | + } catch (Exception ex) { | ||
| 88 | + LOG.error("Failed to notify trade refund result", ex); | ||
| 89 | + } | ||
| 70 | } | 90 | } |
| 71 | } | 91 | } |
| 72 | }); | 92 | }); |
| @@ -77,9 +97,9 @@ public class PaymentResultManager { | @@ -77,9 +97,9 @@ public class PaymentResultManager { | ||
| 77 | 97 | ||
| 78 | ThreadPoolService.getIoThreadPoll().submit(() -> { | 98 | ThreadPoolService.getIoThreadPoll().submit(() -> { |
| 79 | try { | 99 | try { |
| 80 | - String body = JsonUtils.toJsonString(payload); | ||
| 81 | - LOG.info("Notifying online trade refund result: {}", body); | ||
| 82 | - ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(body); | 100 | + String payload = JsonUtils.toJsonString(refundResult); |
| 101 | + LOG.info("Notifying online trade refund result: {}", payload); | ||
| 102 | + ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(payload); | ||
| 83 | if (httpResult.statusCode != 200) { | 103 | if (httpResult.statusCode != 200) { |
| 84 | LOG.error("Failed to notify trade refund result"); | 104 | LOG.error("Failed to notify trade refund result"); |
| 85 | } | 105 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/manager/TaskMessageConsumer.java
| @@ -35,7 +35,7 @@ public class TaskMessageConsumer { | @@ -35,7 +35,7 @@ public class TaskMessageConsumer { | ||
| 35 | ? properties.getContentEncoding() : StandardCharsets.UTF_8.name(); | 35 | ? properties.getContentEncoding() : StandardCharsets.UTF_8.name(); |
| 36 | try { | 36 | try { |
| 37 | String body = new String(packet, charSet); | 37 | String body = new String(packet, charSet); |
| 38 | - LOG.info("Receiving online pipeline async task request: {}", body); | 38 | + LOG.info("Receiving async delay task message: {}", body); |
| 39 | TaskMessage task = TaskMessage.fromJson(body); | 39 | TaskMessage task = TaskMessage.fromJson(body); |
| 40 | int times = NumberUtils.str2Int(task.getParams(), Integer.MAX_VALUE); | 40 | int times = NumberUtils.str2Int(task.getParams(), Integer.MAX_VALUE); |
| 41 | if (task.getType() == TaskMessage.TYPE_CASHIER_ORDER_SCAN) { | 41 | if (task.getType() == TaskMessage.TYPE_CASHIER_ORDER_SCAN) { |
| @@ -46,7 +46,7 @@ public class TaskMessageConsumer { | @@ -46,7 +46,7 @@ public class TaskMessageConsumer { | ||
| 46 | LOG.error("Never happened"); | 46 | LOG.error("Never happened"); |
| 47 | } | 47 | } |
| 48 | } catch (Exception ex) { | 48 | } catch (Exception ex) { |
| 49 | - LOG.error("Consume online pipeline async message exception", ex); | 49 | + LOG.error("Consume async delay task message exception", ex); |
| 50 | } | 50 | } |
| 51 | } | 51 | } |
| 52 | } | 52 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/manager/TaskMessageSender.java
| @@ -47,10 +47,10 @@ public class TaskMessageSender { | @@ -47,10 +47,10 @@ public class TaskMessageSender { | ||
| 47 | properties.setHeader("x-delay", String.valueOf(delayInMillis)); | 47 | properties.setHeader("x-delay", String.valueOf(delayInMillis)); |
| 48 | String payload = JsonUtils.toJsonString(task); | 48 | String payload = JsonUtils.toJsonString(task); |
| 49 | Message message = new Message(payload.getBytes(StandardCharsets.UTF_8), properties); | 49 | Message message = new Message(payload.getBytes(StandardCharsets.UTF_8), properties); |
| 50 | - LOG.info("Sending online payment order scan request for {}", task.getPayload()); | 50 | + LOG.info("Sending async delay task message for {}", task.getPayload()); |
| 51 | rabbitTemplate.send(Constants.PAYMENT_DELAY_EXCHANGE, Constants.PAYMENT_DELAY_KEY, message); | 51 | rabbitTemplate.send(Constants.PAYMENT_DELAY_EXCHANGE, Constants.PAYMENT_DELAY_KEY, message); |
| 52 | } catch (Exception ex) { | 52 | } catch (Exception ex) { |
| 53 | - LOG.error("Failed to send online payment order scan request for {}", task.getPayload(), ex); | 53 | + LOG.error("Failed to send async delay task message for {}", task.getPayload(), ex); |
| 54 | } | 54 | } |
| 55 | }); | 55 | }); |
| 56 | } | 56 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/CashierAssistantServiceImpl.java
| 1 | package com.diligrp.cashier.trade.service.impl; | 1 | package com.diligrp.cashier.trade.service.impl; |
| 2 | 2 | ||
| 3 | -import com.diligrp.cashier.pipeline.Constants; | ||
| 4 | import com.diligrp.cashier.pipeline.core.OnlinePipeline; | 3 | import com.diligrp.cashier.pipeline.core.OnlinePipeline; |
| 5 | import com.diligrp.cashier.pipeline.core.PaymentPipeline; | 4 | import com.diligrp.cashier.pipeline.core.PaymentPipeline; |
| 6 | import com.diligrp.cashier.pipeline.domain.OnlinePaymentResponse; | 5 | import com.diligrp.cashier.pipeline.domain.OnlinePaymentResponse; |
| @@ -9,6 +8,7 @@ import com.diligrp.cashier.pipeline.domain.OnlineRefundOrder; | @@ -9,6 +8,7 @@ import com.diligrp.cashier.pipeline.domain.OnlineRefundOrder; | ||
| 9 | import com.diligrp.cashier.pipeline.domain.OnlineRefundResponse; | 8 | import com.diligrp.cashier.pipeline.domain.OnlineRefundResponse; |
| 10 | import com.diligrp.cashier.pipeline.service.IPaymentPipelineManager; | 9 | import com.diligrp.cashier.pipeline.service.IPaymentPipelineManager; |
| 11 | import com.diligrp.cashier.pipeline.type.PaymentState; | 10 | import com.diligrp.cashier.pipeline.type.PaymentState; |
| 11 | +import com.diligrp.cashier.trade.Constants; | ||
| 12 | import com.diligrp.cashier.trade.dao.IOnlinePaymentDao; | 12 | import com.diligrp.cashier.trade.dao.IOnlinePaymentDao; |
| 13 | import com.diligrp.cashier.trade.domain.TradeStateDTO; | 13 | import com.diligrp.cashier.trade.domain.TradeStateDTO; |
| 14 | import com.diligrp.cashier.trade.model.OnlinePayment; | 14 | import com.diligrp.cashier.trade.model.OnlinePayment; |
| @@ -49,13 +49,13 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | @@ -49,13 +49,13 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | ||
| 49 | 49 | ||
| 50 | @Override | 50 | @Override |
| 51 | public void scanCashierTradeOrder(String tradeId, int times) { | 51 | public void scanCashierTradeOrder(String tradeId, int times) { |
| 52 | - LOG.debug("scanCashierTradeOrder{}: processing cashier order {}", times, tradeId); | ||
| 53 | - String lockKey = String.format(com.diligrp.cashier.trade.Constants.TRADE_LOCK_REDIS_KEY, tradeId); | 52 | + LOG.debug("scanCashierTradeOrder{}: processing cashier trade order {}", times, tradeId); |
| 53 | + String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, tradeId); | ||
| 54 | RLock lock = redissonClient.getLock(lockKey); | 54 | RLock lock = redissonClient.getLock(lockKey); |
| 55 | try { | 55 | try { |
| 56 | lock.lock(); | 56 | lock.lock(); |
| 57 | LocalDateTime now = LocalDateTime.now(); | 57 | LocalDateTime now = LocalDateTime.now(); |
| 58 | - // 理论上只会存在一条支付中的支付订单 | 58 | + // 查询交易订单下状态为支付中的支付订单, 理论上只有一条支付记录 |
| 59 | List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(tradeId, | 59 | List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(tradeId, |
| 60 | TradeType.TRADE.getCode(), PaymentState.PROCESSING.getCode()); | 60 | TradeType.TRADE.getCode(), PaymentState.PROCESSING.getCode()); |
| 61 | // 关闭所有未支付完成的支付订单 | 61 | // 关闭所有未支付完成的支付订单 |
| @@ -65,7 +65,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | @@ -65,7 +65,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | ||
| 65 | if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { | 65 | if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { |
| 66 | OnlinePrepayOrder order = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo()); | 66 | OnlinePrepayOrder order = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo()); |
| 67 | // 微信服务商模式,还需子商户 | 67 | // 微信服务商模式,还需子商户 |
| 68 | - order.attach(Constants.PARAM_MCH_ID, payment.getOutMchId()); | 68 | + order.attach(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID, payment.getOutMchId()); |
| 69 | OnlinePaymentResponse response = onlinePipeline.queryPrepayResponse(order); | 69 | OnlinePaymentResponse response = onlinePipeline.queryPrepayResponse(order); |
| 70 | if (!PaymentState.isFinished(response.getState().getCode())) { | 70 | if (!PaymentState.isFinished(response.getState().getCode())) { |
| 71 | try { | 71 | try { |
| @@ -75,7 +75,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | @@ -75,7 +75,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | ||
| 75 | response.getOutPayType(), response.getPayerId(), response.getWhen(), | 75 | response.getOutPayType(), response.getPayerId(), response.getWhen(), |
| 76 | PaymentState.FAILED, "自动关闭超时的支付订单"); | 76 | PaymentState.FAILED, "自动关闭超时的支付订单"); |
| 77 | } catch (Exception ex) { | 77 | } catch (Exception ex) { |
| 78 | - LOG.error("scanOnlinePrepayOrder: close online prepare order exception", ex); | 78 | + LOG.error("scanCashierTradeOrder: close online prepare order exception", ex); |
| 79 | } | 79 | } |
| 80 | } | 80 | } |
| 81 | cashierPaymentService.notifyPaymentResponse(response); | 81 | cashierPaymentService.notifyPaymentResponse(response); |
| @@ -84,7 +84,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | @@ -84,7 +84,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | ||
| 84 | // 交易订单仍然未完成则关闭交易订单,交易订单不能继续支付 | 84 | // 交易订单仍然未完成则关闭交易订单,交易订单不能继续支付 |
| 85 | TradeOrder trade = tradeAssistantService.findByTradeId(tradeId); | 85 | TradeOrder trade = tradeAssistantService.findByTradeId(tradeId); |
| 86 | if (!TradeState.isFinished(trade.getState())) { | 86 | if (!TradeState.isFinished(trade.getState())) { |
| 87 | - TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.FAILED, trade.getVersion(), now); | 87 | + TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.CLOSED, trade.getVersion(), now); |
| 88 | tradeAssistantService.proceedTradeOrder(tradeStateDTO); | 88 | tradeAssistantService.proceedTradeOrder(tradeStateDTO); |
| 89 | } | 89 | } |
| 90 | } finally { | 90 | } finally { |
| @@ -106,7 +106,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | @@ -106,7 +106,7 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { | ||
| 106 | OnlinePipeline<?> pipeline = paymentPipelineManager.findPipelineById(refund.getPipelineId(), OnlinePipeline.class); | 106 | OnlinePipeline<?> pipeline = paymentPipelineManager.findPipelineById(refund.getPipelineId(), OnlinePipeline.class); |
| 107 | OnlineRefundOrder order = new OnlineRefundOrder(refundId, refund.getOutTradeNo()); | 107 | OnlineRefundOrder order = new OnlineRefundOrder(refundId, refund.getOutTradeNo()); |
| 108 | // 微信服务商模式,还需子商户 | 108 | // 微信服务商模式,还需子商户 |
| 109 | - order.attach(Constants.PARAM_MCH_ID, refund.getOutMchId()); | 109 | + order.attach(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID, refund.getOutMchId()); |
| 110 | OnlineRefundResponse response = pipeline.queryRefundResponse(order); | 110 | OnlineRefundResponse response = pipeline.queryRefundResponse(order); |
| 111 | cashierPaymentService.notifyRefundResult(response); | 111 | cashierPaymentService.notifyRefundResult(response); |
| 112 | } | 112 | } |
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/CashierPaymentServiceImpl.java
| @@ -20,8 +20,8 @@ import com.diligrp.cashier.trade.dao.IOnlinePaymentDao; | @@ -20,8 +20,8 @@ import com.diligrp.cashier.trade.dao.IOnlinePaymentDao; | ||
| 20 | import com.diligrp.cashier.trade.dao.ITradeOrderDao; | 20 | import com.diligrp.cashier.trade.dao.ITradeOrderDao; |
| 21 | import com.diligrp.cashier.trade.domain.*; | 21 | import com.diligrp.cashier.trade.domain.*; |
| 22 | import com.diligrp.cashier.trade.exception.TradePaymentException; | 22 | import com.diligrp.cashier.trade.exception.TradePaymentException; |
| 23 | -import com.diligrp.cashier.trade.manager.TaskMessageSender; | ||
| 24 | import com.diligrp.cashier.trade.manager.PaymentResultManager; | 23 | import com.diligrp.cashier.trade.manager.PaymentResultManager; |
| 24 | +import com.diligrp.cashier.trade.manager.TaskMessageSender; | ||
| 25 | import com.diligrp.cashier.trade.model.OnlinePayment; | 25 | import com.diligrp.cashier.trade.model.OnlinePayment; |
| 26 | import com.diligrp.cashier.trade.model.TradeOrder; | 26 | import com.diligrp.cashier.trade.model.TradeOrder; |
| 27 | import com.diligrp.cashier.trade.service.ICashierPaymentService; | 27 | import com.diligrp.cashier.trade.service.ICashierPaymentService; |
| @@ -84,8 +84,9 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | @@ -84,8 +84,9 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | ||
| 84 | public String doSubmit(Merchant merchant, CashierOrder cashierOrder) { | 84 | public String doSubmit(Merchant merchant, CashierOrder cashierOrder) { |
| 85 | LocalDateTime now = LocalDateTime.now(); | 85 | LocalDateTime now = LocalDateTime.now(); |
| 86 | String tradeId = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.TRADE_ID).nextId(); | 86 | String tradeId = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.TRADE_ID).nextId(); |
| 87 | - int timeout = Objects.isNull(cashierOrder.getTimeout()) ? Constants.DEFAULT_ORDER_TIMEOUT_SECONDS : cashierOrder.getTimeout(); | ||
| 88 | - timeout = Math.max(timeout, Constants.MIN_ORDER_TIMEOUT_SECONDS); | 87 | + // 订单超时时间在1至10分钟之间,默认为5分钟 |
| 88 | + int timeout = Objects.isNull(cashierOrder.getTimeout()) ? Constants.DEFAULT_TRADE_TIMEOUT : cashierOrder.getTimeout(); | ||
| 89 | + timeout = Math.min(Math.max(timeout, Constants.MIN_TRADE_TIMEOUT), Constants.MAX_TRADE_TIMEOUT); | ||
| 89 | TradeOrder tradeOrder = TradeOrder.builder().mchId(merchant.getMchId()).tradeId(tradeId) | 90 | TradeOrder tradeOrder = TradeOrder.builder().mchId(merchant.getMchId()).tradeId(tradeId) |
| 90 | .type(cashierOrder.getType().getCode()).outTradeNo(cashierOrder.getOutTradeNo()).amount(cashierOrder.getAmount()) | 91 | .type(cashierOrder.getType().getCode()).outTradeNo(cashierOrder.getOutTradeNo()).amount(cashierOrder.getAmount()) |
| 91 | .maxAmount(cashierOrder.getAmount()).goods(cashierOrder.getGoods()).timeout(timeout).state(TradeState.PENDING.getCode()) | 92 | .maxAmount(cashierOrder.getAmount()).goods(cashierOrder.getGoods()).timeout(timeout).state(TradeState.PENDING.getCode()) |
| @@ -93,10 +94,9 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | @@ -93,10 +94,9 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | ||
| 93 | .source(0).version(0).createdTime(now).modifiedTime(now).build(); | 94 | .source(0).version(0).createdTime(now).modifiedTime(now).build(); |
| 94 | tradeOrderDao.insertTradeOrder(tradeOrder); | 95 | tradeOrderDao.insertTradeOrder(tradeOrder); |
| 95 | 96 | ||
| 96 | - // TODO: userId是否需要存储 | ||
| 97 | // 兜底处理交易订单,根据支付结果选择关闭或完成交易订单 | 97 | // 兜底处理交易订单,根据支付结果选择关闭或完成交易订单 |
| 98 | TaskMessage message = new TaskMessage(TaskMessage.TYPE_CASHIER_ORDER_SCAN, tradeId, "1"); | 98 | TaskMessage message = new TaskMessage(TaskMessage.TYPE_CASHIER_ORDER_SCAN, tradeId, "1"); |
| 99 | - taskMessageSender.sendDelayTaskMessage(message, timeout); | 99 | + taskMessageSender.sendDelayTaskMessage(message, timeout * 1000); // 转换成毫秒 |
| 100 | return tradeId; | 100 | return tradeId; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| @@ -113,7 +113,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | @@ -113,7 +113,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | ||
| 113 | String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, cashierPayment.getTradeId()); | 113 | String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, cashierPayment.getTradeId()); |
| 114 | RLock lock = redissonClient.getLock(lockKey); | 114 | RLock lock = redissonClient.getLock(lockKey); |
| 115 | try { | 115 | try { |
| 116 | - boolean locked = lock.tryLock(Constants.TRADE_LOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS); | 116 | + boolean locked = lock.tryLock(Constants.TRADE_LOCK_TIMEOUT, TimeUnit.SECONDS); |
| 117 | if (locked) { | 117 | if (locked) { |
| 118 | TradeOrder trade = tradeAssistantService.findByTradeId(cashierPayment.getTradeId()); | 118 | TradeOrder trade = tradeAssistantService.findByTradeId(cashierPayment.getTradeId()); |
| 119 | CashierType cashierType = CashierType.getByCode(trade.getType()); | 119 | CashierType cashierType = CashierType.getByCode(trade.getType()); |
| @@ -131,52 +131,50 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | @@ -131,52 +131,50 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | ||
| 131 | 131 | ||
| 132 | LocalDateTime now = LocalDateTime.now(); | 132 | LocalDateTime now = LocalDateTime.now(); |
| 133 | // 获取支付通道 | 133 | // 获取支付通道 |
| 134 | - PaymentPipeline<?> paymentPipeline = paymentPipelineManager.findPipelineById( | 134 | + PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById( |
| 135 | cashierPayment.getPipelineId(), PaymentPipeline.class); | 135 | cashierPayment.getPipelineId(), PaymentPipeline.class); |
| 136 | String paymentId = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.PAYMENT_ID).nextId(); | 136 | String paymentId = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.PAYMENT_ID).nextId(); |
| 137 | - if (paymentPipeline instanceof OnlinePipeline<?> pipeline) { // 在线支付通道 | 137 | + if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { // 在线支付通道 |
| 138 | // 在线支付通道: 不同的收银台类型使用不同的支付方式(目前只支持小程序收银台) | 138 | // 在线支付通道: 不同的收银台类型使用不同的支付方式(目前只支持小程序收银台) |
| 139 | // 小程序收银台将使用在线支付通道的小程序支付 | 139 | // 小程序收银台将使用在线支付通道的小程序支付 |
| 140 | MiniProPrepayRequest request = new MiniProPaymentConverter(trade, paymentId, now).convert(cashierPayment); | 140 | MiniProPrepayRequest request = new MiniProPaymentConverter(trade, paymentId, now).convert(cashierPayment); |
| 141 | - MiniProPrepayResponse response = pipeline.sendMiniProPrepayRequest(request); | 141 | + MiniProPrepayResponse response = onlinePipeline.sendMiniProPrepayRequest(request); |
| 142 | // 微信服务商模式下outMchId为签约子商户 | 142 | // 微信服务商模式下outMchId为签约子商户 |
| 143 | String outMchId = request.getString(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID); | 143 | String outMchId = request.getString(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID); |
| 144 | OnlinePayment payment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId()) | 144 | OnlinePayment payment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId()) |
| 145 | - .type(TradeType.TRADE).paymentId(paymentId).channelId(pipeline.supportedChannel()) | ||
| 146 | - .payType(PaymentType.MINI_PRO).pipelineId(pipeline.pipelineId()).goods(trade.getGoods()) | 145 | + .type(TradeType.TRADE).paymentId(paymentId).channelId(onlinePipeline.supportedChannel()) |
| 146 | + .payType(PaymentType.MINI_PRO).pipelineId(onlinePipeline.pipelineId()).goods(trade.getGoods()) | ||
| 147 | .amount(trade.getAmount()).payerId(request.getOpenId()).outTradeNo(response.getOutTradeNo()) | 147 | .amount(trade.getAmount()).payerId(request.getOpenId()).outTradeNo(response.getOutTradeNo()) |
| 148 | .state(response.getState()).version(0).createdTime(now).modifiedTime(now).build(); | 148 | .state(response.getState()).version(0).createdTime(now).modifiedTime(now).build(); |
| 149 | onlinePaymentDao.insertOnlinePayment(payment); | 149 | onlinePaymentDao.insertOnlinePayment(payment); |
| 150 | return response; | 150 | return response; |
| 151 | } | 151 | } |
| 152 | - if (paymentPipeline instanceof DiliCardPipeline pipeline) { // 园区卡支付通道 | 152 | + if (pipeline instanceof DiliCardPipeline cardPipeline) { // 园区卡支付通道 |
| 153 | // 园区卡支付通道: 所有的收银台类型使用的是同一种园区卡支付流程 | 153 | // 园区卡支付通道: 所有的收银台类型使用的是同一种园区卡支付流程 |
| 154 | CardPaymentRequest request = new CardPaymentConverter(trade, paymentId, now).convert(cashierPayment); | 154 | CardPaymentRequest request = new CardPaymentConverter(trade, paymentId, now).convert(cashierPayment); |
| 155 | // 修改支付状态为支付中,防止重复支付 | 155 | // 修改支付状态为支付中,防止重复支付 |
| 156 | - CardPaymentResponse response = pipeline.sendPaymentRequest(request); | ||
| 157 | - if (PaymentState.isFinished(response.getState().getCode())) { | 156 | + CardPaymentResponse response = cardPipeline.sendPaymentRequest(request); |
| 157 | + // 支付成功插入支付记录并修改交易订单状态,失败可以继续支付 | ||
| 158 | + if (response.getState() == PaymentState.SUCCESS) { | ||
| 158 | // 园区卡支付通道outMchId为市场ID | 159 | // 园区卡支付通道outMchId为市场ID |
| 159 | - String outMchId = pipeline.params().getOutMchId(); | 160 | + String outMchId = cardPipeline.params().getOutMchId(); |
| 160 | OnlinePayment payment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId()) | 161 | OnlinePayment payment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId()) |
| 161 | - .type(TradeType.TRADE).paymentId(paymentId).channelId(pipeline.supportedChannel()) | ||
| 162 | - .payType(PaymentType.DIRECT).pipelineId(pipeline.pipelineId()).goods(trade.getGoods()) | 162 | + .type(TradeType.TRADE).paymentId(paymentId).channelId(cardPipeline.supportedChannel()) |
| 163 | + .payType(PaymentType.DIRECT).pipelineId(cardPipeline.pipelineId()).goods(trade.getGoods()) | ||
| 163 | .amount(trade.getAmount()).payerId(response.getPayerId()) | 164 | .amount(trade.getAmount()).payerId(response.getPayerId()) |
| 164 | .finishTime(response.getWhen()).outTradeNo(response.getOutTradeNo()) | 165 | .finishTime(response.getWhen()).outTradeNo(response.getOutTradeNo()) |
| 165 | .outPayType(OutPaymentType.DILICARD).state(response.getState()).notifyUrl(trade.getNotifyUrl()) | 166 | .outPayType(OutPaymentType.DILICARD).state(response.getState()).notifyUrl(trade.getNotifyUrl()) |
| 166 | .description(response.getMessage()).version(0).createdTime(now).modifiedTime(now).build(); | 167 | .description(response.getMessage()).version(0).createdTime(now).modifiedTime(now).build(); |
| 167 | onlinePaymentDao.insertOnlinePayment(payment); | 168 | onlinePaymentDao.insertOnlinePayment(payment); |
| 168 | 169 | ||
| 169 | - // 只有成功才修改交易订单状态,此时交易订单仍然可以继续支付 | ||
| 170 | - if (response.getState() == PaymentState.SUCCESS) { | ||
| 171 | - TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.SUCCESS, | ||
| 172 | - trade.getVersion(), now); | ||
| 173 | - tradeAssistantService.proceedTradeOrder(tradeStateDTO); | ||
| 174 | - // 支付成功才通知业务系统支付结果,失败可以再次进行支付 | ||
| 175 | - OnlinePaymentResult paymentResult = new OnlinePaymentResult(trade.getTradeId(), paymentId, | ||
| 176 | - response.getState().getCode(), trade.getOutTradeNo(), OutPaymentType.DILICARD.getCode(), | ||
| 177 | - response.getPayerId(), response.getWhen(), response.getMessage()); | ||
| 178 | - paymentResultManager.notifyPaymentResult(trade.getNotifyUrl(), paymentResult); | ||
| 179 | - } | 170 | + TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.SUCCESS, |
| 171 | + trade.getVersion(), now); | ||
| 172 | + tradeAssistantService.proceedTradeOrder(tradeStateDTO); | ||
| 173 | + // 通知业务系统支付结果, | ||
| 174 | + OnlinePaymentResult paymentResult = new OnlinePaymentResult(trade.getTradeId(), paymentId, | ||
| 175 | + response.getState().getCode(), trade.getOutTradeNo(), OutPaymentType.DILICARD.getCode(), | ||
| 176 | + response.getPayerId(), response.getWhen(), response.getMessage()); | ||
| 177 | + paymentResultManager.notifyPaymentResult(trade.getNotifyUrl(), paymentResult, 500); | ||
| 180 | } | 178 | } |
| 181 | return response; | 179 | return response; |
| 182 | } else { | 180 | } else { |
| @@ -205,10 +203,10 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | @@ -205,10 +203,10 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | ||
| 205 | public void notifyPaymentResponse(OnlinePaymentResponse response) { | 203 | public void notifyPaymentResponse(OnlinePaymentResponse response) { |
| 206 | OnlinePayment payment = tradeAssistantService.findByPaymentId(response.getPaymentId()); | 204 | OnlinePayment payment = tradeAssistantService.findByPaymentId(response.getPaymentId()); |
| 207 | if (PaymentState.isFinished(payment.getState())) { | 205 | if (PaymentState.isFinished(payment.getState())) { |
| 208 | - LOG.warn("Duplicate process payment result notification for {}:{}", payment.getPaymentId(), response.getState()); | 206 | + LOG.warn("Duplicate process payment response: [{}:{}]", payment.getPaymentId(), response.getState()); |
| 209 | return; | 207 | return; |
| 210 | } | 208 | } |
| 211 | - LOG.info("Processing payment result notification: [{},{}]", payment.getPaymentId(), response.getState()); | 209 | + LOG.info("Processing payment response: [{},{}]", payment.getPaymentId(), response.getState()); |
| 212 | 210 | ||
| 213 | if (PaymentState.isFinished(response.getState().getCode())) { | 211 | if (PaymentState.isFinished(response.getState().getCode())) { |
| 214 | LocalDateTime now = LocalDateTime.now(); | 212 | LocalDateTime now = LocalDateTime.now(); |
| @@ -224,14 +222,14 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | @@ -224,14 +222,14 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | ||
| 224 | tradeAssistantService.proceedOnlinePayment(paymentDTO); | 222 | tradeAssistantService.proceedOnlinePayment(paymentDTO); |
| 225 | 223 | ||
| 226 | // 交易订单未完成,支付订单成功支付时处理交易订单,并通知业务系统支付结果;如果支付订单支付失败,收银台交易订单可以继续支付 | 224 | // 交易订单未完成,支付订单成功支付时处理交易订单,并通知业务系统支付结果;如果支付订单支付失败,收银台交易订单可以继续支付 |
| 227 | - if (TradeState.PENDING.equalTo(trade.getState()) && PaymentState.SUCCESS == response.getState()) { | 225 | + if (PaymentState.SUCCESS == response.getState() && TradeState.PENDING.equalTo(trade.getState())) { |
| 228 | TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.SUCCESS, trade.getVersion(), now); | 226 | TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.SUCCESS, trade.getVersion(), now); |
| 229 | tradeAssistantService.proceedTradeOrder(tradeStateDTO); | 227 | tradeAssistantService.proceedTradeOrder(tradeStateDTO); |
| 230 | - | 228 | + LOG.debug("Accomplish cashier order[{}] successfully", trade.getTradeId()); |
| 231 | OnlinePaymentResult paymentResult = OnlinePaymentResult.of(trade.getTradeId(), payment.getPaymentId(), | 229 | OnlinePaymentResult paymentResult = OnlinePaymentResult.of(trade.getTradeId(), payment.getPaymentId(), |
| 232 | response.getState(), trade.getOutTradeNo(), response.getOutPayType(), response.getPayerId(), | 230 | response.getState(), trade.getOutTradeNo(), response.getOutPayType(), response.getPayerId(), |
| 233 | response.getWhen() != null ? response.getWhen() : now, response.getMessage()); | 231 | response.getWhen() != null ? response.getWhen() : now, response.getMessage()); |
| 234 | - paymentResultManager.notifyPaymentResult(trade.getNotifyUrl(), paymentResult); | 232 | + paymentResultManager.notifyPaymentResult(trade.getNotifyUrl(), paymentResult, 500); |
| 235 | } | 233 | } |
| 236 | } finally { | 234 | } finally { |
| 237 | if (lock.isHeldByCurrentThread()) { | 235 | if (lock.isHeldByCurrentThread()) { |
| @@ -280,6 +278,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | @@ -280,6 +278,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { | ||
| 280 | 278 | ||
| 281 | @Override | 279 | @Override |
| 282 | public OnlinePaymentResult queryPaymentState(String paymentId, String mode) { | 280 | public OnlinePaymentResult queryPaymentState(String paymentId, String mode) { |
| 281 | + // TODO: 支付成功后返回支付成功的页面地址 | ||
| 283 | OnlinePayment payment = tradeAssistantService.findByPaymentId(paymentId); | 282 | OnlinePayment payment = tradeAssistantService.findByPaymentId(paymentId); |
| 284 | TradeOrder trade = tradeAssistantService.findByTradeId(payment.getTradeId()); | 283 | TradeOrder trade = tradeAssistantService.findByTradeId(payment.getTradeId()); |
| 285 | 284 |
scripts/cashier-data.sql
0 → 100644
| 1 | +INSERT INTO upay_merchant(mch_id, name, param, address, linkman, telephone, state, created_time, modified_time) | ||
| 2 | +VALUES (1001, '安徽省中瑞农副产品有限责任公司', '{"cashier":{"miniProUrl": "https://cashier.pay.gszdtop.com/merchant/mp"}}', '安徽省濉溪县南环路中瑞农产品批发市场', '赵静', '0561-6863420', 1, now(), now()); | ||
| 0 | \ No newline at end of file | 3 | \ No newline at end of file |