@seaverse/payment-sdk 0.8.2 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,281 +1,286 @@
1
1
  # @seaverse/payment-sdk
2
2
 
3
- SeaVerse Payment SDK - 一站式支付解决方案,提供积分管理、支付弹窗、订阅管理和订单跟踪功能。
3
+ > **Version**: 0.9.1 | **Language**: English
4
4
 
5
- > **最新版本**: v0.8.2 | **文档语言**: 中文优先(包含英文说明)
5
+ A comprehensive payment solution for SeaVerse platform, providing credit management, payment checkout, subscription management, and order tracking.
6
6
 
7
- ## 📦 安装
7
+ ## 📦 Installation
8
8
 
9
9
  ```bash
10
10
  npm install @seaverse/payment-sdk
11
- #
11
+ # or
12
12
  pnpm add @seaverse/payment-sdk
13
+ # or
14
+ yarn add @seaverse/payment-sdk
13
15
  ```
14
16
 
15
- ## 🚀 快速开始
17
+ ## 🚀 Quick Start
16
18
 
17
- ### 1. 积分套餐购买弹窗(推荐使用)
19
+ ### 1. Credit Package Modal (Recommended)
18
20
 
19
- 最简单的集成方式 - 3 行代码完成支付流程:
21
+ The simplest integration - complete payment flow in 3 lines of code:
20
22
 
21
23
  ```typescript
22
24
  import { CreditPackageModal } from '@seaverse/payment-sdk';
23
25
 
24
- // 创建弹窗
26
+ // Create modal
25
27
  const modal = new CreditPackageModal({
28
+ language: 'en', // 'en' | 'zh' | 'zh-TW' | 'ja' | 'ko' | 'es' | 'fr' | 'de' | 'pt' | 'ru' | 'ar' | 'hi' | 'id'
29
+
26
30
  sdkConfig: {
27
- environment: 'development', // 环境:'development' | 'production'
28
- countryCode: 'SG', // 国家代码
29
- accountToken: 'user-token', // 用户认证令牌(可选)
31
+ environment: 'development', // 'development' | 'production'
32
+ accountToken: 'user-token', // User authentication token
30
33
  },
31
- onPaymentSuccess: (orderId, transactionId) => {
32
- console.log('支付成功!', { orderId, transactionId });
34
+
35
+ onPaymentSuccess: (orderId, transactionId, pkg) => {
36
+ console.log('Payment successful!', { orderId, transactionId, credits: pkg.total_credits });
33
37
  },
34
38
  });
35
39
 
36
- // 打开弹窗
40
+ // Open modal
37
41
  modal.open();
38
42
  ```
39
43
 
40
- **效果**:
41
- - ✅ 自动展示预设积分套餐(120/240/520/1200 积分)
42
- - ✅ 自动初始化支付 SDK
43
- - ✅ 自动创建订单
44
- - ✅ 显示购买成功弹窗(带动画效果)
45
- - ✅ 自动刷新积分余额
44
+ **What you get**:
45
+ - ✅ Pre-configured credit packages (fetched from API)
46
+ - ✅ Automatic SDK initialization
47
+ - ✅ Auto order creation
48
+ - ✅ Animated success modal
49
+ - ✅ Auto credit balance refresh
46
50
 
47
- ### 2. 通用套餐弹窗(自定义套餐)
51
+ ### 2. Generic Package Modal (Custom Packages)
48
52
 
49
- 适用于特殊促销、破冰包、首充包等场景:
53
+ For promotions, special offers, and custom packages:
50
54
 
51
55
  ```typescript
52
56
  import { GenericPackageModal, type GenericPackage } from '@seaverse/payment-sdk';
53
57
 
54
- // 定义自定义套餐
58
+ // Define custom packages
55
59
  const packages: GenericPackage[] = [
56
60
  {
57
- id: 'pkg_value',
61
+ id: 'pkg_ice_breaker',
58
62
  name: 'Ice Breaker Pack',
59
63
  price: '0.49',
60
64
  currency: 'USD',
61
65
  credits: '120',
66
+ base_credits: '100',
67
+ bonus_credits: '20',
62
68
  bonus_percentage: 20,
63
- day_limit: 1, // 每日限购1次
64
69
  package_type: 'iceBreaker',
65
70
  },
66
- {
67
- id: 'pkg_pro',
68
- name: 'Emergency Pack',
69
- price: '0.99',
70
- currency: 'USD',
71
- credits: '240',
72
- day_limit: 3, // 每日限购3次
73
- package_type: 'emergency',
74
- },
75
71
  ];
76
72
 
77
- // 创建弹窗
73
+ // Create modal
78
74
  const modal = new GenericPackageModal({
79
75
  packages: packages,
76
+ language: 'en',
77
+
80
78
  sdkConfig: {
81
79
  environment: 'development',
82
- countryCode: 'SG',
83
80
  accountToken: 'user-token',
84
81
  },
82
+
85
83
  onPaymentSuccess: (orderId, transactionId, pkg) => {
86
- console.log(`${pkg.name} 购买成功!`, orderId);
84
+ console.log(`${pkg.name} purchased!`, orderId);
87
85
  },
88
- onPaymentFailed: (error, pkg) => {
89
- if (error.message.includes('limit')) {
90
- alert(`${pkg.name} 已达购买限额`);
91
- }
86
+ });
87
+
88
+ modal.open();
89
+ ```
90
+
91
+ ### 3. Payment Checkout Modal (Full Checkout Experience)
92
+
93
+ Complete checkout flow with payment method selection:
94
+
95
+ ```typescript
96
+ import { PaymentCheckoutModal, PRODUCT_TYPE } from '@seaverse/payment-sdk';
97
+
98
+ const modal = new PaymentCheckoutModal({
99
+ product: {
100
+ id: 'pkg_credit_100',
101
+ name: '100 Credits Package',
102
+ price: 9.99,
103
+ currency: 'USD',
104
+ type: PRODUCT_TYPE.CREDITPACK,
105
+ },
106
+
107
+ autoCreateOrder: {
108
+ productId: 'pkg_credit_100',
109
+ purchaseType: 1, // 1 = one-time purchase, 2 = subscription
110
+ apiHost: 'https://payment.seaverse.com',
111
+ accountToken: 'user-token',
112
+ clientId: 'your-client-id',
113
+ language_code: 'en',
114
+ },
115
+
116
+ language: 'en',
117
+
118
+ onPaymentSuccess: (payload) => {
119
+ console.log('Payment completed!', payload);
92
120
  },
93
121
  });
94
122
 
95
123
  modal.open();
96
124
  ```
97
125
 
98
- ## 🏗️ 架构设计
126
+ ---
127
+
128
+ ## 🏗️ Architecture
129
+
130
+ ### Version 0.9.0 - Critical Bug Fixes
131
+
132
+ **Major fixes in this release**:
99
133
 
100
- ### 代码重构 (v0.8.1)
134
+ 1. **Fixed SDK Initialization Error** 🔧
135
+ - Resolved "Payment method 'dropin' not found" error
136
+ - Issue: BasePackageModal tried to find Dropin payment when only Link payments available
137
+ - Solution: Override `initializeSDK()` in CreditPackageModal and GenericPackageModal to skip legacy initialization
138
+ - Now PaymentCheckoutModal handles all SDK initialization independently
101
139
 
102
- 为了提高代码可维护性和消除重复逻辑,SDK 进行了架构重构:
140
+ 2. **Fixed Link Payment Auto-Execution** 🔧
141
+ - Prevented immediate redirect before users see checkout modal
142
+ - Issue: `autoSelectDefaultPaymentMethod()` auto-executed Link payment, causing instant redirect
143
+ - Solution: Only auto-select Dropin payments, wait for manual selection when only Link available
144
+ - Improved user experience with proper checkout flow
103
145
 
104
- **核心改进**:
105
- - **抽象基类设计** - 创建 `BasePackageModal<TPackage, TOptions>` 抽象基类
106
- - **消除重复代码** - 减少 ~400 行重复代码(SDK 初始化、支付流程、事件处理)
107
- - **类型安全** - 使用 TypeScript 泛型确保类型安全
108
- - ✅ **向后兼容** - 公开 API 完全不变,现有代码无需修改
146
+ 3. **UI/UX Enhancements** 🎨
147
+ - Increased payment method card spacing from 8px to 14px
148
+ - Better visual hierarchy and click targets
149
+ - Consistent spacing in both skeleton and main UI
109
150
 
110
- **类继承结构**:
151
+ ### Class Hierarchy
111
152
 
