增加支付版本判断

This commit is contained in:
hy001 2026-05-25 23:22:51 +08:00
parent d799d68946
commit 0464935619
14 changed files with 175 additions and 28 deletions

View File

@ -56,9 +56,13 @@ public class BuySuccessEvent implements Serializable {
*/ */
String payPlatform; String payPlatform;
/** /**
* 来源. * 本次充值请求的App版本.
*/ */
String appVersion;
/**
* 来源.
*/
String origin; String origin;
/** /**

View File

@ -29,6 +29,7 @@ public class RechargeSuccessEvent implements Serializable {
private String currency; private String currency;
private String payPlatform; private String payPlatform;
private String paymentMethod; private String paymentMethod;
private String appVersion;
private String sourceOrderId; private String sourceOrderId;
private String orderId; private String orderId;
private String occurredAt; private String occurredAt;

View File

@ -109,6 +109,7 @@ public class AppInAppPurchaseCmdExe {
.setSysOrigin(history.getSysOrigin()) .setSysOrigin(history.getSysOrigin())
.setPlatform(history.getPlatform()) .setPlatform(history.getPlatform())
.setPayPlatform(history.getPayPlatform()) .setPayPlatform(history.getPayPlatform())
.setAppVersion(reqAppVersion(cmd))
.setOrigin(appCommodity.getProductConfigProductId()) .setOrigin(appCommodity.getProductConfigProductId())
.setOriginName(appCommodity.getOriginDescription()) .setOriginName(appCommodity.getOriginDescription())
.setExpireDateMs(history.getExpiresDateMs()) .setExpireDateMs(history.getExpiresDateMs())
@ -168,7 +169,12 @@ public class AppInAppPurchaseCmdExe {
return MonthlyRechargeType.UNDEFINED; return MonthlyRechargeType.UNDEFINED;
} }
private void saveFriendshipRecord(AppCommodity appCommodity) { private String reqAppVersion(AbstractPurchaseCmd cmd) {
return Objects.nonNull(cmd.getReqAppIntel())
? Objects.toString(cmd.getReqAppIntel().getVersion(), "")
: "";
}
private void saveFriendshipRecord(AppCommodity appCommodity) {
PurchaseHistory purchaseHistory = appCommodity.getPurchaseHistory(); PurchaseHistory purchaseHistory = appCommodity.getPurchaseHistory();
orderPurchaseFriendshipRecordService.save( orderPurchaseFriendshipRecordService.save(
new OrderPurchaseFriendshipRecord() new OrderPurchaseFriendshipRecord()

View File

@ -119,11 +119,12 @@ public class PayWebPlaceAnOrderCmdExe {
+ "&appId=" + application.getId() + "&appId=" + application.getId()
+ "&appStatus=0" + "&appStatus=0"
+ "&appType=" + commodity.getType()); + "&appType=" + commodity.getType());
details.setCancelRedirectUrl(details.getRechargeUrl()); details.setCancelRedirectUrl(details.getRechargeUrl());
details.setNewVersion(cmd.getNewVersion()); details.setNewVersion(cmd.getNewVersion());
details.setRequestIp(IpUtils.getIpAddr()); details.setAppVersion(cmd.getAppVersion());
details.setRequestIp(IpUtils.getIpAddr());
// 记录充值金额
// 记录充值金额
rechargeRecord(details); rechargeRecord(details);
return details; return details;
} }

View File

@ -115,9 +115,13 @@ public class PayPlaceAnOrderDetailsV2 implements Serializable {
*/ */
private Boolean newVersion; private Boolean newVersion;
/** /**
* 请求ip信息. * 本次充值请求的App版本.
*/ */
private String appVersion;
/**
* 请求ip信息.
*/
private String requestIp; private String requestIp;
public String getFactoryChannel() { public String getFactoryChannel() {
@ -156,6 +160,7 @@ public class PayPlaceAnOrderDetailsV2 implements Serializable {
.put("countryCode", this.getCountryCode()) .put("countryCode", this.getCountryCode())
.put("amount", this.getAmount().toString()) .put("amount", this.getAmount().toString())
.put("currency", this.getCurrency()) .put("currency", this.getCurrency())
.put("appVersion", Objects.toString(this.getAppVersion(), ""))
.build(); .build();
} }

View File

@ -1,7 +1,6 @@
package com.red.circle.order.app.command.pay.web.strategy; package com.red.circle.order.app.command.pay.web.strategy;
import com.google.api.client.util.Maps; import com.red.circle.component.pay.paymax.PayMaxUtils;
import com.red.circle.component.pay.paymax.PayMaxUtils;
import com.red.circle.framework.core.request.RequestClientEnum; import com.red.circle.framework.core.request.RequestClientEnum;
import com.red.circle.framework.web.props.EnvProperties; import com.red.circle.framework.web.props.EnvProperties;
import com.red.circle.order.app.common.MiFaPayMysqlOrderSupport; import com.red.circle.order.app.common.MiFaPayMysqlOrderSupport;
@ -104,9 +103,9 @@ public class PayPlaceAnOrderService {
.setNoticeData(response.extra()) .setNoticeData(response.extra())
.setCreateTime(TimestampUtils.now()) .setCreateTime(TimestampUtils.now())
)) ))
.setMetadata(Maps.newHashMap()) .setMetadata(param.createMetadata())
.setVersion(0) .setVersion(0)
); );
return response; return response;
} }

