npm package: @seaverse/payment-sdk
Description: SeaVerse Payment SDK - Credit management, payment checkout, and subscription management
Author: SeaVerse Team
Latest version: 0.9.10

# @seaverse/payment-sdk

> **Version**: 0.9.7 | **Language**: English

A comprehensive payment solution for SeaVerse platform, providing credit management, payment checkout, subscription management, and order tracking.

## 📦 Installation

```bash
npm install @seaverse/payment-sdk
# or
pnpm add @seaverse/payment-sdk
# or
yarn add @seaverse/payment-sdk
```

## 🚀 Quick Start

### 1. Credit Package Modal (Recommended)

The simplest integration - complete payment flow in 3 lines of code:

```typescript
import { CreditPackageModal } from '@seaverse/payment-sdk';

// Create modal
const modal = new CreditPackageModal({
  language: 'en',  // 'en' | 'zh' | 'zh-TW' | 'ja' | 'ko' | 'es' | 'fr' | 'de' | 'pt' | 'ru' | 'ar' | 'hi' | 'id'

  sdkConfig: {
    environment: 'development',     // 'development' | 'production'
    accountToken: 'user-token',     // User authentication token
  },

  onPaymentSuccess: (orderId, transactionId, pkg) => {
    console.log('Payment successful!', { orderId, transactionId, credits: pkg.total_credits });
  },
});

// Open modal
modal.open();
```

**What you get**:
- ✅ Pre-configured credit packages (fetched from API)
- ✅ Automatic SDK initialization
- ✅ Auto order creation
- ✅ Animated success modal
- ✅ Auto credit balance refresh

### 2. Generic Package Modal (Custom Packages)

For promotions, special offers, and custom packages:

```typescript
import { GenericPackageModal, type GenericPackage } from '@seaverse/payment-sdk';

// Define custom packages
const packages: GenericPackage[] = [
  {
    id: 'pkg_ice_breaker',
    name: 'Ice Breaker Pack',
    price: '0.49',
    currency: 'USD',
    credits: '120',
    base_credits: '100',
    bonus_credits: '20',
    bonus_percentage: 20,
    package_type: 'iceBreaker',
  },
];

// Create modal
const modal = new GenericPackageModal({
  packages: packages,
  language: 'en',

  sdkConfig: {
    environment: 'development',
    accountToken: 'user-token',
  },

  onPaymentSuccess: (orderId, transactionId, pkg) => {
    console.log(`${pkg.name} purchased!`, orderId);
  },

  onClose: () => {
    console.log('Modal closed');
  },
});

modal.open();
```

### 3. Payment Checkout Modal (Full Checkout Experience)

Complete checkout flow with payment method selection:

```typescript
import { PaymentCheckoutModal, PRODUCT_TYPE } from '@seaverse/payment-sdk';

const modal = new PaymentCheckoutModal({
  product: {
    id: 'pkg_credit_100',
    name: '100 Credits Package',
    price: 9.99,
    currency: 'USD',
    type: PRODUCT_TYPE.CREDITPACK,
  },

  autoCreateOrder: {
    productId: 'pkg_credit_100',
    purchaseType: 1,  // 1 = one-time purchase, 2 = subscription
    apiHost: 'https://payment.seaverse.com',
    accountToken: 'user-token',
    clientId: 'your-client-id',
    language_code: 'en',
  },

  language: 'en',

  onPaymentSuccess: (payload) => {
    console.log('Payment completed!', payload);
  },
});

modal.open();
```

---

## 🏗️ Architecture

### Version 0.9.2 - Enhancement

**Improvements in this release**:

1. **Enhanced GenericPackageModal** 🎯
   - Added `onClose` callback support for custom package modals
   - Callback is now triggered when modal is closed via the close button
   - Enables better integration with parent component lifecycle
   - Example usage:
   ```typescript
   const modal = new GenericPackageModal({
     packages: [...],
     onClose: () => {
       console.log('Modal closed by user');
       // Perform cleanup or refresh actions
     },
   });
   ```

### Version 0.9.0 - Critical Bug Fixes

**Major fixes in this release**:

1. **Fixed SDK Initialization Error** 🔧
   - Resolved "Payment method 'dropin' not found" error
   - Issue: BasePackageModal tried to find Dropin payment when only Link payments available
   - Solution: Override `initializeSDK()` in CreditPackageModal and GenericPackageModal to skip legacy initialization
   - Now PaymentCheckoutModal handles all SDK initialization independently

2. **Fixed Link Payment Auto-Execution** 🔧
   - Prevented immediate redirect before users see checkout modal
   - Issue: `autoSelectDefaultPaymentMethod()` auto-executed Link payment, causing instant redirect
   - Solution: Only auto-select Dropin payments, wait for manual selection when only Link available
   - Improved user experience with proper checkout flow

3. **UI/UX Enhancements** 🎨
   - Increased payment method card spacing from 8px to 14px
   - Better visual hierarchy and click targets
   - Consistent spacing in both skeleton and main UI

### Class Hierarchy

```
BasePackageModal<TPackage, TOptions>  (Abstract base class)
├── CreditPackageModal                (Standard credit packages)
└── GenericPackageModal               (Custom promotional packages)

PaymentCheckoutModal                   (Standalone checkout system)
├── PaymentStrategyFactory
│   ├── LinkPaymentStrategy           (Redirect payments)
│   ├── DropinPaymentStrategy         (Embedded forms)
│   └── BasePaymentStrategy           (Strategy base)
└── Services
    ├── PaymentOrderService           (Order management)
    ├── PaymentLoadingManager         (Loading states)
    └── PaymentStateManager           (State management)
```

### Design Patterns Used

- **Singleton Pattern**: SeaartPaymentSDK.getInstance()
- **Strategy Pattern**: Payment strategy selection (Link vs Dropin)
- **Template Method Pattern**: BasePackageModal with abstract methods
- **Factory Pattern**: PaymentStrategyFactory.createStrategy()
- **Service Locator Pattern**: Service injection in PaymentCheckoutModal

---

## 📚 Core Features

### 🌟 Recommended Features (For New Users)