112
153
  ```
113
- BasePackageModal<TPackage, TOptions> (抽象基类)
114
- ├── CreditPackageModal (积分套餐弹框)
115
- └── GenericPackageModal (通用套餐弹框)
154
+ BasePackageModal<TPackage, TOptions> (Abstract base class)
155
+ ├── CreditPackageModal (Standard credit packages)
156
+ └── GenericPackageModal (Custom promotional packages)
157
+
158
+ PaymentCheckoutModal (Standalone checkout system)
159
+ ├── PaymentStrategyFactory
160
+ │ ├── LinkPaymentStrategy (Redirect payments)
161
+ │ ├── DropinPaymentStrategy (Embedded forms)
162
+ │ └── BasePaymentStrategy (Strategy base)
163
+ └── Services
164
+ ├── PaymentOrderService (Order management)
165
+ ├── PaymentLoadingManager (Loading states)
166
+ └── PaymentStateManager (State management)
116
167
  ```
117
168
 
118
- **BasePackageModal 提供的共享功能**:
119
- - SDK 初始化和状态管理
120
- - 支付流程处理(订单创建、支付弹框)
121
- - 事件监听和按钮处理
122
- - 工具方法(formatNumber、cleanup 等)
169
+ ### Design Patterns Used
123
170
 
124
- **子类只需实现**:
125
- - `createModal()` - 创建和配置 PaymentModal
126
- - `renderContent()` - 渲染弹框内容(UI 特定逻辑)
127
- - `getPackages()` - 获取套餐列表
128
- - `getPackageDisplayName()` - 获取套餐显示名称
129
- - `getLoadingButtonHTML()` - 获取加载按钮 HTML
130
-
131
- 这种设计确保:
132
- - **单一职责** - 基类负责逻辑,子类负责 UI
133
- - **DRY 原则** - 共享逻辑只需维护一处
134
- - **易于扩展** - 添加新套餐类型只需继承基类
171
+ - **Singleton Pattern**: SeaartPaymentSDK.getInstance()
172
+ - **Strategy Pattern**: Payment strategy selection (Link vs Dropin)
173
+ - **Template Method Pattern**: BasePackageModal with abstract methods
174
+ - **Factory Pattern**: PaymentStrategyFactory.createStrategy()
175
+ - **Service Locator Pattern**: Service injection in PaymentCheckoutModal
135
176
 
136
177
  ---
137
178
 
138
- ## 📖 核心功能模块
179
+ ## 📚 Core Features
139
180
 
140
- ### ⭐️ 推荐功能(新用户优先使用)
181
+ ### 🌟 Recommended Features (For New Users)
141
182
 