View File

@ -15,7 +15,9 @@ import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** /**
@ -61,6 +63,7 @@ public final class MiFaPayMysqlOrderSupport {
.setFactoryCode(param.getFactoryCode()) .setFactoryCode(param.getFactoryCode())
.setFactoryOrderId(Objects.toString(response.getTradeNo(), "")) .setFactoryOrderId(Objects.toString(response.getTradeNo(), ""))
.setReferenceId(Objects.toString(param.getApplicationId(), "")) .setReferenceId(Objects.toString(param.getApplicationId(), ""))
.setAppVersion(Objects.toString(param.getAppVersion(), ""))
.setReceiptType(Objects.toString(param.getReceiptType(), .setReceiptType(Objects.toString(param.getReceiptType(),
InAppPurchaseReceiptType.PAYMENT.name())) InAppPurchaseReceiptType.PAYMENT.name()))
.setPaymentChannel(Objects.toString(param.getChannelCode(), "")) .setPaymentChannel(Objects.toString(param.getChannelCode(), ""))
@ -121,7 +124,8 @@ public final class MiFaPayMysqlOrderSupport {
.setReason(order.getReason()) .setReason(order.getReason())
.setCreateTime(order.getCreateTime()) .setCreateTime(order.getCreateTime())
.setUpdateTime(order.getUpdateTime()) .setUpdateTime(order.getUpdateTime())
.setCreateUser(order.getCreateUser()); .setCreateUser(order.getCreateUser())
.setMetadata(metadata(order));
} }
public static InAppPurchaseStatus toInAppPurchaseStatus(String payStatus) { public static InAppPurchaseStatus toInAppPurchaseStatus(String payStatus) {
@ -162,6 +166,14 @@ public final class MiFaPayMysqlOrderSupport {
return InAppPurchaseReceiptType.PAYMENT; return InAppPurchaseReceiptType.PAYMENT;
} }
private static Map<String, String> metadata(OrderUserPurchasePay order) {
Map<String, String> metadata = new HashMap<>();
if (StringUtils.isNotBlank(order.getAppVersion())) {
metadata.put("appVersion", order.getAppVersion());
}
return metadata;
}
private static BigDecimal defaultDecimal(BigDecimal value) { private static BigDecimal defaultDecimal(BigDecimal value) {
return value != null ? value : BigDecimal.ZERO; return value != null ? value : BigDecimal.ZERO;
} }

View File

@ -65,10 +65,12 @@ public class RechargeSuccessEventPublisher {
payload.put("candyQuantity", event.getCandyQuantity()); payload.put("candyQuantity", event.getCandyQuantity());
payload.put("platform", event.getPlatform()); payload.put("platform", event.getPlatform());
payload.put("payPlatform", event.getPayPlatform()); payload.put("payPlatform", event.getPayPlatform());
payload.put("appVersion", event.getAppVersion());
String sourceOrderId = String.valueOf(purchaseHistoryId); String sourceOrderId = String.valueOf(purchaseHistoryId);
String payPlatform = normalizePayPlatform(defaultIfBlank(event.getPayPlatform(), event.getPlatform())); String payPlatform = normalizePayPlatform(defaultIfBlank(event.getPayPlatform(), event.getPlatform()));
String paymentMethod = classifyPaymentMethod(payPlatform); String paymentMethod = classifyPaymentMethod(payPlatform);
String appVersion = defaultIfBlank(event.getAppVersion(), "");
publish(new RechargeSuccessEvent() publish(new RechargeSuccessEvent()
.setEventId("RECHARGE_SUCCESS:" + paymentMethod + ":" + sourceOrderId) .setEventId("RECHARGE_SUCCESS:" + paymentMethod + ":" + sourceOrderId)
.setSysOrigin(event.getSysOrigin()) .setSysOrigin(event.getSysOrigin())
@ -78,6 +80,7 @@ public class RechargeSuccessEventPublisher {
.setCurrency("USD") .setCurrency("USD")
.setPayPlatform(payPlatform) .setPayPlatform(payPlatform)
.setPaymentMethod(paymentMethod) .setPaymentMethod(paymentMethod)
.setAppVersion(appVersion)
.setSourceOrderId(sourceOrderId) .setSourceOrderId(sourceOrderId)
.setOrderId(sourceOrderId) .setOrderId(sourceOrderId)
.setOccurredAt(toInstantString(event.getBuyDateTime())) .setOccurredAt(toInstantString(event.getBuyDateTime()))
@ -110,6 +113,8 @@ public class RechargeSuccessEventPublisher {
payload.put("platform", Objects.nonNull(order.getFactory()) ? order.getFactory().getPlatform() : null); payload.put("platform", Objects.nonNull(order.getFactory()) ? order.getFactory().getPlatform() : null);
payload.put("productCode", product.getCode()); payload.put("productCode", product.getCode());
payload.put("productContent", product.getContent()); payload.put("productContent", product.getContent());
String appVersion = appVersionFromMetadata(order);
payload.put("appVersion", appVersion);
publish(new RechargeSuccessEvent() publish(new RechargeSuccessEvent()
.setEventId("RECHARGE_SUCCESS:" + paymentMethod + ":" + payPlatform + ":" + order.getId()) .setEventId("RECHARGE_SUCCESS:" + paymentMethod + ":" + payPlatform + ":" + order.getId())
@ -120,6 +125,7 @@ public class RechargeSuccessEventPublisher {
.setCurrency(defaultIfBlank(order.getCurrency(), "USD")) .setCurrency(defaultIfBlank(order.getCurrency(), "USD"))
.setPayPlatform(payPlatform) .setPayPlatform(payPlatform)
.setPaymentMethod(paymentMethod) .setPaymentMethod(paymentMethod)
.setAppVersion(appVersion)
.setSourceOrderId(order.getId()) .setSourceOrderId(order.getId())
.setOrderId(defaultIfBlank(order.getOrderId(), order.getId())) .setOrderId(defaultIfBlank(order.getOrderId(), order.getId()))
.setOccurredAt(firstTime(order.getPurchaseDateMs(), order.getUpdateTime(), order.getCreateTime())) .setOccurredAt(firstTime(order.getPurchaseDateMs(), order.getUpdateTime(), order.getCreateTime()))
@ -165,6 +171,13 @@ public class RechargeSuccessEventPublisher {
return THIRD_PARTY; return THIRD_PARTY;
} }
private String appVersionFromMetadata(InAppPurchaseDetails order) {
if (Objects.isNull(order) || Objects.isNull(order.getMetadata())) {
return "";
}
return defaultIfBlank(order.getMetadata().get("appVersion"), "");
}
private Long toCents(BigDecimal amount) { private Long toCents(BigDecimal amount) {
if (Objects.isNull(amount) || amount.compareTo(BigDecimal.ZERO) <= 0) { if (Objects.isNull(amount) || amount.compareTo(BigDecimal.ZERO) <= 0) {
return null; return null;

View File

@ -64,9 +64,13 @@ public class PayPlaceAnOrderCmd implements Serializable {
*/ */
private Boolean newVersion; private Boolean newVersion;
/** /**
* 请求ip信息. * 本次充值请求的App版本.
*/ */
private String appVersion;
/**
* 请求ip信息.
*/
private String requestIp; private String requestIp;
} }

