终端内直接弹出 UnlockProOverlay:订阅支付无需跳转账户页
新增 useTerminalPay hook 和 billing-utils 纯函数,SubscriptionGate 集成支付弹窗。 用户点击订阅后原地弹窗 → 连接钱包 → 链上支付 → 自动刷新进入终端。
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
export interface TerminalBilling {
|
||||
planAmount: number;
|
||||
pointsEnabled: boolean;
|
||||
pointsPerUsdc: number;
|
||||
maxDiscountUsdc: number;
|
||||
pointsUsed: number;
|
||||
discountAmount: number;
|
||||
payAmount: number;
|
||||
canRedeem: boolean;
|
||||
}
|
||||
|
||||
export interface PointsRedemptionConfig {
|
||||
enabled?: boolean;
|
||||
points_per_usdc?: number;
|
||||
max_discount_usdc?: number;
|
||||
}
|
||||
|
||||
export function computeBilling(params: {
|
||||
planPriceUsd: number;
|
||||
totalPoints: number;
|
||||
usePoints: boolean;
|
||||
redemptionCfg?: PointsRedemptionConfig | null;
|
||||
}): TerminalBilling {
|
||||
const planAmount =
|
||||
Number.isFinite(params.planPriceUsd) && params.planPriceUsd > 0
|
||||
? params.planPriceUsd
|
||||
: 10;
|
||||
|
||||
const cfg = params.redemptionCfg || {};
|
||||
const pointsEnabled = cfg.enabled !== false;
|
||||
const pointsPerUsdcRaw = Number(cfg.points_per_usdc ?? 500);
|
||||
const pointsPerUsdc =
|
||||
Number.isFinite(pointsPerUsdcRaw) && pointsPerUsdcRaw > 0
|
||||
? Math.floor(pointsPerUsdcRaw)
|
||||
: 500;
|
||||
|
||||
const maxDiscountRaw = Number(cfg.max_discount_usdc ?? 3);
|
||||
const maxDiscountUsdc = Math.max(
|
||||
0,
|
||||
Math.min(
|
||||
Math.floor(Number.isFinite(maxDiscountRaw) ? maxDiscountRaw : 3),
|
||||
Math.floor(planAmount),
|
||||
),
|
||||
);
|
||||
|
||||
const maxRedeemablePoints = pointsPerUsdc * maxDiscountUsdc;
|
||||
const actualRedeem = pointsEnabled
|
||||
? Math.min(params.totalPoints, maxRedeemablePoints)
|
||||
: 0;
|
||||
const discountUnits = Math.floor(actualRedeem / pointsPerUsdc);
|
||||
const pointsUsed = discountUnits * pointsPerUsdc;
|
||||
const canRedeem =
|
||||
pointsEnabled &&
|
||||
maxDiscountUsdc > 0 &&
|
||||
params.totalPoints >= pointsPerUsdc;
|
||||
const applyDiscount =
|
||||
params.usePoints && canRedeem && pointsUsed > 0;
|
||||
|
||||
return {
|
||||
planAmount,
|
||||
pointsEnabled,
|
||||
pointsPerUsdc,
|
||||
maxDiscountUsdc,
|
||||
pointsUsed,
|
||||
discountAmount: discountUnits,
|
||||
payAmount: planAmount - (applyDiscount ? discountUnits : 0),
|
||||
canRedeem,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user