| Feature | Component | Use Case | Documentation |
|---------|-----------|----------|---------------|
| **Credit Packages** | `CreditPackageModal` | Standard credit purchases | [👉 View](#creditpackagemodal---standard-credit-purchases) |
| **Custom Packages** | `GenericPackageModal` | Promotions & special offers | [👉 View](#genericpackagemodal---custom-packages) |
| **Checkout System** | `PaymentCheckoutModal` | Full checkout experience | [👉 View](#paymentcheckoutmodal---checkout-system) |
| **Success Modal** | `PurchaseSuccessModal` | Auto-integrated, no manual call needed | [👉 View](#purchasesuccessmodal---purchase-success) |

### 🔧 Advanced Features

| Feature | API | Use Case |
|---------|-----|----------|
| **Credit Query** | `getCreditDetail` | Check user credit balance |
| **Subscription Management** | `getCurrentSubscription`, `changeSubscription` | Manage subscriptions |
| **Order Management** | `checkOrderStatus`, `pollOrderStatus` | Track order status |
| **Custom Payment Flows** | `SeaartPaymentSDK` | Full control over payment process |

---

## 📖 Detailed Documentation

### CreditPackageModal - Standard Credit Purchases

**Use Cases**:
- ✅ Standard credit package purchases
- ✅ Dynamic packages from API
- ✅ Simplest integration method

#### Basic Usage

```typescript
import { CreditPackageModal } from '@seaverse/payment-sdk';

const modal = new CreditPackageModal({
  // Language (optional, defaults to 'en')
  language: 'en',  // 'en' | 'zh' | 'zh-TW' | 'ja' | 'ko' | etc.

  // Modal title (optional)
  title: 'Purchase Credits',
  title_cn: '购买积分',  // Chinese title

  // SDK Configuration (required)
  sdkConfig: {
    environment: 'production',
    accountToken: 'user-token',

    // Optional overrides
    businessType: 1,  // 1 = one-time, 2 = subscription
    clientId: 'custom-client-id',
    orderApiUrl: 'https://custom-api.com',
  },

  // Callbacks
  onPaymentSuccess: (orderId, transactionId, pkg) => {
    console.log('Payment successful!', {
      orderId,
      transactionId,
      credits: pkg.total_credits
    });
  },

  onPaymentFailed: (error, pkg) => {
    console.error('Payment failed:', error.message);
  },

  onClose: () => {
    console.log('Modal closed');
  },
});

// Open modal
modal.open();

// Close modal (optional)
modal.close();

// Check status
console.log('Is open:', modal.isOpen());
```

#### Dynamic Package Fetching

Packages are automatically fetched from the API based on:
- Environment (`development` or `production`)
- Account token (for user-specific packages)
- Business type (one-time vs subscription)

---

### GenericPackageModal - Custom Packages

**Use Cases**:
- ✅ Special promotions (ice breaker packs, emergency packs)
- ✅ Limited-time offers
- ✅ First-purchase bonuses
- ✅ Custom package configurations

#### Basic Usage

```typescript
import { GenericPackageModal, type GenericPackage } from '@seaverse/payment-sdk';

const packages: GenericPackage[] = [
  {
    id: 'pkg_ice_breaker',
    name: 'Ice Breaker Pack',
    price: '0.49',
    currency: 'USD',
    credits: '120',
    base_credits: '100',
    bonus_credits: '20',
    bonus_percentage: 20,        // Show "+20%" badge
    package_type: 'iceBreaker',  // Display "One-time Only"
  },
  {
    id: 'pkg_emergency',
    name: 'Emergency Pack',
    price: '0.99',
    currency: 'USD',
    credits: '240',
    package_type: 'emergency',
  },
];

const modal = new GenericPackageModal({
  packages: packages,
  language: 'en',

  sdkConfig: {
    environment: 'development',
    accountToken: 'user-token',
  },

  onPaymentSuccess: (orderId, transactionId, pkg) => {
    console.log(`${pkg.name} purchased successfully!`);
  },
});

modal.open();
```

#### GenericPackage Interface

```typescript
interface GenericPackage {
  // Required fields
  id: string;              // Unique package identifier
  name: string;            // Package name
  price: string;           // Price (string to support decimals)
  currency: string;        // Currency code (e.g., 'USD')
  credits: string;         // Total credits

  // Optional bonus fields
  base_credits?: string;       // Base credits
  bonus_credits?: string;      // Bonus credits
  bonus_percentage?: number;   // Bonus percentage (e.g., 20 for +20%)

  // Optional classification
  package_type?: 'iceBreaker' | 'emergency' | 'firstCharge' | 'custom';
}
```

---

### PaymentCheckoutModal - Checkout System

**Use Cases**:
- ✅ Full checkout experience with payment method selection
- ✅ Support for multiple payment types (Link, Dropin, BindCard)
- ✅ Auto order creation and payment
- ✅ Advanced customization and control

#### Basic Usage

```typescript
import { PaymentCheckoutModal, PRODUCT_TYPE } from '@seaverse/payment-sdk';

const modal = new PaymentCheckoutModal({
  // Product information
  product: {
    id: 'pkg_credit_100',
    name: '100 Credits Package',
    price: 9.99,
    currency: 'USD',
    type: PRODUCT_TYPE.CREDITPACK,  // CREDITPACK | SUBSCRIPTION | CHANGE_SUBSCRIPTION
  },

  // Auto create order (recommended)
  autoCreateOrder: {
    productId: 'pkg_credit_100',
    purchaseType: 1,              // 1 = one-time, 2 = subscription
    apiHost: 'https://payment.seaverse.com',
    accountToken: 'user-token',
    clientId: 'your-client-id',
    language_code: 'en',
  },

  // Optional configuration
  accountName: 'John Doe',        // Display in order summary
  language: 'en',

  // Callbacks
  onPaymentSuccess: (payload) => {
    console.log('Payment successful!', payload);
  },

  onPaymentFailed: (error) => {
    console.error('Payment failed:', error.message);
  },

  onPaymentMethodSelect: (method) => {
    console.log('Payment method selected:', method.payment_method_name);
  },

  onLinkPaymentStart: (methodName) => {
    console.log('Link payment started:', methodName);
    // Show "Please complete payment in new window" message
  },

  onLoading: (loading) => {
    console.log('Loading state:', loading);
  },
});

modal.open();
```

#### Payment Methods Supported

1. **Link Payment** (payment_type = 1)
   - Redirect to external payment page
   - Auto order status polling
   - Verification modal after redirect

2. **Dropin Payment** (payment_type = 2)
   - Embedded payment form
   - Support credit cards, PayPal, etc.
   - Inline validation and submission

3. **BindCard Payment** (payment_type = 2 with saved cards)
   - Display saved payment methods
   - Quick payment with saved cards
   - Add new card option

#### Auto-Selection Strategy (Fixed in v0.9.0)

The checkout modal intelligently handles payment method selection:

- ✅ **When Dropin available**: Auto-select first Dropin and render payment form
- ✅ **When only Link available**: Wait for user manual selection (no auto-execution)
- ✅ **Prevents issue**: No more instant redirect before users see checkout

---

### PurchaseSuccessModal - Purchase Success

**✨ Auto-integrated** - Automatically displays after successful payment in CreditPackageModal and GenericPackageModal.

#### Features

- ✅ Email confirmation card design
- ✅ Beautiful animations (fade in/out, scale, sequential)
- ✅ Display purchase details (package name, credits, amount)
- ✅ Support ESC key, overlay click, close button
- ✅ Auto prevent body scroll
- ✅ Multi-language support (13+ languages)

#### Auto-trigger Flow

```
User clicks purchase button
  ↓
Payment successful
  ↓
CreditPackageModal/GenericPackageModal closes
  ↓
PurchaseSuccessModal displays (with animation)
  ↓
User closes success modal
  ↓
Auto credit balance refresh
  ↓
Trigger onPaymentSuccess callback
```

#### Manual Usage (Optional)

```typescript
import { PurchaseSuccessModal } from '@seaverse/payment-sdk';

const modal = new PurchaseSuccessModal({
  data: {
    packName: 'Ice Breaker Pack',
    credits: 120,
    amount: '0.49',
    currency: '$',  // Auto-converted from currency code
    orderId: 'order_123',
    transactionId: 'txn_456',
  },
  language: 'en',
  onClose: () => {
    console.log('Success modal closed');
  },
});

modal.open();
```

---

## 🌍 Internationalization

### Supported Languages (13+)

| Language | Code | Country Mapping |
|----------|------|-----------------|
| English | `en` | US |
| Simplified Chinese | `zh` | CN |
| Traditional Chinese | `zh-TW` | TW |
| Japanese | `ja` | JP |
| Korean | `ko` | KR |
| Spanish | `es` | ES |
| French | `fr` | FR |
| German | `de` | DE |
| Portuguese | `pt` | PT |
| Russian | `ru` | RU |
| Arabic | `ar` | SA |
| Hindi | `hi` | IN |
| Indonesian | `id` | ID |

### Language Auto-Mapping

The SDK automatically maps language codes to country codes for payment method retrieval:

```typescript
// User sets language
const modal = new CreditPackageModal({
  language: 'ja',  // Japanese
  sdkConfig: { /* ... */ }
});

// SDK automatically uses country_code: 'JP' when fetching payment methods
```

### Custom Language Handling

For SDK initialization, some languages require special formatting:

```typescript
// SDK Language Format Conversion
'zh'    → 'zhCN'   // Simplified Chinese
'zh-TW' → 'zhTW'   // Traditional Chinese
'en'    → 'en'     // English (no conversion)
'ja'    → 'ja'     // Japanese (no conversion)
// ... other languages use code directly
```

---

## ⚙️ Configuration

### Environment Configuration

The SDK auto-configures based on `environment`:

**Development**:
```typescript
{
  scriptUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/client.js',
  clientId: 'XF49NOfyZ54O16GujB0ptio2',
  orderApiUrl: 'https://payment.sg.seaverse.dev',
  walletApiUrl: 'https://wallet.sg.seaverse.dev',
  cssUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/client.css',
}
```

**Production**:
```typescript
{
  scriptUrl: 'https://payment-static.seaverse.com/sdk/seaart-payment-component.js',
  clientId: 'prod_client_id',
  orderApiUrl: 'https://payment.seaverse.com',
  walletApiUrl: 'https://wallet.seaverse.com',
  cssUrl: 'https://payment-static.seaverse.com/sdk/seaart-payment-component.css',
}
```

### PaymentSDKConfig Interface

```typescript
interface PaymentSDKConfig {
  // Required
  environment: 'development' | 'production';
  accountToken: string;

  // Optional (with sensible defaults)
  businessType?: 1 | 2;       // 1 = one-time, 2 = subscription
  scriptTimeout?: number;     // Default: 10000ms
  paymentMethodType?: string; // Default: 'dropin'

  // Advanced overrides
  scriptUrl?: string;         // Override environment config
  clientId?: string;          // Override environment config
  orderApiUrl?: string;       // Override environment config
  cssUrl?: string;            // Override environment config
}
```

---

## 🔍 Advanced Features

### Credit Query

```typescript
import { getCreditDetail } from '@seaverse/payment-sdk';

const apiHost = 'https://wallet.seaverse.com';
const token = 'user-token';

const detail = await getCreditDetail(apiHost, token);

console.log('Total balance:', detail.total_balance);
console.log('Tier:', detail.tier);

detail.pools.forEach(pool => {
  console.log(`${pool.type} pool: ${pool.balance} credits`);
});
```

#### Credit Pool System

| Pool Type | Description | Expiration |
|-----------|-------------|------------|
| `daily` | Daily credits | Next day 00:00 UTC |
| `event` | Event credits | Event end date |
| `monthly` | Monthly credits | 30 days after grant |
| `permanent` | Permanent credits | Never expires |

**Consumption Priority**: Daily → Event → Monthly → Permanent

### Subscription Management

```typescript
import {
  getCurrentSubscription,
  getActiveSubscription,
  changeSubscription,
} from '@seaverse/payment-sdk';

const apiUrl = 'https://payment.seaverse.com';
const token = 'user-token';

// Query current subscription status
const current = await getCurrentSubscription(apiUrl, token);
console.log('Status:', current.subscription_status);

// Get active subscription details
const active = await getActiveSubscription(apiUrl, token);
console.log('Plan:', active.product_name);

// Upgrade/downgrade subscription
const result = await changeSubscription(apiUrl, token, {
  productId: 'pro_plan',
  billingPeriod: 'year',
  redirectUrl: window.location.href,
});
```

### Order Status Tracking

```typescript
import { checkOrderStatus, pollOrderStatus } from '@seaverse/payment-sdk';

const apiUrl = 'https://payment.seaverse.com';
const token = 'user-token';
const transactionId = 'txn_123';

// Single status check
const status = await checkOrderStatus(transactionId, apiUrl, token);
console.log('Order status:', status.order_status);

// Poll until final status
const finalStatus = await pollOrderStatus(transactionId, apiUrl, token, {
  interval: 2000,      // Poll interval (ms)
  maxAttempts: 30,     // Max attempts
  onPoll: (status, attempt) => {
    console.log(`Attempt ${attempt}: ${status}`);
  },
});

console.log('Final status:', finalStatus.order_status);
```

---

## 🎨 UI Feedback Utilities

SDK provides unified UI feedback tools (replacement for browser `alert()`):

```typescript
import {
  showErrorMessage,
  showSuccessMessage,
  showInfoMessage,
  showLoadingIndicator,
  hideLoadingIndicator,
} from '@seaverse/payment-sdk';

// Error message (red gradient)
showErrorMessage('Payment failed, please try again', 3000);

// Success message (green gradient)
showSuccessMessage('Payment successful!', 3000);

// Info message (blue gradient)
showInfoMessage('Processing your request...', 3000);

// Loading indicator
const loader = showLoadingIndicator('Initializing payment system...');
// ... async operation
hideLoadingIndicator(loader);
```

**Features**:
- ✅ Beautiful gradient backgrounds + icons
- ✅ Auto fade in/out animations
- ✅ Auto removal (configurable duration)
- ✅ Prevent duplicate display
- ✅ XSS protection

---

## 🛡️ Error Handling

### Common Error Codes

| Code | Constant | Description |
|------|----------|-------------|
| `0` | `SUCCESS` | Success |
| `400` | `BAD_REQUEST` | Invalid parameters |
| `401` | `UNAUTHORIZED` | Unauthorized |
| `500` | `SERVER_ERROR` | Server error |
| `4001` | `DAILY_LIMIT_EXCEEDED` | Daily limit exceeded |
| `4002` | `PRODUCT_NOT_FOUND` | Product not found |

### Error Handling Example

```typescript
const modal = new GenericPackageModal({
  packages: packages,
  sdkConfig: { /* ... */ },

  onPaymentFailed: (error, pkg) => {
    if (error.message.includes('limit')) {
      showErrorMessage(`Daily limit reached for ${pkg.name}`);
    } else if (error.message.includes('payment')) {
      showErrorMessage('Payment processing failed');
    } else {
      showErrorMessage(`Error: ${error.message}`);
    }
  },
});
```

---

## 🧪 Testing

### Test Card Numbers (Development Only)

For testing payment functionality in development environment:

| Field | Value |
|-------|-------|
| Card Number | `4212345678910006` |
| Expiry | `03/30` |
| CVC | `737` |
| 3DS Password | `password` |

---

## 🌐 Framework Integration

### Vue 3

```vue
<script setup lang="ts">
import { ref } from 'vue';
import { CreditPackageModal } from '@seaverse/payment-sdk';

const userToken = ref('user-token-here');

const openPaymentModal = () => {
  const modal = new CreditPackageModal({
    language: 'en',
    sdkConfig: {
      environment: import.meta.env.DEV ? 'development' : 'production',
      accountToken: userToken.value,
    },
    onPaymentSuccess: (orderId, transactionId, pkg) => {
      console.log('Payment successful', { orderId, transactionId });
      // Refresh user data
    },
  });
  modal.open();
};
</script>

<template>
  <button @click="openPaymentModal">Purchase Credits</button>
</template>
```

### React

```tsx
import { CreditPackageModal } from '@seaverse/payment-sdk';

function PurchaseButton() {
  const handlePurchase = () => {
    const modal = new CreditPackageModal({
      language: 'en',
      sdkConfig: {
        environment: process.env.NODE_ENV === 'development' ? 'development' : 'production',
        accountToken: getUserToken(),
      },
      onPaymentSuccess: (orderId, transactionId, pkg) => {
        console.log('Payment successful', { orderId, transactionId });
        // Refresh user data
      },
    });
    modal.open();
  };

  return <button onClick={handlePurchase}>Purchase Credits</button>;
}
```

### Svelte

```svelte
<script lang="ts">
  import { CreditPackageModal } from '@seaverse/payment-sdk';

  let userToken = 'user-token-here';

  function openPaymentModal() {
    const modal = new CreditPackageModal({
      language: 'en',
      sdkConfig: {
        environment: 'development',
        accountToken: userToken,
      },
      onPaymentSuccess: (orderId, transactionId, pkg) => {
        console.log('Payment successful', { orderId, transactionId });
      },
    });
    modal.open();
  }
</script>

<button on:click={openPaymentModal}>Purchase Credits</button>
```

---

## 📝 TypeScript Support

Full TypeScript type definitions included:

```typescript
import type {
  // Modal types
  CreditPackageModalOptions,
  GenericPackageModalOptions,
  GenericPackage,
  CreditPackageItem,

  // Configuration types
  PaymentSDKConfig,
  Environment,
  EnvironmentConfig,
  LocaleCode,
  CountryCode,

  // Payment types
  Product,
  ProductType,
  AutoCreateOrderConfig,
  PaymentMethod,
  BindCard,

  // Response types
  OrderStatusResponse,
  CreditDetailResponse,
  CurrentSubscription,
  ActiveSubscription,
} from '@seaverse/payment-sdk';
```

---

## 📊 Comparison Table

### CreditPackageModal vs GenericPackageModal vs PaymentCheckoutModal

| Feature | CreditPackageModal | GenericPackageModal | PaymentCheckoutModal |
|---------|-------------------|---------------------|---------------------|
| **Package Data** | API-fetched | User-provided | User-provided product |
| **Package Type** | Dynamic credit packs | Custom (promo/special) | Any product type |
| **Complexity** | ⭐️ Simple | ⭐️⭐️ Medium | ⭐️⭐️⭐️ Advanced |
| **Use Case** | Standard purchases | Promotions/offers | Full checkout control |
| **Customization** | Limited | Medium | Full control |
| **SDK Initialization** | Auto (via PaymentCheckoutModal) | Auto (via PaymentCheckoutModal) | Auto |
| **Payment Methods** | All supported | All supported | All supported |

**Selection Guide**:
- 🎯 **Standard credit purchases** → Use `CreditPackageModal` (recommended for beginners)
- 🎁 **Special promotions** → Use `GenericPackageModal`
- 🔧 **Advanced custom flows** → Use `PaymentCheckoutModal`

---

## 📄 Changelog

### v0.9.7 (2026-02-08) - Configuration & Stability

**🔧 Improvements**:
- Configuration updates and stability improvements.

### v0.9.6 (2026-02-08) - Link Payment Callback Fix

**🔧 Bug Fixes**:
- **Dynamic Callback URL**: Fixed Link payment `callback_url` from hardcoded `/pricing` to `window.location.pathname`, ensuring correct redirect on any page.
- **Removed Debug Logs**: Cleaned up leftover `console.log` in `packages.ts`.

### v0.9.5 (2026-02-08) - CreditPackCard UI Refinement & Modal Fix

**🎨 CreditPackCard UI Overhaul**:
- **1:1 Design Restoration**: Rebuilt CreditPackCard to pixel-match reference design across all dimensions.
  - Card: `246x252` → `228x auto`, `border-radius: 16px`, compact padding `28px 20px 16px`.
  - Number: `36px` → `32px`, italic weight `600`, tighter letter-spacing.
  - Credits text: `16px` at `0.45` opacity, 8px margin below.
  - Bonus tag: `16px` bold green `#00E699`, `6px` border-radius, compact padding.
  - Button: `48px` height, `14px` border-radius, `18px` font, fixed `16px` margin-top.
- **Color System Update**: Unified to `#00E699` green palette across glow, bonus text, button gradient, and borders.
- **Badge Refinement**: Reduced to `72px`, repositioned `top: -16px, right: -12px`, `12deg` rotation, italic "Double" text.
- **Spacing Optimization**: Eliminated excessive gaps between bonus tag and button; content flows naturally without `flex: 1` or `margin-top: auto` stretch.

**🔧 GenericPackageModal Fix**:
- **Fixed White Background Layer**: Resolved issue where `.payment-modal` white background (`#ffffff`) was visible behind dark-themed cards.
  - Added `backgroundColor: transparent`, `boxShadow: none`, `borderRadius: 0` overrides.
  - Cleared `.payment-modal-content` background to transparent.
- **SeaartPaymentSDK**: Now uses environment config `clientId` instead of user-provided one for correct payment gateway routing.

### v0.9.4 (2026-02-07) - Mobile Responsiveness & SDK Refinement

**📱 Mobile & Responsive Enhancements**:
- **Full Responsive Support**: Added comprehensive media queries to `CreditPackageModal` for seamless display on Mobile, Tablet, and Desktop.
- **Dynamic Layouts**: Implemented adaptive grid columns, font sizes, and paddings based on screen width.
- **Improved Mobile UI**: Optimized card sizes and modal dimensions for small screens (max-width: 768px).

**🔧 SDK & Configuration Refinements**:
- **Environment-based Initialization**: Refactored `SeaartPaymentSDK` to automatically load configurations based on the environment (`development`/`production`).
- **Updated Production Config**: Updated production `clientId` for the official payment gateway.
- **Enhanced Type Safety**: Unified `LocaleCode` usage across the SDK and demo projects.
- **Better Locale Support**: Improved `isZh` logic to support both Simplified (`zh`) and Traditional (`zh-TW`) Chinese.

### v0.9.3 (2026-02-07) - UI/UX Overhaul & Design Restoration

**🎨 Major UI Overhaul**:
- **Unified Modal Design**: Redesigned `PurchaseSuccessModal`, `PaymentFailedModal`, `PaymentVerificationModal`, and `RetentionModal` to match the new dark design system.
  - New tokens: Background `#121212`, border `rgba(44,44,46,0.6)`, and brand green `#10B981`.
  - Improved typography and spacing for better readability.
- **GenericPackageModal 1:1 Restoration**: Completely rebuilt the custom package cards to match `Credits.html` design.
  - Added ambient glow effects and hover animations.
  - New "Value Badge" (+N% EXTRA VALUE) with golden theme.
  - Redesigned CTA buttons with integrated price blocks and hover shine effects.

**🔧 Fixes & Improvements**:
- **Fixed Locale Support**: Updated `isZh` checks to correctly handle both Simplified Chinese (`zh`) and Traditional Chinese (`zh-TW`).
- **Enhanced Interactions**: Added scale feedback and glowing effects to all primary buttons.
- **Refined Layouts**: Optimized border radii and paddings across all payment-related modals.

### v0.9.2 (2026-02-07) - Enhancement
- **Enhanced GenericPackageModal**: Added `onClose` callback support for custom package modals.
- **Improved Integration**: Better lifecycle management for parent components.

### v0.9.0 (2026-02-07) - Critical Bug Fixes

**🔧 Critical Fixes**:
- Fixed SDK initialization failure when only Link payment methods available
  - Issue: `BasePackageModal.initializeSDK()` required Dropin payment (payment_type === 2)
  - Solution: Override `initializeSDK()` in CreditPackageModal and GenericPackageModal
  - Now PaymentCheckoutModal handles all SDK initialization independently

- Fixed Link payment auto-execution issue
  - Issue: `autoSelectDefaultPaymentMethod()` auto-executed Link payment, causing instant redirect
  - Solution: Refined strategy - only auto-select when Dropin exists; wait for manual selection when only Link available
  - Improved UX: Users now see checkout modal before any payment action

**🎨 UI/UX Improvements**:
- Increased payment method card spacing from 8px to 14px
- Better visual breathing room and click targets
- Consistent spacing in both skeleton and main UI

**📁 Files Changed** (5 files, +86 -53 lines):
- `CreditPackageModal.ts`: Added `initializeSDK()` and `waitForSDKInitialization()` overrides
- `GenericPackageModal.ts`: Added `initializeSDK()` and `waitForSDKInitialization()` overrides
- `PaymentCheckoutModal.ts`: Refined `autoSelectDefaultPaymentMethod()` logic (lines 485-517)
- `PaymentUIRenderer.ts`: Updated card gap from 8px to 14px (lines 207, 276)
- `index.ts`: Version bump

### v0.8.2 (2026-02-02) - Architecture Refactoring

**🏗️ Architecture**:
- Created `BasePackageModal` abstract base class
- Eliminated ~400 lines of duplicate code between CreditPackageModal and GenericPackageModal
- Improved type safety with TypeScript generics
- 100% backward compatible - no breaking changes

**📦 Package Size**:
- CreditPackageModal: 1042 lines → 515 lines (50% reduction)
- GenericPackageModal: 752 lines → 340 lines (55% reduction)
- Total code reduction: ~25%

---

## 🔗 Links

- 📦 [NPM Package](https://www.npmjs.com/package/@seaverse/payment-sdk)
- 🐙 [GitHub Repository](https://github.com/SeaVerseAI/sv-sdk)
- 📖 [API Documentation](https://github.com/SeaVerseAI/sv-sdk/tree/main/packages/payment-sdk)
- 🐛 [Issue Tracker](https://github.com/SeaVerseAI/sv-sdk/issues)

---

## 📄 License

MIT License

---

## 🤝 Contributing

Issues and Pull Requests are welcome!

---

**Last Updated**: 2026-02-08
**SDK Version**: 0.9.7