View File

@ -45,6 +45,9 @@ public class OrderUserPurchasePay implements Serializable {
@TableField("reference_id") @TableField("reference_id")
private String referenceId; private String referenceId;
@TableField("app_version")
private String appVersion;
@TableField("receipt_type") @TableField("receipt_type")
private String receiptType; private String receiptType;

View File

@ -190,6 +190,7 @@ public class InAppPurchaseDetailsClientServiceImpl implements InAppPurchaseDetai
putMetadata(metadata, "payCountryId", order.getPayCountryId()); putMetadata(metadata, "payCountryId", order.getPayCountryId());
putMetadata(metadata, "countryId", order.getCountryId()); putMetadata(metadata, "countryId", order.getCountryId());
putMetadata(metadata, "reason", order.getReason()); putMetadata(metadata, "reason", order.getReason());
putMetadata(metadata, "appVersion", order.getAppVersion());
return metadata; return metadata;
} }

View File

@ -294,13 +294,18 @@ public class PropsActivityRewardGroupClientServiceImpl implements
if (Objects.equals(config.getType(), PropsActivityRewardEnum.PROPS.name()) || Objects.equals(config.getType(), PropsActivityRewardEnum.PROP_COUPON.name())) { if (Objects.equals(config.getType(), PropsActivityRewardEnum.PROPS.name()) || Objects.equals(config.getType(), PropsActivityRewardEnum.PROP_COUPON.name())) {
PropsSourceRecord sourceRecord = sourceRecordMap PropsSourceRecord sourceRecord = sourceRecordMap
.get(Long.valueOf(config.getContent())); .get(Long.valueOf(config.getContent()));
if (Objects.nonNull(sourceRecord)) { if (Objects.nonNull(sourceRecord)) {
propsActivity.setCover(sourceRecord.getCover()); if (Objects.equals(config.getType(), PropsActivityRewardEnum.PROPS.name())
propsActivity.setSourceUrl(sourceRecord.getSourceUrl()); && StringUtils.isNotBlank(sourceRecord.getType())) {
propsActivity.setAmount(sourceRecord.getAmount()); propsActivity.setType(sourceRecord.getType());
propsActivity.setName(sourceRecord.getName()); propsActivity.setDetailType(sourceRecord.getType());
} }
} propsActivity.setCover(sourceRecord.getCover());
propsActivity.setSourceUrl(sourceRecord.getSourceUrl());
propsActivity.setAmount(sourceRecord.getAmount());
propsActivity.setName(sourceRecord.getName());
}
}
if (Objects.equals(config.getType(), PropsActivityRewardEnum.FRAGMENTS.name())) { if (Objects.equals(config.getType(), PropsActivityRewardEnum.FRAGMENTS.name())) {
PropsSourceRecord sourceRecord = fragmentsSourceMap PropsSourceRecord sourceRecord = fragmentsSourceMap
@ -432,6 +437,8 @@ public class PropsActivityRewardGroupClientServiceImpl implements
private void setVipConfig(PropsActivityRewardConfig config, private void setVipConfig(PropsActivityRewardConfig config,
PropsActivityRewardConfigInfoDTO propsActivity, PropsActivityRewardConfigInfoDTO propsActivity,
VipLevelConfig vipConfig, Map<Long, PropsSourceRecord> vipCoverMap) { VipLevelConfig vipConfig, Map<Long, PropsSourceRecord> vipCoverMap) {
propsActivity.setType(VipActivityRewardCommon.VIP_DETAIL_TYPE);
propsActivity.setDetailType(VipActivityRewardCommon.VIP_DETAIL_TYPE);
propsActivity.setCover(resolveVipCover(vipConfig, vipCoverMap)); propsActivity.setCover(resolveVipCover(vipConfig, vipCoverMap));
propsActivity.setSourceUrl(resolveVipSourceUrl(vipConfig, vipCoverMap)); propsActivity.setSourceUrl(resolveVipSourceUrl(vipConfig, vipCoverMap));
propsActivity.setAmount(BigDecimal.valueOf(Objects.requireNonNullElse( propsActivity.setAmount(BigDecimal.valueOf(Objects.requireNonNullElse(

View File

@ -0,0 +1,16 @@
SET @table_schema = DATABASE();
SET @ddl = IF(
EXISTS(
SELECT 1
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @table_schema
AND TABLE_NAME = 'order_user_purchase_pay'
AND COLUMN_NAME = 'app_version'
),
'SELECT 1',
"ALTER TABLE `order_user_purchase_pay` ADD COLUMN `app_version` varchar(32) NOT NULL DEFAULT '' COMMENT '本次充值请求的App版本' AFTER `reference_id`"
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

View File

@ -0,0 +1,75 @@
SET NAMES utf8mb4;
SET @operate_manager_id := (
SELECT id
FROM sys_menu
WHERE alias = 'OperateManager'
LIMIT 1
);
INSERT INTO sys_menu (
id,
parent_id,
menu_name,
path,
menu_type,
icon,
create_user,
update_user,
sort,
status,
router,
alias
)
SELECT
menu_id.next_id,
@operate_manager_id,
'区域飘屏',
'operate/region-broadcast',
2,
'lucide:radio-tower',
'0',
'0',
18,
0,
'region-broadcast',
'OperateRegionBroadcast'
FROM (
SELECT COALESCE(MAX(id), 1700000000) + 1 AS next_id
FROM sys_menu
) AS menu_id
WHERE @operate_manager_id IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM sys_menu WHERE alias = 'OperateRegionBroadcast'
);
UPDATE sys_menu
SET
parent_id = @operate_manager_id,
menu_name = '区域飘屏',
path = 'operate/region-broadcast',
menu_type = 2,
icon = 'lucide:radio-tower',
update_user = '0',
sort = 18,
status = 0,
router = 'region-broadcast'
WHERE alias = 'OperateRegionBroadcast'
AND @operate_manager_id IS NOT NULL;
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT DISTINCT
role_menu.role_id,
target_menu.id
FROM sys_role_menu AS role_menu
JOIN sys_menu AS source_menu
ON source_menu.id = role_menu.menu_id
AND source_menu.alias = 'OperateManager'
JOIN sys_menu AS target_menu
ON target_menu.alias = 'OperateRegionBroadcast'
WHERE NOT EXISTS (
SELECT 1
FROM sys_role_menu AS existing_role_menu
WHERE existing_role_menu.role_id = role_menu.role_id
AND existing_role_menu.menu_id = target_menu.id
);