import { createCommands } from '@jolibox/common'; import { createAPI, registerCanIUse, t } from './base'; import { createJoliGemPaymentService } from '../payment/payment-service'; import { createAPIError } from '@/common/report/errors'; import { IPaymentChoice } from '@jolibox/ui/dist/bridge/coin'; import { ISpinSubscriptionPriceData, ISubscriptionTierData } from '@jolibox/types'; import { subscriptionService } from '@/native/subscription'; import { applyNative } from '@jolibox/native-bridge'; import { ISubscriptionPlanData } from '@/native/subscription/type'; const commands = createCommands(); const paymentService = createJoliGemPaymentService(); const purchaseGem = createAPI('purchaseGem', { paramsSchema: t.tuple( t.object({ productId: t.string() }) ), implement: async (params: { productId: string }): Promise<{ totalAmount?: string }> => { const result = await paymentService.purchase(params.productId); if (result.code !== 'SUCCESS') { throw createAPIError({ code: -1, msg: '[JoliboxSDK]: purchase gem failed: ' + result.message }); } return { totalAmount: result.data?.totalAmount ?? '' }; } }); const getGemProducts = createAPI('getGemProducts', { paramsSchema: t.tuple(), implement: async (): Promise<{ products: IPaymentChoice[] }> => { const choices = (await paymentService.getProductsInfoWithBalance())?.paymentChoices ?? []; console.info('choices', choices); return { products: choices.map((choice) => ({ productId: choice.productId, totalAmountStr: choice.totalAmountStr ?? '', quantity: choice.quantity })) }; } }); const getSubscriptionPlans = createAPI('getSubscriptionPlans', { paramsSchema: t.tuple(), implement: async (): Promise<{ plans: ISubscriptionTierData[] } | undefined> => { const subPlans = await subscriptionService.getSubInfo(); console.log('[PaymentAPI] getSubscriptionPlans result', subPlans); if (!subPlans) { throw createAPIError({ code: -1, msg: '[JoliboxSDK]: get subscription plans failed' }); } return { plans: subPlans }; } }); const flushSubInfoCache = createAPI('flushSubInfoCache', { paramsSchema: t.tuple(), implement: async (): Promise => { await subscriptionService.updateAllNativePriceCache(); } }); // base subscribe const internalSubscribe = async (params: { productId: string; appStoreProductId?: string }) => { const { productId } = params; let basePlanId = params.appStoreProductId; let appStoreProductId = params.appStoreProductId; let nativeProductId = productId; if (!params.appStoreProductId) { const tier = await subscriptionService.getTierByProductId(params.productId); if (!tier) { throw createAPIError({ code: -1, msg: '[JoliboxSDK]: product not found' }); } basePlanId = tier.basePlanId; appStoreProductId = tier.appStoreProductId; nativeProductId = tier.nativeProductId; } if (!basePlanId || !appStoreProductId || !nativeProductId) { throw createAPIError({ code: -1, msg: '[JoliboxSDK]: product not found' }); } const result = await subscriptionService.subscribe({ basePlanId, nativeProductId, appStoreProductId }); return { result: result.result, subPlanId: result.subPlanId, errMsg: result.message ?? '' }; }; // origin subscribe const subscribe = createAPI('subscribe', { paramsSchema: t.tuple( t.object({ productId: t.string(), appStoreProductId: t.string().optional() }) ), implement: internalSubscribe // 直接引用 }); const subscribeSpin = createAPI('subscribeSpin', { paramsSchema: t.tuple( t.object({ appStoreProductId: t.string().optional() }) ), implement: async (params) => { return internalSubscribe({ ...params, productId: 'jolibox_app_spin_sub' }); } }); commands.registerCommand('PaymentSDK.purchaseGem', purchaseGem); commands.registerCommand('PaymentSDK.getGemProducts', getGemProducts); commands.registerCommand('PaymentSDK.getSubscriptionPlans', getSubscriptionPlans); commands.registerCommand('PaymentSDK.subscribe', subscribe); commands.registerCommand('PaymentSDK.subscribeSpin', subscribeSpin); const getSpinSubscriptionPrice = createAPI('getSpinSubscriptionPrice', { paramsSchema: t.tuple( t.object({ appStoreProductId: t.string() }) ), implement: async (params: { appStoreProductId: string; }): Promise<{ plans: ISpinSubscriptionPriceData[] }> => { const { data } = await applyNative('requestSubscriptionPlansAsync', { appStoreProductIds: [params.appStoreProductId], type: 'SPIN' }); if (!data) { throw createAPIError({ code: -1, msg: '[JoliboxSDK]: get spin subscription price failed' }); } const plans: ISpinSubscriptionPriceData[] = Object.values( data as Record ).map((plan) => ({ basePlanId: plan.basePlanId, productId: plan.productId, formattedPrice: plan.pricing.formattedPrice, originalPrice: plan.pricing.originalPrice, trialDay: plan.trial?.duration ?? 0 })); return { plans }; } }); commands.registerCommand('PaymentSDK.flushSubInfoCache', flushSubInfoCache); commands.registerCommand('PaymentSDK.getSpinSubscriptionPrice', getSpinSubscriptionPrice); registerCanIUse('payment.purchaseGem', { version: '1.2.9' }); registerCanIUse('payment.getGemProducts', { version: '1.2.9' }); registerCanIUse('payment.getSubscriptionPlans', { version: '1.2.9' }); registerCanIUse('payment.subscribe', { version: '1.2.9' }); registerCanIUse('payment.flushSubInfoCache', { version: '1.2.9' }); registerCanIUse('payment.subscribeSpin', { version: '1.3.7' }); registerCanIUse('payment.getSpinSubscriptionPrice', { version: '1.4.3' });