142
- | 功能 | 组件 | 使用场景 | 文档 |
143
- | ------------------ | ---------------------- | ---------------------- | ----------------------------------------------- |
144
- | **积分套餐购买** | `CreditPackageModal` | 标准积分购买(最简单) | [👉 查看](#creditpackagemodal---标准积分购买) |
145
- | **自定义套餐购买** | `GenericPackageModal` | 促销活动、特殊套餐 | [👉 查看](#genericpackagemodal---自定义套餐购买) |
146
- | **购买成功弹窗** | `PurchaseSuccessModal` | 自动集成,无需手动调用 | [👉 查看](#purchasesuccessmodal---购买成功弹窗) |
183
+ | Feature | Component | Use Case | Documentation |
184
+ |---------|-----------|----------|---------------|
185
+ | **Credit Packages** | `CreditPackageModal` | Standard credit purchases | [👉 View](#creditpackagemodal---standard-credit-purchases) |
186
+ | **Custom Packages** | `GenericPackageModal` | Promotions & special offers | [👉 View](#genericpackagemodal---custom-packages) |
187
+ | **Checkout System** | `PaymentCheckoutModal` | Full checkout experience | [👉 View](#paymentcheckoutmodal---checkout-system) |
188
+ | **Success Modal** | `PurchaseSuccessModal` | Auto-integrated, no manual call needed | [👉 View](#purchasesuccessmodal---purchase-success) |
147
189
 
148
- ### 🔧 高级功能(进阶用户)
190
+ ### 🔧 Advanced Features
149
191
 
150
- | 功能 | API | 使用场景 |
151
- | --------------------- | ---------------------------------------------- | -------------------------- |
152
- | **积分查询** | `PaymentClient` | 查询用户积分余额、交易记录 |
153
- | **订阅管理** | `getCurrentSubscription`, `changeSubscription` | 订阅状态查询、升级/降级 |
154
- | **订单管理** | `checkOrderStatus`, `pollOrderStatus` | 订单状态查询、轮询 |
155
- | **SeaartPayment SDK** | `SeaartPaymentSDK` | 完全自定义支付流程 |
192
+ | Feature | API | Use Case |
193
+ |---------|-----|----------|
194
+ | **Credit Query** | `getCreditDetail` | Check user credit balance |
195
+ | **Subscription Management** | `getCurrentSubscription`, `changeSubscription` | Manage subscriptions |
196
+ | **Order Management** | `checkOrderStatus`, `pollOrderStatus` | Track order status |
197
+ | **Custom Payment Flows** | `SeaartPaymentSDK` | Full control over payment process |
156
198
 
157
199
  ---
158
200
 
159
- ## 📚 详细使用文档
201
+ ## 📖 Detailed Documentation
160
202
 
161
- ### CreditPackageModal - 标准积分购买
203
+ ### CreditPackageModal - Standard Credit Purchases
162
204
 
163
- **适用场景**:
164
- - ✅ 标准积分套餐购买(120/240/520/1200 积分)
165
- - ✅ 展示创作力量类型(文生图、图生图等)
166
- - ✅ 最简单的集成方式
205
+ **Use Cases**:
206
+ - ✅ Standard credit package purchases
207
+ - ✅ Dynamic packages from API
208
+ - ✅ Simplest integration method
167
209
 
168
- #### 基础用法
210
+ #### Basic Usage
169
211
 
170
212
  ```typescript
171
213
  import { CreditPackageModal } from '@seaverse/payment-sdk';
172
214
 
173
215
  const modal = new CreditPackageModal({
174
- // 语言设置(可选,默认 'en'
175
- language: 'zh-CN', // 'en' | 'zh-CN'
216
+ // Language (optional, defaults to 'en')
217
+ language: 'en', // 'en' | 'zh' | 'zh-TW' | 'ja' | 'ko' | etc.
218
+
219
+ // Modal title (optional)
220
+ title: 'Purchase Credits',
221
+ title_cn: '购买积分', // Chinese title
176
222
 
177
- // SDK 配置(必填)
223
+ // SDK Configuration (required)
178
224
  sdkConfig: {
179
- environment: 'development', // 'development' | 'production'
180
- countryCode: 'SG', // ISO 3166-1 国家代码
181
- accountToken: 'user-token', // 用户认证令牌(可选)
182
- businessType: 1, // 1=一次性购买, 2=订阅(可选,默认1)
225
+ environment: 'production',
226
+ accountToken: 'user-token',
227
+
228
+ // Optional overrides
229
+ businessType: 1, // 1 = one-time, 2 = subscription
230
+ clientId: 'custom-client-id',
231
+ orderApiUrl: 'https://custom-api.com',
183
232
  },
184
233
 
185
- // 回调函数
186
- onPaymentSuccess: (orderId: string, transactionId: string) => {
187
- console.log('支付成功!', { orderId, transactionId });
188
- // 刷新用户积分、更新 UI 等
234
+ // Callbacks
235
+ onPaymentSuccess: (orderId, transactionId, pkg) => {
236
+ console.log('Payment successful!', {
237
+ orderId,
238
+ transactionId,
239
+ credits: pkg.total_credits
240
+ });
189
241
  },
190
242
 
191
- onPaymentFailed: (error: Error) => {
192
- console.error('支付失败:', error.message);
193
- // 显示错误提示
243
+ onPaymentFailed: (error, pkg) => {
244
+ console.error('Payment failed:', error.message);
194
245
  },
195
246
 
196
247
  onClose: () => {
197
- console.log('弹窗关闭');
248
+ console.log('Modal closed');
198
249
  },
199
250
  });
200
251
 
201
- // 打开弹窗
252
+ // Open modal
202
253
  modal.open();
203
254
 
204
- // 关闭弹窗(可选)
255
+ // Close modal (optional)
205
256
  modal.close();
206
257
 
207
- // 检查弹窗状态
208
- console.log('弹窗是否打开:', modal.isOpen());
209
- ```
210
-
211
- #### 预设积分套餐
212
-
213
- SDK 内置以下积分套餐:
214
-
215
- | 套餐 | 积分 | 价格 | 说明 |
216
- | ------- | ---- | ----- | -------- |
217
- | Starter | 120 | $0.49 | 入门套餐 |
218
- | Value | 240 | $0.99 | 超值套餐 |
219
- | Pro | 520 | $1.99 | 专业套餐 |
220
- | Ultra | 1200 | $4.99 | 旗舰套餐 |
221
-
222
- #### 环境配置
223
-
224
- SDK 根据 `environment` 自动配置以下参数:
225
-
226
- **开发环境 (development)**:
227
- ```typescript
228
- {
229
- scriptUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/client.js',
230
- clientId: 'XF49NOfyZ54O16GujB0ptio2',
231
- orderApiUrl: 'https://payment.sg.seaverse.dev',
232
- walletApiUrl: 'https://wallet.sg.seaverse.dev',
233
- }
234
- ```
235
-
236
- **生产环境 (production)**:
237
- ```typescript
238
- {
239
- scriptUrl: 'https://payment-static.seaverse.com/sdk/seaart-payment-component.js',
240
- clientId: 'prod_client_id',
241
- orderApiUrl: 'https://payment.seaverse.com',
242
- walletApiUrl: 'https://wallet.seaverse.com',
243
- }
258
+ // Check status
259
+ console.log('Is open:', modal.isOpen());
244
260
  ```
245
261
 
246
- #### 高级配置(可选)
247
-
248
- 如需覆盖环境配置:
249
-
250
- ```typescript
251
- const modal = new CreditPackageModal({
252
- sdkConfig: {
253
- environment: 'production',
254
- countryCode: 'US',
262
+ #### Dynamic Package Fetching
255
263
 
256
- // 覆盖默认配置
257
- scriptUrl: 'https://custom-cdn.com/payment.js',
258
- clientId: 'custom-client-id',
259
- orderApiUrl: 'https://custom-api.com',
260
- },
261
- });
262
- ```
264
+ Packages are automatically fetched from the API based on:
265
+ - Environment (`development` or `production`)
266
+ - Account token (for user-specific packages)
267
+ - Business type (one-time vs subscription)
263
268
 
264
269
  ---
265
270
 
266
- ### GenericPackageModal - 自定义套餐购买
271
+ ### GenericPackageModal - Custom Packages
267
272
 
268
- **适用场景**:
269
- - ✅ 特殊促销套餐(破冰包、告急包、首充包)
270
- - ✅ 限时优惠活动
271
- - ✅ 自定义套餐数据和样式
273
+ **Use Cases**:
274
+ - ✅ Special promotions (ice breaker packs, emergency packs)
275
+ - ✅ Limited-time offers
276
+ - ✅ First-purchase bonuses
277
+ - ✅ Custom package configurations
272
278
 
273
- #### 基础用法
279
+ #### Basic Usage
274
280
 
275
281
  ```typescript
276
282
  import { GenericPackageModal, type GenericPackage } from '@seaverse/payment-sdk';
277
283
 
278
- // 定义套餐数据
279
284
  const packages: GenericPackage[] = [
280
285
  {
281
286
  id: 'pkg_ice_breaker',
@@ -285,523 +290,394 @@ const packages: GenericPackage[] = [
285
290
  credits: '120',
286
291
  base_credits: '100',
287
292
  bonus_credits: '20',
288
- bonus_percentage: 20,
289
- day_limit: 1,
290
- package_type: 'iceBreaker',
293
+ bonus_percentage: 20, // Show "+20%" badge
294
+ package_type: 'iceBreaker', // Display "One-time Only"
295
+ },
296
+ {
297
+ id: 'pkg_emergency',
298
+ name: 'Emergency Pack',
299
+ price: '0.99',
300
+ currency: 'USD',
301
+ credits: '240',
302
+ package_type: 'emergency',
291
303
  },
292
304
  ];
293
305
 
294
- // 创建弹窗
295
306
  const modal = new GenericPackageModal({
296
- language: 'zh-CN',
297
307
  packages: packages,
308
+ language: 'en',
298
309
 
299
310
  sdkConfig: {
300
311
  environment: 'development',
301
- countryCode: 'SG',
302
312
  accountToken: 'user-token',
303
313
  },
304
314
 
305
315
  onPaymentSuccess: (orderId, transactionId, pkg) => {
306
- console.log(`${pkg.name} 购买成功!`, { orderId, transactionId });
307
- },
308
-
309
- onPaymentFailed: (error, pkg) => {
310
- console.error(`${pkg.name} 购买失败:`, error.message);
316
+ console.log(`${pkg.name} purchased successfully!`);
311
317
  },
312
318
  });
313
319
 
314
320
  modal.open();
315
321
  ```
316
322
 
317
- #### GenericPackage 接口定义
323
+ #### GenericPackage Interface
318
324
 
319
325
  ```typescript
320
326
  interface GenericPackage {
321
- // 基础信息(必填)
322
- id: string; // 套餐唯一标识
323
- name: string; // 套餐名称
324
- price: string; // 价格(字符串,支持小数)
325
- currency: string; // 货币代码(如 'USD'
326
- credits: string; // 总积分数
327
-
328
- // 奖励信息(可选)
329
- base_credits?: string; // 基础积分
330
- bonus_credits?: string; // 奖励积分
331
- bonus_percentage?: number; // 奖励百分比(如 20 表示 +20%)
332
-
333
- // 购买限制(可选,仅用于展示,后端验证)
334
- day_limit?: number; // 每日限购次数(0 = 无限制)
335
- lifetime_limit?: number; // 终身限购次数(0 = 无限制)
336
-
337
- // 分类标识(可选)
327
+ // Required fields
328
+ id: string; // Unique package identifier
329
+ name: string; // Package name
330
+ price: string; // Price (string to support decimals)
331
+ currency: string; // Currency code (e.g., 'USD')
332
+ credits: string; // Total credits
333
+
334
+ // Optional bonus fields
335
+ base_credits?: string; // Base credits
336
+ bonus_credits?: string; // Bonus credits
337
+ bonus_percentage?: number; // Bonus percentage (e.g., 20 for +20%)
338
+
339
+ // Optional classification
338
340
  package_type?: 'iceBreaker' | 'emergency' | 'firstCharge' | 'custom';
339
341
  }
340
342
  ```
341
343
 
342
- #### 预定义套餐示例
344
+ ---
345
+
346
+ ### PaymentCheckoutModal - Checkout System
347
+
348
+ **Use Cases**:
349
+ - ✅ Full checkout experience with payment method selection
350
+ - ✅ Support for multiple payment types (Link, Dropin, BindCard)
351
+ - ✅ Auto order creation and payment
352
+ - ✅ Advanced customization and control
343
353
 
344
- SDK 提供以下预定义套餐供参考:
354
+ #### Basic Usage
345
355
 
346
356
  ```typescript
347
- import {
348
- EXAMPLE_ICE_BREAKER, // 破冰包
349
- EXAMPLE_EMERGENCY, // 告急包
350
- EXAMPLE_FIRST_CHARGE, // 首充包
351
- EXAMPLE_PACKAGES, // 所有示例套餐数组
352
- } from '@seaverse/payment-sdk';
357
+ import { PaymentCheckoutModal, PRODUCT_TYPE } from '@seaverse/payment-sdk';
358
+
359
+ const modal = new PaymentCheckoutModal({
360
+ // Product information
361
+ product: {
362
+ id: 'pkg_credit_100',
363
+ name: '100 Credits Package',
364
+ price: 9.99,
365
+ currency: 'USD',
366
+ type: PRODUCT_TYPE.CREDITPACK, // CREDITPACK | SUBSCRIPTION | CHANGE_SUBSCRIPTION
367
+ },
353
368
 
354
- // 使用预定义套餐
355
- const modal = new GenericPackageModal({
356
- packages: [EXAMPLE_ICE_BREAKER, EXAMPLE_EMERGENCY],
357
- sdkConfig: { /* ... */ },
369
+ // Auto create order (recommended)
370
+ autoCreateOrder: {
371
+ productId: 'pkg_credit_100',
372
+ purchaseType: 1, // 1 = one-time, 2 = subscription
373
+ apiHost: 'https://payment.seaverse.com',
374
+ accountToken: 'user-token',
375
+ clientId: 'your-client-id',
376
+ language_code: 'en',
377
+ },
378
+
379
+ // Optional configuration
380
+ accountName: 'John Doe', // Display in order summary
381
+ language: 'en',
382
+
383
+ // Callbacks
384
+ onPaymentSuccess: (payload) => {
385
+ console.log('Payment successful!', payload);
386
+ },
387
+
388
+ onPaymentFailed: (error) => {
389
+ console.error('Payment failed:', error.message);
390
+ },
391
+
392
+ onPaymentMethodSelect: (method) => {
393
+ console.log('Payment method selected:', method.payment_method_name);
394
+ },
395
+
396
+ onLinkPaymentStart: (methodName) => {
397
+ console.log('Link payment started:', methodName);
398
+ // Show "Please complete payment in new window" message
399
+ },
400
+
401
+ onLoading: (loading) => {
402
+ console.log('Loading state:', loading);
403
+ },
358
404
  });
405
+
406
+ modal.open();
359
407
  ```
360
408
 
361
- **预定义套餐详情**:
409
+ #### Payment Methods Supported
410
+
411
+ 1. **Link Payment** (payment_type = 1)
412
+ - Redirect to external payment page
413
+ - Auto order status polling
414
+ - Verification modal after redirect
415
+
416
+ 2. **Dropin Payment** (payment_type = 2)
417
+ - Embedded payment form
418
+ - Support credit cards, PayPal, etc.
419
+ - Inline validation and submission
420
+
421
+ 3. **BindCard Payment** (payment_type = 2 with saved cards)
422
+ - Display saved payment methods
423
+ - Quick payment with saved cards
424
+ - Add new card option
362
425
 
363
- | 套餐 | 价格 | 积分 | 限制 | 说明 |
364
- | ---------------------- | ----- | ---- | ------- | ------------------------ |
365
- | `EXAMPLE_ICE_BREAKER` | $0.49 | 120 | 每日1次 | 破冰包 - 超低价首次破冰 |
366
- | `EXAMPLE_EMERGENCY` | $0.99 | 240 | 每日3次 | 告急包 - 日常转化主力 |
367
- | `EXAMPLE_FIRST_CHARGE` | $1.99 | 620 | 终身1次 | 首充包 - 提升首充用户LTV |
426
+ #### Auto-Selection Strategy (Fixed in v0.9.0)
427
+
428
+ The checkout modal intelligently handles payment method selection:
429
+
430
+ - **When Dropin available**: Auto-select first Dropin and render payment form
431
+ - ✅ **When only Link available**: Wait for user manual selection (no auto-execution)
432
+ - ✅ **Prevents issue**: No more instant redirect before users see checkout
368
433
 
369
434
  ---
370
435
 
371
- ### PurchaseSuccessModal - 购买成功弹窗
436
+ ### PurchaseSuccessModal - Purchase Success
372
437
 
373
- **✨ 自动集成** - 无需手动调用,在 `CreditPackageModal` `GenericPackageModal` 支付成功后自动显示。
438
+ **✨ Auto-integrated** - Automatically displays after successful payment in CreditPackageModal and GenericPackageModal.
374
439
 
375
- #### 功能特性
440
+ #### Features
376
441
 
377
- - ✅ 邮件确认卡片风格设计
378
- - ✅ 精美动画效果(淡入淡出、缩放、顺序动画)
379
- - ✅ 显示购买详情(套餐名称、积分数、支付金额)
380
- - ✅ 支持 ESC 键、点击遮罩、关闭按钮关闭
381
- - ✅ 自动阻止 body 滚动
382
- - ✅ 支持中英文切换
442
+ - ✅ Email confirmation card design
443
+ - ✅ Beautiful animations (fade in/out, scale, sequential)
444
+ - ✅ Display purchase details (package name, credits, amount)
445
+ - ✅ Support ESC key, overlay click, close button
446
+ - ✅ Auto prevent body scroll
447
+ - ✅ Multi-language support (13+ languages)
383
448
 
384
- #### 自动触发流程
449
+ #### Auto-trigger Flow
385
450
 
386
451
  ```
387
- 用户点击购买按钮
452
+ User clicks purchase button
388
453
 
389
- 支付成功
454
+ Payment successful
390
455
 
391
- CreditPackageModal/GenericPackageModal 关闭
456
+ CreditPackageModal/GenericPackageModal closes
392
457
 
393
- PurchaseSuccessModal 自动显示(带动画)
458
+ PurchaseSuccessModal displays (with animation)
394
459
 
395
- 用户关闭成功弹窗
460
+ User closes success modal
396
461
 
397
- 自动刷新积分余额
462
+ Auto credit balance refresh
398
463
 
399
- 触发 onPaymentSuccess 回调
464
+ Trigger onPaymentSuccess callback
400
465
  ```
401
466
 
402
- #### 手动使用(可选)
403
-
404
- 如需在其他场景手动调用:
467
+ #### Manual Usage (Optional)
405
468
 
406
469
  ```typescript
407
470
  import { PurchaseSuccessModal } from '@seaverse/payment-sdk';
408
471
 
409
- const successModal = new PurchaseSuccessModal({
472
+ const modal = new PurchaseSuccessModal({
410
473
  data: {
411
474
  packName: 'Ice Breaker Pack',
412
475
  credits: 120,
413
476
  amount: '0.49',
414
- currency: '$',
477
+ currency: '$', // Auto-converted from currency code
415
478
  orderId: 'order_123',
416
479
  transactionId: 'txn_456',
417
480
  },
418
- language: 'zh-CN',
481
+ language: 'en',
419
482
  onClose: () => {
420
- console.log('成功弹窗关闭');
483
+ console.log('Success modal closed');
421
484
  },
422
485
  });
423
486
 
424
- successModal.open();
487
+ modal.open();
425
488
  ```
426
489
 
427
490
  ---
428
491
 
429
- ## 🔍 高级功能
492
+ ## 🌍 Internationalization
430
493
 
431
- ### 积分查询(PaymentClient)
494
+ ### Supported Languages (13+)
432
495
 
433
- 查询用户积分余额和交易记录:
496
+ | Language | Code | Country Mapping |
497
+ |----------|------|-----------------|
498
+ | English | `en` | US |
499
+ | Simplified Chinese | `zh` | CN |
500
+ | Traditional Chinese | `zh-TW` | TW |
501
+ | Japanese | `ja` | JP |
502
+ | Korean | `ko` | KR |
503
+ | Spanish | `es` | ES |
504
+ | French | `fr` | FR |
505
+ | German | `de` | DE |
506
+ | Portuguese | `pt` | PT |
507
+ | Russian | `ru` | RU |
508
+ | Arabic | `ar` | SA |
509
+ | Hindi | `hi` | IN |
510
+ | Indonesian | `id` | ID |
434
511
 
435
- ```typescript
436
- import { PaymentClient } from '@seaverse/payment-sdk';
437
-
438
- const client = new PaymentClient({
439
- appId: 'seaverse',
440
- token: 'your-bearer-token',
441
- baseURL: 'https://payment.sg.seaverse.dev', // 可选
442
- });
512
+ ### Language Auto-Mapping
443
513
 
444
- // 查询积分详情(4 池结构)
445
- const detail = await client.getCreditDetail();
446
- console.log('总余额:', detail.total_balance);
447
-
448
- detail.pools.forEach(pool => {
449
- console.log(`${pool.type} 池:${pool.balance} 积分`);
450
- });
514
+ The SDK automatically maps language codes to country codes for payment method retrieval:
451
515
 
452
- // 查询交易记录
453
- const transactions = await client.listTransactions({
454
- page: 1,
455
- page_size: 20,
456
- start_time: '2024-01-01T00:00:00Z',
457
- end_time: '2024-12-31T23:59:59Z',
516
+ ```typescript
517
+ // User sets language
518
+ const modal = new CreditPackageModal({
519
+ language: 'ja', // Japanese
520
+ sdkConfig: { /* ... */ }
458
521
  });
459
522
 
460
- transactions.transactions.forEach(txn => {
461
- console.log(`${txn.type}: ${txn.amount} 积分`);
462
- });
523
+ // SDK automatically uses country_code: 'JP' when fetching payment methods
463
524
  ```
464
525
 
465
- #### 4 池积分系统
466
-
467
- | 池类型 | 说明 | 过期时间 |
468
- | ----------- | -------- | -------------- |
469
- | `daily` | 每日积分 | 次日 00:00 UTC |
470
- | `event` | 活动积分 | 活动截止日期 |
471
- | `monthly` | 月度积分 | 授予后 30 天 |
472
- | `permanent` | 永久积分 | 永不过期 |
526
+ ### Custom Language Handling
473
527
 
474
- **消费优先级**:Daily Event Monthly Permanent
475
-
476
- ---
477
-
478
- ### 订阅管理
479
-
480
- 查询和管理用户订阅:
528
+ For SDK initialization, some languages require special formatting:
481
529
 
482
530
  ```typescript
483
- import {
484
- getCurrentSubscription,
485
- getActiveSubscription,
486
- changeSubscription,
487
- restartSubscription,
488
- } from '@seaverse/payment-sdk';
489
-
490
- const apiUrl = 'https://payment.sg.seaverse.dev';
491
- const token = 'user-token';
492
-
493
- // 查询当前订阅状态
494
- const current = await getCurrentSubscription(apiUrl, token);
495
- console.log('订阅状态:', current.subscription_status);
496
-
497
- // 查询活跃订阅详情
498
- const active = await getActiveSubscription(apiUrl, token);
499
- console.log('当前套餐:', active.product_name);
500
-
501
- // 升级/降级订阅
502
- const changeResult = await changeSubscription(apiUrl, token, {
503
- productId: 'pro_plan',
504
- billingPeriod: 'year',
505
- redirectUrl: window.location.href,
506
- });
507
-
508
- // 重启已取消的订阅
509
- const restartResult = await restartSubscription(apiUrl, token, {
510
- subscriptionId: 'sub_123',
511
- });
531
+ // SDK Language Format Conversion
532
+ 'zh' → 'zhCN' // Simplified Chinese
533
+ 'zh-TW' → 'zhTW' // Traditional Chinese
534
+ 'en' → 'en' // English (no conversion)
535
+ 'ja' → 'ja' // Japanese (no conversion)
536
+ // ... other languages use code directly
512
537
  ```
513
538
 
514
539
  ---
515
540
 
516
- ### 订单管理
517
-
518
- 检查订单状态和轮询支付结果:
519
-
520
- ```typescript
521
- import { checkOrderStatus, pollOrderStatus } from '@seaverse/payment-sdk';
522
-
523
- const apiUrl = 'https://payment.sg.seaverse.dev';
524
- const token = 'user-token';
541
+ ## ⚙️ Configuration
525
542
 
526
- // 单次查询订单状态
527
- const status = await checkOrderStatus('transaction_id', apiUrl, token);
528
- console.log('订单状态:', status.order_status);
543
+ ### Environment Configuration
529
544
 
530
- // 轮询订单状态直到最终状态
531
- const finalStatus = await pollOrderStatus('transaction_id', apiUrl, token, {
532
- interval: 2000, // 轮询间隔(毫秒)
533
- maxAttempts: 30, // 最大尝试次数
534
- onPoll: (status, attempt) => {
535
- console.log(`第 ${attempt} 次查询:${status}`);
536
- },
537
- });
545
+ The SDK auto-configures based on `environment`:
538
546
 
539
- console.log('最终状态:', finalStatus.order_status);
547
+ **Development**:
548
+ ```typescript
549
+ {
550
+ scriptUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/client.js',
551
+ clientId: 'XF49NOfyZ54O16GujB0ptio2',
552
+ orderApiUrl: 'https://payment.sg.seaverse.dev',
553
+ walletApiUrl: 'https://wallet.sg.seaverse.dev',
554
+ cssUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/client.css',
555
+ }
540
556
  ```
541
557
 
542
- ---
543
-
544
- ### SeaartPayment SDK(完全自定义)
545
-
546
- 适用于需要完全控制支付流程的高级场景:
547
-
558
+ **Production**:
548
559
  ```typescript
549
- import { SeaartPaymentSDK } from '@seaverse/payment-sdk';
550
-
551
- // 1. 初始化 SDK(应用启动时)
552
- const sdk = SeaartPaymentSDK.getInstance();
553
- await sdk.init({
554
- scriptUrl: 'https://your-cdn.com/seaart-payment.js',
555
- clientId: 'your-client-id',
556
- language: 'en',
557
- cssUrl: 'https://your-cdn.com/seaart-payment.css', // 可选
558
- });
559
-
560
- // 2. 获取支付方式
561
- const methods = await sdk.getPaymentMethods({
562
- country_code: 'US',
563
- business_type: 2, // 1=一次性, 2=订阅
564
- });
560
+ {
561
+ scriptUrl: 'https://payment-static.seaverse.com/sdk/seaart-payment-component.js',
562
+ clientId: 'prod_client_id',
563
+ orderApiUrl: 'https://payment.seaverse.com',
564
+ walletApiUrl: 'https://wallet.seaverse.com',
565
+ cssUrl: 'https://payment-static.seaverse.com/sdk/seaart-payment-component.css',
566
+ }
567
+ ```
565
568
 
566
- // 3. 创建订单支付实例
567
- const orderPayment = sdk.createOrderPayment({
568
- orderId: 'order-123',
569
- accountToken: 'user-token',
570
- });
569
+ ### PaymentSDKConfig Interface
571
570
 
572
- // 4a. 跳转支付(Link Payment)
573
- const linkMethod = methods.find(m => m.payment_type === 1);
574
- const linkPayment = orderPayment.createLinkPayment(linkMethod, {
575
- callback_url: `${window.location.origin}/payment-callback`,
576
- });
577
- await linkPayment.redirectToPayment();
578
-
579
- // 4b. 嵌入式支付(Dropin Payment)
580
- const dropinMethod = methods.find(m => m.payment_type === 2);
581
- const dropinPayment = orderPayment.createDropinPayment(dropinMethod, {
582
- containerId: '#payment-container',
583
- onCompleted: (payload) => {
584
- console.log('支付成功:', payload);
585
- },
586
- onFailed: (payload) => {
587
- console.error('支付失败:', payload);
588
- },
589
- });
590
- await dropinPayment.render();
591
-
592
- // 5. 处理支付回调(回调页面)
593
- const result = await sdk.handleCallback(
594
- { type: 'subscription' },
595
- 'https://payment-api.com',
596
- 'auth-token'
597
- );
598
- if (result.success) {
599
- console.log('支付验证成功:', result.data);
571
+ ```typescript
572
+ interface PaymentSDKConfig {
573
+ // Required
574
+ environment: 'development' | 'production';
575
+ accountToken: string;
576
+
577
+ // Optional (with sensible defaults)
578
+ businessType?: 1 | 2; // 1 = one-time, 2 = subscription
579
+ scriptTimeout?: number; // Default: 10000ms
580
+ paymentMethodType?: string; // Default: 'dropin'
581
+
582
+ // Advanced overrides
583
+ scriptUrl?: string; // Override environment config
584
+ clientId?: string; // Override environment config
585
+ orderApiUrl?: string; // Override environment config
586
+ cssUrl?: string; // Override environment config
600
587
  }
601
588
  ```
602
589
 
603
590
  ---
604
591
 
605
- ### DropinPaymentModal - Dropin 支付弹框(带挽留功能)
606
-
607
- **适用场景**:
608
- - ✅ 需要弹框形式的 Dropin 支付(无需自己创建弹框容器)
609
- - ✅ 支持用户取消支付时的挽留弹框(可选)
610
- - ✅ 自动处理弹框打开/关闭/清理逻辑
592
+ ## 🔍 Advanced Features
611
593
 
612
- #### 基础用法
594
+ ### Credit Query
613
595
 
614
596
  ```typescript
615
- import { SeaartPaymentSDK, DropinPaymentModal } from '@seaverse/payment-sdk';
616
-
617
- // 1. 初始化 SDK
618
- const sdk = SeaartPaymentSDK.getInstance();
619
- await sdk.init({
620
- scriptUrl: 'https://your-cdn.com/seaart-payment.js',
621
- clientId: 'your-client-id',
622
- language: 'en',
623
- });
624
-
625
- // 2. 获取支付方式
626
- const methods = await sdk.getPaymentMethods({
627
- country_code: 'US',
628
- business_type: 1, // 1=一次性购买
629
- });
630
-
631
- // 3. 创建订单支付实例
632
- const orderPayment = sdk.createOrderPayment({
633
- orderId: 'order-123',
634
- accountToken: 'user-token',
635
- });
636
-
637
- // 4. 选择 Dropin 支付方式
638
- const dropinMethod = methods.find(m => m.payment_type === 2);
597
+ import { getCreditDetail } from '@seaverse/payment-sdk';
639
598
 
640
- // 5. 创建 Dropin 支付弹框
641
- const modal = new DropinPaymentModal(
642
- orderPayment,
643
- 'order-123',
644
- 'user-token',
645
- dropinMethod,
646
- {
647
- // 弹框配置
648
- modalTitle: `Pay with ${dropinMethod.payment_method_name}`,
649
- enableRetention: true, // 启用挽留弹框(默认:true)
650
-
651
- // 挽留弹框配置
652
- retentionOptions: {
653
- language: 'en', // 'en' | 'zh-CN'
654
- bonusAmount: 990, // 活动赠送积分(可选)
655
- },
656
-
657
- // 支付回调
658
- onCompleted: (payload) => {
659
- console.log('支付成功!', payload);
660
- // 刷新积分、更新 UI 等
661
- },
662
-
663
- onFailed: (payload) => {
664
- console.error('支付失败:', payload);
665
- },
666
-
667
- onLoading: (loading) => {
668
- console.log('加载状态:', loading);
669
- },
670
- }
671
- );
599
+ const apiHost = 'https://wallet.seaverse.com';
600
+ const token = 'user-token';
672
601
 
673
- // 6. 打开弹框
674
- await modal.open();
602
+ const detail = await getCreditDetail(apiHost, token);
675
603
 
676
- // 可选:手动关闭弹框
677
- // modal.close();
604
+ console.log('Total balance:', detail.total_balance);
605
+ console.log('Tier:', detail.tier);
678
606
 
679
- // 可选:检查弹框状态
680
- // console.log('弹框是否打开:', modal.isOpen());
607
+ detail.pools.forEach(pool => {
608
+ console.log(`${pool.type} pool: ${pool.balance} credits`);
609
+ });
681
610
  ```
682
611
 
683
- #### 挽留弹框流程说明
612
+ #### Credit Pool System
684
613
 
685
- 当用户尝试取消支付时(点击关闭按钮或 ESC 键),会触发以下流程:
614
+ | Pool Type | Description | Expiration |
615
+ |-----------|-------------|------------|
616
+ | `daily` | Daily credits | Next day 00:00 UTC |
617
+ | `event` | Event credits | Event end date |
618
+ | `monthly` | Monthly credits | 30 days after grant |
619
+ | `permanent` | Permanent credits | Never expires |
686
620
 
687
- 1. **关闭支付弹框**支付弹框关闭
688
- 2. **显示挽留弹框** → 自动弹出挽留弹框,展示:
689
- - 订单详情(商品名称、购买数量、优惠价格)
690
- - 倒计时提示(15分钟订单过期时间)
691
- - 活动赠送(如果有)
692
- 3. **用户选择**:
693
- - **继续支付**:关闭挽留弹框 → 重新打开支付弹框
694
- - **确认取消**:关闭所有弹框 → 清理资源
621
+ **Consumption Priority**: Daily Event → Monthly → Permanent
695
622
 
696
- #### 配置选项
623
+ ### Subscription Management
697
624
 
698
625
  ```typescript
699
- interface DropinPaymentModalOptions {
700
- // 弹框标题
701
- modalTitle?: string;
702
-
703
- // 弹框选项
704
- modalOptions?: {
705
- showCloseButton?: boolean; // 显示关闭按钮(默认:true)
706
- closeOnOverlayClick?: boolean; // 点击遮罩关闭(默认:false)
707
- closeOnEsc?: boolean; // ESC 键关闭(默认:false)
708
- className?: string; // 自定义类名
709
- maxWidth?: string; // 最大宽度(默认:'600px')
710
- };
711
-
712
- // 是否启用挽留弹框(默认:true)
713
- enableRetention?: boolean;
714
-
715
- // 挽留弹框配置
716
- retentionOptions?: {
717
- language?: 'en' | 'zh-CN'; // 语言(默认:'en')
718
- bonusAmount?: number; // 活动赠送积分(可选)
719
- };
720
-
721
- // 支付回调
722
- onSubmit?: (payload: any) => void;
723
- onError?: (payload: any, error: any) => void;
724
- onCreateOrder?: (payload: any) => void;
725
- onCompleted?: (payload: any) => void;
726
- onFailed?: (payload: any) => void;
727
- onLoading?: (loading: boolean) => void;
728
- }
729
- ```
730
-
731
- #### 挽留弹框预览
732
-
733
- 挽留弹框采用深色卡片设计,包含:
734
- - 订单倒计时(15 分钟)
735
- - 商品信息(名称、购买数量、活动赠送、优惠价)
736
- - 价格显示(自动根据货币代码映射符号,如 USD→$, EUR→€, JPY→¥ 等)
737
- - 两个按钮:「取消」和「继续支付」(使用与积分弹框一致的绿色渐变主题色)
626
+ import {
627
+ getCurrentSubscription,
628
+ getActiveSubscription,
629
+ changeSubscription,
630
+ } from '@seaverse/payment-sdk';
738
631
 
739
- **支持的货币符号**:
740
- - 美元 (USD) → $
741
- - 欧元 (EUR) → €
742
- - 英镑 (GBP) → £
743
- - 日元 (JPY) / 人民币 (CNY) → ¥
744
- - 新加坡元 (SGD) → S$
745
- - 港币 (HKD) → HK$
746
- - 等 30+ 种货币符号...
632
+ const apiUrl = 'https://payment.seaverse.com';
633
+ const token = 'user-token';
747
634
 
748
- #### 禁用挽留弹框
635
+ // Query current subscription status
636
+ const current = await getCurrentSubscription(apiUrl, token);
637
+ console.log('Status:', current.subscription_status);
749
638
 
750
- 如果不需要挽留功能,可以禁用:
639
+ // Get active subscription details
640
+ const active = await getActiveSubscription(apiUrl, token);
641
+ console.log('Plan:', active.product_name);
751
642
 
752
- ```typescript
753
- const modal = new DropinPaymentModal(
754
- orderPayment,
755
- 'order-123',
756
- 'user-token',
757
- dropinMethod,
758
- {
759
- enableRetention: false, // 禁用挽留弹框
760
- onCompleted: (payload) => {
761
- console.log('支付成功!', payload);
762
- },
763
- }
764
- );
643
+ // Upgrade/downgrade subscription
644
+ const result = await changeSubscription(apiUrl, token, {
645
+ productId: 'pro_plan',
646
+ billingPeriod: 'year',
647
+ redirectUrl: window.location.href,
648
+ });
765
649
  ```
766
650
 
767
- ---
651
+ ### Order Status Tracking
768
652
 
769
- ## ⚙️ 配置选项
653
+ ```typescript
654
+ import { checkOrderStatus, pollOrderStatus } from '@seaverse/payment-sdk';
770
655
 
771
- ### 环境配置(Environment)
656
+ const apiUrl = 'https://payment.seaverse.com';
657
+ const token = 'user-token';
658
+ const transactionId = 'txn_123';
772
659
 
773
- | 环境 | 值 | 说明 |
774
- | -------- | --------------- | ------------ |
775
- | 开发环境 | `'development'` | 开发测试环境 |
776
- | 生产环境 | `'production'` | 正式生产环境 |
660
+ // Single status check
661
+ const status = await checkOrderStatus(transactionId, apiUrl, token);
662
+ console.log('Order status:', status.order_status);
777
663
 
778
- ### SDK 配置(sdkConfig)
664
+ // Poll until final status
665
+ const finalStatus = await pollOrderStatus(transactionId, apiUrl, token, {
666
+ interval: 2000, // Poll interval (ms)
667
+ maxAttempts: 30, // Max attempts
668
+ onPoll: (status, attempt) => {
669
+ console.log(`Attempt ${attempt}: ${status}`);
670
+ },
671
+ });
779
672
 
780
- ```typescript
781
- interface PaymentSDKConfig {
782
- // 必填参数
783
- environment: 'development' | 'production'; // 环境变量
784
- countryCode: string; // 国家代码(ISO 3166-1)
785
-
786
- // 可选参数
787
- accountToken?: string; // 用户认证令牌
788
- businessType?: 1 | 2; // 1=一次性购买, 2=订阅(默认 1)
789
-
790
- // 高级选项(覆盖环境配置)
791
- scriptUrl?: string; // 自定义脚本 URL
792
- clientId?: string; // 自定义客户端 ID
793
- orderApiUrl?: string; // 自定义订单 API 地址
794
- cssUrl?: string; // 自定义 CSS URL
795
- scriptTimeout?: number; // 脚本加载超时(默认 10000ms)
796
- paymentMethodType?: string; // 支付方式类型过滤(默认 'dropin')
797
- }
673
+ console.log('Final status:', finalStatus.order_status);
798
674
  ```
799
675
 
800
676
  ---
801
677
 
802
- ## 🎨 UI 反馈工具
678
+ ## 🎨 UI Feedback Utilities
803
679
 
804
- SDK 提供统一的 UI 反馈工具,替代浏览器原生 `alert()`:
680
+ SDK provides unified UI feedback tools (replacement for browser `alert()`):
805
681
 
806
682
  ```typescript
807
683
  import {
@@ -812,46 +688,44 @@ import {
812
688
  hideLoadingIndicator,
813
689
  } from '@seaverse/payment-sdk';
814
690
 
815
- // 错误提示(红色渐变背景)
816
- showErrorMessage('支付失败,请重试', 3000);
691
+ // Error message (red gradient)
692
+ showErrorMessage('Payment failed, please try again', 3000);
817
693
 
818
- // 成功提示(绿色渐变背景)
819
- showSuccessMessage('支付成功!', 3000);
694
+ // Success message (green gradient)
695
+ showSuccessMessage('Payment successful!', 3000);
820
696
 
821
- // 信息提示(蓝色渐变背景)
822
- showInfoMessage('正在处理您的请求...', 3000);
697
+ // Info message (blue gradient)
698
+ showInfoMessage('Processing your request...', 3000);
823
699
 
824
- // 加载指示器
825
- const loader = showLoadingIndicator('初始化支付系统...');
826
- // ... 异步操作
700
+ // Loading indicator
701
+ const loader = showLoadingIndicator('Initializing payment system...');
702
+ // ... async operation
827
703
  hideLoadingIndicator(loader);
828
704
  ```
829
705
 
830
- **特性**:
831
- - ✅ 精美渐变背景 + 图标
832
- - ✅ 自动淡入淡出动画
833
- - ✅ 自动移除(可配置时长)
834
- - ✅ 防止重复显示
835
- - ✅ XSS 防护
706
+ **Features**:
707
+ - ✅ Beautiful gradient backgrounds + icons
708
+ - ✅ Auto fade in/out animations
709
+ - ✅ Auto removal (configurable duration)
710
+ - ✅ Prevent duplicate display
711
+ - ✅ XSS protection
836
712
 
837
713
  ---
838
714
 
839
- ## 🛡️ 错误处理
715
+ ## 🛡️ Error Handling
840
716
 
841
- ### 业务错误码(BIZ_CODE)
717
+ ### Common Error Codes
842
718
 
843
- | 错误码 | 常量 | 说明 |
844
- | ------ | ---------------------- | ------------ |
845
- | `0` | `SUCCESS` | 操作成功 |
846
- | `400` | `BAD_REQUEST` | 请求参数错误 |
847
- | `401` | `UNAUTHORIZED` | 未授权 |
848
- | `500` | `SERVER_ERROR` | 服务器错误 |
849
- | `4001` | `DAILY_LIMIT_EXCEEDED` | 超过每日限额 |
850
- | `4002` | `PRODUCT_NOT_FOUND` | 产品不存在 |
851
- | `4004` | `INSUFFICIENT_BALANCE` | 余额不足 |
852
- | `4005` | `ORDER_NOT_FOUND` | 订单不存在 |
719
+ | Code | Constant | Description |
720
+ |------|----------|-------------|
721
+ | `0` | `SUCCESS` | Success |
722
+ | `400` | `BAD_REQUEST` | Invalid parameters |
723
+ | `401` | `UNAUTHORIZED` | Unauthorized |
724
+ | `500` | `SERVER_ERROR` | Server error |
725
+ | `4001` | `DAILY_LIMIT_EXCEEDED` | Daily limit exceeded |
726
+ | `4002` | `PRODUCT_NOT_FOUND` | Product not found |
853
727
 
854
- ### 错误处理示例
728
+ ### Error Handling Example
855
729
 
856
730
  ```typescript
857
731
  const modal = new GenericPackageModal({
@@ -859,13 +733,12 @@ const modal = new GenericPackageModal({
859
733
  sdkConfig: { /* ... */ },
860
734
 
861
735
  onPaymentFailed: (error, pkg) => {
862
- // 处理限额错误
863
- if (error.message.includes('Daily limit')) {
864
- showErrorMessage(`您已达到 ${pkg.name} 的每日购买限额`);
865
- } else if (error.message.includes('Lifetime limit')) {
866
- showErrorMessage('此套餐仅限购买一次,您已购买过');
736
+ if (error.message.includes('limit')) {
737
+ showErrorMessage(`Daily limit reached for ${pkg.name}`);
738
+ } else if (error.message.includes('payment')) {
739
+ showErrorMessage('Payment processing failed');
867
740
  } else {
868
- showErrorMessage(`支付失败:${error.message}`);
741
+ showErrorMessage(`Error: ${error.message}`);
869
742
  }
870
743
  },
871
744
  });
@@ -873,64 +746,22 @@ const modal = new GenericPackageModal({
873
746
 
874
747
  ---
875
748
 
876
- ## 🧪 测试卡号(开发环境)
877
-
878
- 在开发环境测试支付功能:
879
-
880
- | 字段 | 值 |
881
- | -------- | ------------------ |
882
- | 卡号 | `4212345678910006` |
883
- | 有效期 | `03/30` |
884
- | CVC | `737` |
885
- | 3DS 密码 | `password` |
886
-
887
- ---
888
-
889
- ## 📊 API 对比表
890
-
891
- ### CreditPackageModal vs GenericPackageModal
892
-
893
- | 特性 | CreditPackageModal | GenericPackageModal |
894
- | -------------- | ------------------ | --------------------------------- |
895
- | **套餐数据** | 内置预设套餐 | 外部配置(灵活) |
896
- | **套餐类型** | 标准积分套餐 | 任意类型(破冰/告急/首充/自定义) |
897
- | **购买限制** | 无 | 支持每日/终身限购 |
898
- | **奖励展示** | 无 | 支持奖励百分比 |
899
- | **配置复杂度** | ⭐️ 简单 | ⭐️⭐️ 中等 |
900
- | **使用场景** | 标准积分购买 | 特殊促销、限时活动 |
901
-
902
- **选择建议**:
903
- - 🎯 **标准积分购买** → 使用 `CreditPackageModal`(推荐新手)
904
- - 🎁 **特殊促销活动** → 使用 `GenericPackageModal`
905
-
906
- ---
907
-
908
- ## 🔄 迁移指南
909
-
910
- ### 从 v0.8.x 迁移到 v0.9.x
749
+ ## 🧪 Testing
911
750
 
912
- **主要变化**:引入环境配置,简化参数
751
+ ### Test Card Numbers (Development Only)
913
752
 
914
- ```typescript
915
- // ✅ 新版本(v0.8.x)
916
- const modal = new GenericPackageModal({
917
- packages: packages,
918
- sdkConfig: {
919
- environment: 'development', // 只需指定环境
920
- countryCode: 'SG', // 扁平化参数
921
- businessType: 1, // 可选,默认 1
922
- },
923
- });
924
- ```
753
+ For testing payment functionality in development environment:
925
754
 
926
- **参数变化**:
927
- - ✅ 新增:`environment` - 自动配置所有 URL
928
- - 简化:`countryCode` - `paymentMethodsParams.country_code` 扁平化
929
- - 简化:`businessType` - 从 `paymentMethodsParams.business_type` 扁平化
755
+ | Field | Value |
756
+ |-------|-------|
757
+ | Card Number | `4212345678910006` |
758
+ | Expiry | `03/30` |
759
+ | CVC | `737` |
760
+ | 3DS Password | `password` |
930
761
 
931
762
  ---
932
763
 
933
- ## 🌐 框架集成
764
+ ## 🌐 Framework Integration
934
765
 
935
766
  ### Vue 3
936
767
 
@@ -939,16 +770,18 @@ const modal = new GenericPackageModal({
939
770
  import { ref } from 'vue';
940
771
  import { CreditPackageModal } from '@seaverse/payment-sdk';
941
772
 
942
- const showModal = () => {
773
+ const userToken = ref('user-token-here');
774
+
775
+ const openPaymentModal = () => {
943
776
  const modal = new CreditPackageModal({
777
+ language: 'en',
944
778
  sdkConfig: {
945
779
  environment: import.meta.env.DEV ? 'development' : 'production',
946
- countryCode: 'SG',
947
780
  accountToken: userToken.value,
948
781
  },
949
- onPaymentSuccess: (orderId, transactionId) => {
950
- console.log('支付成功', { orderId, transactionId });
951
- // 刷新用户数据
782
+ onPaymentSuccess: (orderId, transactionId, pkg) => {
783
+ console.log('Payment successful', { orderId, transactionId });
784
+ // Refresh user data
952
785
  },
953
786
  });
954
787
  modal.open();
@@ -956,7 +789,7 @@ const showModal = () => {
956
789
  </script>
957
790
 
958
791
  <template>
959
- <button @click="showModal">购买积分</button>
792
+ <button @click="openPaymentModal">Purchase Credits</button>
960
793
  </template>
961
794
  ```
962
795
 
@@ -968,101 +801,170 @@ import { CreditPackageModal } from '@seaverse/payment-sdk';
968
801
  function PurchaseButton() {
969
802
  const handlePurchase = () => {
970
803
  const modal = new CreditPackageModal({
804
+ language: 'en',
971
805
  sdkConfig: {
972
806
  environment: process.env.NODE_ENV === 'development' ? 'development' : 'production',
973
- countryCode: 'SG',
974
807
  accountToken: getUserToken(),
975
808
  },
976
- onPaymentSuccess: (orderId, transactionId) => {
977
- console.log('支付成功', { orderId, transactionId });
978
- // 刷新用户数据
809
+ onPaymentSuccess: (orderId, transactionId, pkg) => {
810
+ console.log('Payment successful', { orderId, transactionId });
811
+ // Refresh user data
979
812
  },
980
813
  });
981
814
  modal.open();
982
815
  };
983
816
 
984
- return <button onClick={handlePurchase}>购买积分</button>;
817
+ return <button onClick={handlePurchase}>Purchase Credits</button>;
985
818
  }
986
819
  ```
987
820
 
821
+ ### Svelte
822
+
823
+ ```svelte
824
+ <script lang="ts">
825
+ import { CreditPackageModal } from '@seaverse/payment-sdk';
826
+
827
+ let userToken = 'user-token-here';
828
+
829
+ function openPaymentModal() {
830
+ const modal = new CreditPackageModal({
831
+ language: 'en',
832
+ sdkConfig: {
833
+ environment: 'development',
834
+ accountToken: userToken,
835
+ },
836
+ onPaymentSuccess: (orderId, transactionId, pkg) => {
837
+ console.log('Payment successful', { orderId, transactionId });
838
+ },
839
+ });
840
+ modal.open();
841
+ }
842
+ </script>
843
+
844
+ <button on:click={openPaymentModal}>Purchase Credits</button>
845
+ ```
846
+
988
847
  ---
989
848
 
990
- ## 📝 TypeScript 支持
849
+ ## 📝 TypeScript Support
991
850
 
992
- SDK 包含完整的 TypeScript 类型定义:
851
+ Full TypeScript type definitions included:
993
852
 
994
853
  ```typescript
995
854
  import type {
996
- // Modal 相关
855
+ // Modal types
997
856
  CreditPackageModalOptions,
998
857
  GenericPackageModalOptions,
999
858
  GenericPackage,
1000
- PurchaseSuccessData,
859
+ CreditPackageItem,
1001
860
 
1002
- // 配置相关
861
+ // Configuration types
1003
862
  PaymentSDKConfig,
1004
863
  Environment,
1005
864
  EnvironmentConfig,
865
+ LocaleCode,
866
+ CountryCode,
1006
867
 
1007
- // 积分相关
1008
- CreditDetailResponse,
1009
- CreditTransaction,
1010
- CreditPoolType,
868
+ // Payment types
869
+ Product,
870
+ ProductType,
871
+ AutoCreateOrderConfig,
872
+ PaymentMethod,
873
+ BindCard,
1011
874
 
1012
- // 订阅相关
875
+ // Response types
876
+ OrderStatusResponse,
877
+ CreditDetailResponse,
1013
878
  CurrentSubscription,
1014
879
  ActiveSubscription,
1015
-
1016
- // 订单相关
1017
- OrderStatus,
1018
- OrderStatusResponse,
1019
880
  } from '@seaverse/payment-sdk';
1020
881
  ```
1021
882
 
1022
883
  ---
1023
884
 
1024
- ## 🔗 相关链接
885
+ ## 📊 Comparison Table
1025
886
 
1026
- - 📦 [NPM Package](https://www.npmjs.com/package/@seaverse/payment-sdk)
1027
- - 🐙 [GitHub Repository](https://github.com/SeaVerseAI/sv-sdk)
1028
- - 📖 [API Documentation](https://github.com/SeaVerseAI/sv-sdk/tree/main/packages/payment-sdk)
1029
- - 🐛 [Issue Tracker](https://github.com/SeaVerseAI/sv-sdk/issues)
887
+ ### CreditPackageModal vs GenericPackageModal vs PaymentCheckoutModal
888
+
889
+ | Feature | CreditPackageModal | GenericPackageModal | PaymentCheckoutModal |
890
+ |---------|-------------------|---------------------|---------------------|
891
+ | **Package Data** | API-fetched | User-provided | User-provided product |
892
+ | **Package Type** | Dynamic credit packs | Custom (promo/special) | Any product type |
893
+ | **Complexity** | ⭐️ Simple | ⭐️⭐️ Medium | ⭐️⭐️⭐️ Advanced |
894
+ | **Use Case** | Standard purchases | Promotions/offers | Full checkout control |
895
+ | **Customization** | Limited | Medium | Full control |
896
+ | **SDK Initialization** | Auto (via PaymentCheckoutModal) | Auto (via PaymentCheckoutModal) | Auto |
897
+ | **Payment Methods** | All supported | All supported | All supported |
898
+
899
+ **Selection Guide**:
900
+ - 🎯 **Standard credit purchases** → Use `CreditPackageModal` (recommended for beginners)
901
+ - 🎁 **Special promotions** → Use `GenericPackageModal`
902
+ - 🔧 **Advanced custom flows** → Use `PaymentCheckoutModal`
1030
903
 
1031
904
  ---
1032
905
 
1033
- ## 📄 许可证
906
+ ## 📄 Changelog
1034
907
 
1035
- MIT License
908
+ ### v0.9.0 (2026-02-07) - Critical Bug Fixes
909
+
910
+ **🔧 Critical Fixes**:
911
+ - Fixed SDK initialization failure when only Link payment methods available
912
+ - Issue: `BasePackageModal.initializeSDK()` required Dropin payment (payment_type === 2)
913
+ - Solution: Override `initializeSDK()` in CreditPackageModal and GenericPackageModal
914
+ - Now PaymentCheckoutModal handles all SDK initialization independently
915
+
916
+ - Fixed Link payment auto-execution issue
917
+ - Issue: `autoSelectDefaultPaymentMethod()` auto-executed Link payment, causing instant redirect
918
+ - Solution: Refined strategy - only auto-select when Dropin exists; wait for manual selection when only Link available
919
+ - Improved UX: Users now see checkout modal before any payment action
920
+
921
+ **🎨 UI/UX Improvements**:
922
+ - Increased payment method card spacing from 8px to 14px
923
+ - Better visual breathing room and click targets
924
+ - Consistent spacing in both skeleton and main UI
925
+
926
+ **📁 Files Changed** (5 files, +86 -53 lines):
927
+ - `CreditPackageModal.ts`: Added `initializeSDK()` and `waitForSDKInitialization()` overrides
928
+ - `GenericPackageModal.ts`: Added `initializeSDK()` and `waitForSDKInitialization()` overrides
929
+ - `PaymentCheckoutModal.ts`: Refined `autoSelectDefaultPaymentMethod()` logic (lines 485-517)
930
+ - `PaymentUIRenderer.ts`: Updated card gap from 8px to 14px (lines 207, 276)
931
+ - `index.ts`: Version bump
932
+
933
+ ### v0.8.2 (2026-02-02) - Architecture Refactoring
934
+
935
+ **🏗️ Architecture**:
936
+ - Created `BasePackageModal` abstract base class
937
+ - Eliminated ~400 lines of duplicate code between CreditPackageModal and GenericPackageModal
938
+ - Improved type safety with TypeScript generics
939
+ - 100% backward compatible - no breaking changes
940
+
941
+ **📦 Package Size**:
942
+ - CreditPackageModal: 1042 lines → 515 lines (50% reduction)
943
+ - GenericPackageModal: 752 lines → 340 lines (55% reduction)
944
+ - Total code reduction: ~25%
1036
945
 
1037
946
  ---
1038
947
 
1039
- ## 🤝 贡献
948
+ ## 🔗 Links
1040
949
 
1041
- 欢迎提交 Issue Pull Request!
950
+ - 📦 [NPM Package](https://www.npmjs.com/package/@seaverse/payment-sdk)
951
+ - 🐙 [GitHub Repository](https://github.com/SeaVerseAI/sv-sdk)
952
+ - 📖 [API Documentation](https://github.com/SeaVerseAI/sv-sdk/tree/main/packages/payment-sdk)
953
+ - 🐛 [Issue Tracker](https://github.com/SeaVerseAI/sv-sdk/issues)
1042
954
 
1043
955
  ---
1044
956
 
1045
- **更新日期**: 2026-02-02
1046
- **SDK 版本**: v0.8.2
957
+ ## 📄 License
1047
958
 
1048
- ## 📝 更新日志
959
+ MIT License
960
+
961
+ ---
1049
962
 
1050
- ### v0.8.2 (2026-02-02)
963
+ ## 🤝 Contributing
1051
964
 
1052
- **架构重构**:
1053
- - 🏗️ 创建 `BasePackageModal` 抽象基类,消除 `CreditPackageModal` 和 `GenericPackageModal` 之间的重复代码
1054
- - 📉 减少约 400 行重复代码(25% 代码量减少)
1055
- - 🎯 `CreditPackageModal`: 从 1042 行减少到 515 行
1056
- - 🎯 `GenericPackageModal`: 从 752 行减少到 340 行
1057
- - ✅ 完全向后兼容,现有代码无需修改
1058
- - 🔒 通过 TypeScript 泛型确保类型安全
965
+ Issues and Pull Requests are welcome!
1059
966
 
1060
- **类型系统改进**:
1061
- - 新增 `BasePackage` 接口 - 所有套餐类型的基础接口
1062
- - 新增 `BasePackageModalOptions<TPackage>` 接口 - 通用配置接口
1063
- - `CreditPackage` 和 `GenericPackage` 现在继承自 `BasePackage`
967
+ ---
1064
968
 
1065
- **开发体验提升**:
1066
- - 更容易添加新的套餐类型(只需继承 `BasePackageModal`)
1067
- - 修复 bug 只需在基类中修改一处
1068
- - 更清晰的职责分离(基类处理逻辑,子类处理 UI)
969
+ **Last Updated**: 2026-02-07
970
+ **SDK Version**: 0.9.0