diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java index 6917eb08..5050f79d 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java @@ -166,9 +166,42 @@ public class PayWebApplicationCommodityV2QueryExe { } private PayCountry getPayCountry(PayWebApplicationCommodityCmd cmd) { - return Objects.isNull(cmd.getPayCountryId()) - ? payCountryService.getShelfSortMax() - : payCountryService.getById(cmd.getPayCountryId()); + if (Objects.isNull(cmd.getPayCountryId())) { + return payCountryService.getShelfSortMax(); + } + + PayCountry payCountry = payCountryService.getById(cmd.getPayCountryId()); + if (Objects.isNull(payCountry)) { + return getUsablePayCountryByCountryId(cmd.getPayCountryId()); + } + if (isUsablePayCountry(payCountry)) { + return payCountry; + } + return Optional.ofNullable(getUsablePayCountryByCountryId(payCountry.getCountryId())) + .orElse(payCountry); + } + + private PayCountry getUsablePayCountryByCountryId(Long countryId) { + if (Objects.isNull(countryId)) { + return null; + } + + return payCountryService.query() + .eq(PayCountry::getShelf, Boolean.TRUE) + .eq(PayCountry::getCountryId, countryId) + .orderByDesc(PayCountry::getSort) + .list() + .stream() + .filter(this::isUsablePayCountry) + .findFirst() + .orElse(null); + } + + private boolean isUsablePayCountry(PayCountry payCountry) { + return Objects.nonNull(payCountry) + && StringUtils.isNotBlank(payCountry.getCurrency()) + && CollectionUtils.isNotEmpty( + payCountryChannelDetailsService.listChannelCode(payCountry.getId())); } private List getPayChannels(List payChannels, diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOpenPayCountryQueryExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOpenPayCountryQueryExe.java index 487c95b3..77bd1b24 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOpenPayCountryQueryExe.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOpenPayCountryQueryExe.java @@ -38,7 +38,9 @@ public class PayWebOpenPayCountryQueryExe { ); return payCountries.stream().map(payCountry -> new PayCountryCO() .setId(payCountry.getId()) + .setPayCountryId(payCountry.getId()) .setCountryId(payCountry.getCountryId()) + .setCurrency(payCountry.getCurrency()) .setCountry(countryCodeMap.get(payCountry.getCountryId())) ).collect(Collectors.toList()); } diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java index d5b043b4..03ad331b 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java @@ -23,6 +23,7 @@ import com.red.circle.order.inner.asserts.PayErrorCode; import com.red.circle.order.inner.model.enums.inapp.InAppPurchaseReceiptType; import com.red.circle.other.inner.endpoint.sys.SysCountryCodeClient; import com.red.circle.other.inner.model.dto.sys.SysCountryCodeDTO; +import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.num.ArithmeticUtils; import com.red.circle.tool.core.sequence.IdWorkerUtils; import com.red.circle.tool.core.text.StringUtils; @@ -70,14 +71,16 @@ public class PayWebPlaceAnOrderCmdExe { ResponseAssert.notNull(PayErrorCode.UNKNOWN_APPLICATION, application); PayApplicationCommodity commodity = getAppCommodity(cmd); + PayCountry payCountry = getPayCountry(cmd.getPayCountryId()); + // 不支持地区 + ResponseAssert.notNull(PayErrorCode.REGION_NOT_SUPPORTED, payCountry); + cmd.setPayCountryId(payCountry.getId()); + PayCountryChannelDetails channelDetails = payCountryChannelDetailsService .getSuggestScoreMax(cmd.getPayCountryId(), cmd.getChannelCode(), commodity.getAmountUsd()); // 没有合适的支付方式 ResponseAssert.notNull(PayErrorCode.NO_SUITABLE_PAYMENT_CHANNEL, channelDetails); - PayCountry payCountry = payCountryService.getById(cmd.getPayCountryId()); - // 不支持地区 - ResponseAssert.notNull(PayErrorCode.REGION_NOT_SUPPORTED, payCountry); SysCountryCodeDTO sysCountryCode = ResponseAssert.requiredSuccess( sysCountryCodeClient.getById(payCountry.getCountryId()) ); @@ -131,6 +134,41 @@ public class PayWebPlaceAnOrderCmdExe { return details; } + private PayCountry getPayCountry(Long payCountryId) { + PayCountry payCountry = payCountryService.getById(payCountryId); + if (Objects.isNull(payCountry)) { + return getUsablePayCountryByCountryId(payCountryId); + } + if (isUsablePayCountry(payCountry)) { + return payCountry; + } + PayCountry compatiblePayCountry = getUsablePayCountryByCountryId(payCountry.getCountryId()); + return Objects.nonNull(compatiblePayCountry) ? compatiblePayCountry : payCountry; + } + + private PayCountry getUsablePayCountryByCountryId(Long countryId) { + if (Objects.isNull(countryId)) { + return null; + } + + return payCountryService.query() + .eq(PayCountry::getShelf, Boolean.TRUE) + .eq(PayCountry::getCountryId, countryId) + .orderByDesc(PayCountry::getSort) + .list() + .stream() + .filter(this::isUsablePayCountry) + .findFirst() + .orElse(null); + } + + private boolean isUsablePayCountry(PayCountry payCountry) { + return Objects.nonNull(payCountry) + && StringUtils.isNotBlank(payCountry.getCurrency()) + && CollectionUtils.isNotEmpty( + payCountryChannelDetailsService.listChannelCode(payCountry.getId())); + } + /** * 获取实时汇率,失败时返回配置的汇率 * @param payCountry 支付国家配置 diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java index 49025543..d7d58430 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java @@ -8,10 +8,12 @@ import com.red.circle.order.app.dto.clientobject.pay.UserProfileAndCountryCO; import com.red.circle.order.app.dto.clientobject.pay.WebSiteUseProfileCO; import com.red.circle.order.app.dto.cmd.PayWebUserCmd; import com.red.circle.order.infra.database.rds.entity.pay.PayCountry; +import com.red.circle.order.infra.database.rds.service.pay.PayCountryChannelDetailsService; import com.red.circle.order.infra.database.rds.service.pay.PayCountryService; import com.red.circle.order.inner.model.enums.PayApplicationCommodityType; import com.red.circle.other.inner.endpoint.sys.SysCountryCodeClient; import com.red.circle.other.inner.model.dto.sys.SysCountryCodeDTO; +import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.parse.DataTypeUtils; import com.red.circle.tool.core.regex.RegexConstant; import com.red.circle.tool.core.text.StringUtils; @@ -42,6 +44,7 @@ public class UserProfileAndCountryQueryExe { private final UserRegionClient userRegionClient; private final FreightGoldClient freightGoldClient; private final PayCountryService payCountryService; + private final PayCountryChannelDetailsService payCountryChannelDetailsService; private final UserProfileClient userProfileClient; private final SysCountryCodeClient sysCountryCodeClient; private final RegionRelationClient regionRelationClient; @@ -82,6 +85,7 @@ public class UserProfileAndCountryQueryExe { Map mapCountryCode = getMapCountryCode(payCountryList); ResponseAssert.notEmpty(CommonErrorCode.NOT_SUPPORTED_REGION, mapCountryCode); + Map compatiblePayCountryMap = getCompatiblePayCountryMap(payCountryList); return new UserProfileAndCountryCO() .setCountryList(payCountryList.stream().map(country -> { @@ -90,9 +94,13 @@ public class UserProfileAndCountryQueryExe { if (Objects.isNull(countryCode)) { return null; } + PayCountry compatiblePayCountry = compatiblePayCountryMap + .getOrDefault(country.getCountryId(), country); return new PayCountryCO() .setId(country.getId()) + .setPayCountryId(compatiblePayCountry.getId()) .setCountryId(country.getCountryId()) + .setCurrency(compatiblePayCountry.getCurrency()) .setCountry(countryCode); }).filter(Objects::nonNull).collect(Collectors.toList())) @@ -125,6 +133,29 @@ public class UserProfileAndCountryQueryExe { ); } + private Map getCompatiblePayCountryMap(List payCountryList) { + if (CollectionUtils.isEmpty(payCountryList)) { + return java.util.Collections.emptyMap(); + } + + List candidates = payCountryService.query() + .eq(PayCountry::getShelf, Boolean.TRUE) + .in(PayCountry::getCountryId, payCountryList.stream().map(PayCountry::getCountryId) + .collect(Collectors.toSet())) + .orderByDesc(PayCountry::getSort) + .list(); + if (CollectionUtils.isEmpty(candidates)) { + return java.util.Collections.emptyMap(); + } + + return candidates.stream() + .filter(country -> StringUtils.isNotBlank(country.getCurrency())) + .filter(country -> CollectionUtils.isNotEmpty( + payCountryChannelDetailsService.listChannelCode(country.getId()))) + .collect(Collectors.toMap(PayCountry::getCountryId, country -> country, + (left, right) -> left)); + } + private List getRegionRelationList(UserProfileDTO userProfile, String regionId) { return ResponseAssert.requiredSuccess( diff --git a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/clientobject/pay/PayCountryCO.java b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/clientobject/pay/PayCountryCO.java index 85c15ed8..86298625 100644 --- a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/clientobject/pay/PayCountryCO.java +++ b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/clientobject/pay/PayCountryCO.java @@ -30,12 +30,23 @@ public class PayCountryCO extends ClientObject { @JsonSerialize(using = ToStringSerializer.class) private Long id; + /** + * 可用于支付接口的支付国家ID. + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long payCountryId; + /** * 国家id. */ @JsonSerialize(using = ToStringSerializer.class) private Long countryId; + /** + * 国家货币. + */ + private String currency; + /** * 国家信息. */