npm package: @tagadapay/plugin-sdk
Description: Modern React SDK for building Tagada Pay plugins
Author: Tagada Pay
Latest version: 3.1.25

# TagadaPay Plugin SDK

A comprehensive React SDK for building plugins on the TagadaPay platform. Create custom checkout experiences, landing pages, and interactive components with automatic configuration injection and advanced routing capabilities.

> **🚀 V2 Now Available!** The new V2 architecture features TanStack Query integration, improved TypeScript support, and better performance. [See V2 Architecture](#-v2-architecture) for details.
>
> **Recommended**: Use `@tagadapay/plugin-sdk/v3` for new projects. V1 (`/react`) is still supported for existing projects.

## 📚 Documentation

### V2 Core APIs (Recommended)

- **[V2 Architecture](#-v2-architecture)** - New TanStack Query-based architecture
- **[V2 Examples](#-v2-examples)** - Complete examples using the new V2 hooks
- **[useCheckout (V2)](#usecheckout)** - TanStack Query-based checkout management
- **[useOffers (V2)](#useoffers)** - Dynamic pricing with automatic caching
- **[useProducts (V2)](#useproducts)** - Product data management
- **[useStoreConfig (V2)](#usestoreconfig)** - Store configuration with automatic caching
- **[usePayment (V2)](#usepayment)** - Payment processing with 3DS support
- **[V2 Utility Functions](#v2-utility-functions--advanced-features)** - Enhanced utilities and TanStack Query integration

### Legacy V1 APIs (Still Supported)

- **[useCheckout (V1)](./docs/README-useCheckout.md)** - Legacy checkout state management
- **[setCheckoutInfo](./docs/README-setCheckoutInfo.md)** - Customer information and validation
- **[useOffers (V1)](./docs/README-useOffers.md)** - Legacy dynamic pricing
- **[usePromotionCodes](./docs/README-usePromotionCodes.md)** - Legacy promotion code management
- **[Money utilities](./docs/README-money.md)** - Currency formatting and calculations
- **[URL utilities](./docs/README-urlUtils.md)** - Navigation and routing helpers

### Plugin Development

- **[Plugin Configuration](./docs/PLUGIN_CONFIG.md)** - How to access store context, config, and branding
- **[Initialization Modes](#-initialization-modes)** - Choose between blocking and non-blocking initialization
- **[Google Autocomplete](./docs/README-google-autocomplete.md)** - Address autocomplete with Google Places API
- **[ISO Data](./docs/README-iso-data.md)** - Country and region data with Google integration

### Examples

- **[Vite Checkout Demo](../checkout-vite)** - Complete checkout implementation

## 🏗️ Building a Plugin

### Plugin Structure

Every TagadaPay plugin follows this simple structure:

```
my-plugin/
├── plugin.manifest.json    # Plugin metadata & routing
├── .local.json            # Local dev config (auto-injected in production)
├── config/                # Optional deployment configs
│   ├── theme-green.json   # Config variant A
│   └── theme-blue.json    # Config variant B
├── src/
│   └── App.tsx           # Your plugin code
└── dist/                 # Built plugin files
```

### Configuration Flow

```mermaid
graph TD
    A[🛠️ Local Development] --> B[.local.json]
    A --> C[config/*.json]
    B --> D[usePluginConfig()]
    C --> D

    E[🚀 Production] --> F[Platform Injection]
    F --> G[HTTP Headers & Meta Tags]
    G --> D

    D --> H[Your Plugin Component]

    style A fill:#e1f5fe
    style E fill:#f3e5f5
    style D fill:#fff3e0
    style H fill:#e8f5e8
```

### Essential Files

#### 1. **`plugin.manifest.json`** - Plugin Metadata

```json
{
  "pluginId": "my-awesome-plugin",
  "name": "My Awesome Plugin",
  "version": "1.0.0",
  "mode": "direct-mode",
  "router": {
    "basePath": "/",
    "matcher": ".*",
    "excluder": "/checkout"
  }
}
```

#### 2. **`.local.json`** - Local Development Context

```json
{
  "storeId": "store_abc123",
  "accountId": "acc_xyz789",
  "basePath": "/"
}
```

> ⚠️ **Auto-managed**: This file is only for local dev. In production, the platform injects this data automatically.

#### 3. **`config/my-theme.json`** - Optional Deployment Config

```json
{
  "configName": "green-theme",
  "branding": {
    "primaryColor": "#059669",
    "companyName": "My Store",
    "logoUrl": "https://example.com/logo.png"
  },
  "features": {
    "enableChat": true,
    "maxItems": 10
  }
}
```

> 📝 **Note**: Config can contain any keys you need - the SDK doesn't enforce a specific structure.

## 🚀 Quick Start

### Installation

```bash
npm install @tagadapay/plugin-sdk
```

### Basic Plugin Setup

```tsx
import React from 'react';
import {
  TagadaProvider,
  usePluginConfig,
  useGoogleAutocomplete,
  useISOData,
  useCheckout,
  formatMoney,
} from '@tagadapay/plugin-sdk/v3';

function MyPlugin() {
  const { config, storeId, accountId, basePath, loading } = usePluginConfig();

  // Optional: Add address autocomplete
  const { searchPlaces, predictions } = useGoogleAutocomplete({
    apiKey: config?.googleMapsApiKey || 'YOUR_API_KEY',
  });

  // Optional: Add country/region data
  const { countries } = useISOData('en');

  // V2: Use TanStack Query-based checkout hook
  const { checkout, init, updateLineItems, isLoading } = useCheckout({
    checkoutToken: 'your-checkout-token',
  });

  if (loading) return <div>Loading...</div>;

  return (
    <div style={{ '--primary': config?.branding?.primaryColor }}>
      <h1>Welcome to {config?.branding?.companyName}</h1>
      <p>Store: {storeId}</p>
      <p>Base Path: {basePath}</p>
      <p>Available Countries: {Object.keys(countries).length}</p>

      {checkout && (
        <div>
          <h2>Checkout Total: {formatMoney(checkout.summary.total, checkout.currency)}</h2>
          <p>Items: {checkout.lineItems.length}</p>
        </div>
      )}
    </div>
  );
}

// Wrap your plugin with TagadaProvider
function App() {
  return (
    <TagadaProvider>
      <MyPlugin />
    </TagadaProvider>
  );
}

export default App;
```

## 🏗️ V2 Architecture

### What's New in V2

The TagadaPay Plugin SDK v3 introduces a clean architecture with significant improvements:

#### **🔄 TanStack Query Integration**

- **Automatic Caching**: All API calls are cached and synchronized across components
- **Background Refetching**: Data stays fresh with automatic background updates
- **Optimistic Updates**: Instant UI feedback with automatic rollback on errors
- **Request Deduplication**: Multiple components can use the same data without duplicate requests

#### **🏗️ Clean Architecture**

- **Core Layer**: Pure functions and API clients without React dependencies
- **React Layer**: Hooks and components that use core functions
- **Better Testing**: Easier to test business logic separately from UI logic

#### **📦 Import Paths**

```tsx
// V2 (Recommended)
import { useCheckout, useOffers, TagadaProvider } from '@tagadapay/plugin-sdk/v3';

// Legacy (Still supported)
import { useCheckout, useOffers, TagadaProvider } from '@tagadapay/plugin-sdk/react';
```

#### **🔧 Enhanced Developer Experience**

- **TypeScript First**: Better type inference and autocomplete
- **Debug Tools**: Built-in debug drawer for development
- **Performance**: Reduced bundle size and better performance

### Migration from V1

Most hooks have the same names but improved APIs:

```tsx
// V1 Pattern
const { checkout, loading, error } = useCheckout();

// V2 Pattern (TanStack Query)
const { checkout, isLoading, error, refresh } = useCheckout({
  checkoutToken: 'token',
  enabled: true,
});
```

### 📚 V2 Examples

#### Complete Checkout Flow

```tsx
import React, { useState } from 'react';
import {
  TagadaProvider,
  useCheckout,
  useProducts,
  usePluginConfig,
  formatMoney,
} from '@tagadapay/plugin-sdk/v3';

function CheckoutPage() {
  const [checkoutToken, setCheckoutToken] = useState<string>();
  const { config } = usePluginConfig();

  // Load products
  const { products, isLoading: productsLoading } = useProducts({
    storeId: config.storeId,
  });

  // Initialize checkout when needed
  const {
    checkout,
    isLoading: checkoutLoading,
    init,
    updateLineItems,
    updateCustomer,
    applyPromotionCode,
  } = useCheckout({
    checkoutToken,
    enabled: !!checkoutToken,
  });

  const handleInitCheckout = async () => {
    if (!products?.length) return;

    const result = await init({
      lineItems: [
        {
          variantId: products[0].variants[0].id,
          quantity: 1,
        },
      ],
    });

    setCheckoutToken(result.checkoutToken);
  };

  const handleApplyPromo = async (code: string) => {
    try {
      await applyPromotionCode(code);
      // TanStack Query automatically refetches and updates the UI
    } catch (error) {
      console.error('Failed to apply promo:', error);
    }
  };

  if (productsLoading) return <div>Loading products...</div>;

  return (
    <div>
      <h1>Checkout</h1>

      {!checkoutToken ? (
        <button onClick={handleInitCheckout}>Start Checkout</button>
      ) : (
        <div>
          {checkoutLoading ? (
            <div>Loading checkout...</div>
          ) : checkout ? (
            <div>
              <h2>Order Summary</h2>
              <p>Total: {formatMoney(checkout.summary.total, checkout.currency)}</p>
              <p>Items: {checkout.lineItems.length}</p>

              <div>
                <input
                  type="text"
                  placeholder="Promo code"
                  onKeyDown={(e) => {
                    if (e.key === 'Enter') {
                      handleApplyPromo(e.currentTarget.value);
                    }
                  }}
                />
              </div>
            </div>
          ) : null}
        </div>
      )}
    </div>
  );
}

function App() {
  return (
    <TagadaProvider>
      <CheckoutPage />
    </TagadaProvider>
  );
}
```

#### Multi-Component Data Sharing

```tsx
import React from 'react';
import { TagadaProvider, useCheckout, useOffers, formatMoney } from '@tagadapay/plugin-sdk/v3';

// Component 1: Cart Summary
function CartSummary({ checkoutToken }: { checkoutToken: string }) {
  const { checkout, isLoading } = useCheckout({ checkoutToken });

  if (isLoading) return <div>Loading...</div>;
  if (!checkout) return null;

  return (
    <div>
      <h3>Cart ({checkout.lineItems.length} items)</h3>
      <p>Total: {formatMoney(checkout.summary.total, checkout.currency)}</p>
    </div>
  );
}

// Component 2: Available Offers (shares same checkout data automatically)
function OffersPanel({ checkoutToken }: { checkoutToken: string }) {
  const { checkout } = useCheckout({ checkoutToken }); // Same data, no extra request!
  const { offers, isLoading } = useOffers({
    storeId: checkout?.storeId,
  });

  if (isLoading) return <div>Loading offers...</div>;

  return (
    <div>
      <h3>Special Offers</h3>
      {offers?.map((offer) => (
        <div key={offer.id}>
          <p>{offer.title}</p>
          <p>Save {formatMoney(offer.discount, checkout?.currency || 'USD')}</p>
        </div>
      ))}
    </div>
  );
}

// Main component
function CheckoutWithOffers() {
  const checkoutToken = 'your-checkout-token';

  return (
    <div style={{ display: 'flex', gap: '20px' }}>
      <CartSummary checkoutToken={checkoutToken} />
      <OffersPanel checkoutToken={checkoutToken} />
    </div>
  );
}
```

#### Optimistic Updates

```tsx
import React from 'react';
import { useCheckout } from '@tagadapay/plugin-sdk/v3';

function QuantitySelector({
  checkoutToken,
  variantId,
  currentQuantity,
}: {
  checkoutToken: string;
  variantId: string;
  currentQuantity: number;
}) {
  const { checkout, setItemQuantity, updateLineItemsOptimistic } = useCheckout({ checkoutToken });

  const handleQuantityChange = async (newQuantity: number) => {
    // 1. Optimistic update (instant UI feedback)
    const updatedItems =
      checkout?.lineItems.map((item) =>
        item.variantId === variantId ? { ...item, quantity: newQuantity } : item,
      ) || [];

    updateLineItemsOptimistic(updatedItems);

    // 2. Server update (with automatic rollback on error)
    try {
      await setItemQuantity(variantId, newQuantity);
      // TanStack Query automatically syncs the real data
    } catch (error) {
      // Automatic rollback to previous state
      console.error('Failed to update quantity:', error);
    }
  };

  return (
    <div>
      <button onClick={() => handleQuantityChange(currentQuantity - 1)}>-</button>
      <span>{currentQuantity}</span>
      <button onClick={() => handleQuantityChange(currentQuantity + 1)}>+</button>
    </div>
  );
}
```

## 🚀 Initialization Modes

The TagadaProvider supports two initialization modes to give you control over when your components render:

### Non-Blocking Mode (Default - Recommended)

```tsx
<TagadaProvider>
  {/* Children render immediately after config loads */}
  <YourApp />
</TagadaProvider>

// OR explicitly
<TagadaProvider blockUntilSessionReady={false}>
  <YourApp />
</TagadaProvider>
```

**Flow:**

1. **Phase 1 & 2** ✅ Plugin config loads → Children render immediately
2. **Phase 3** 🔄 Session initialization runs in background
3. **API calls** 🔄 Hooks automatically wait for session to be ready

**Benefits:**

- ⚡ **Faster rendering** - UI appears immediately
- 🎯 **Better UX** - Show loading states while session initializes
- 🔄 **Automatic waiting** - Hooks handle session timing for you

### Blocking Mode (Legacy Behavior)

```tsx
<TagadaProvider blockUntilSessionReady={true}>
  {/* Children render only after ALL initialization completes */}
  <YourApp />
</TagadaProvider>
```

**Flow:**

1. **All Phases** ⏳ Config + Session must complete before children render
2. **API calls** ✅ Work immediately (no waiting needed)

**Use when:**

- 🔄 **Migrating** from older SDK versions
- 🎯 **Simple apps** that don't need progressive loading

### Console Logs

The SDK logs help you understand which mode you're using:

**Non-blocking mode:**

```
✅ Phase 1 & 2 Complete - Plugin config loaded
🚀 Non-blocking mode: Children can now render - Phase 3 will continue in background
🔄 [useCheckout] Waiting for session initialization to complete...
✅ Phase 3 Complete - Session initialization completed successfully
✅ [useCheckout] Session initialized, proceeding with checkout init
```

**Blocking mode:**

```
✅ Phase 1 & 2 Complete - Plugin config loaded
⏳ Blocking mode: Children will render after Phase 3 completes
✅ Phase 3 Complete - Session initialization completed successfully
```

### TagadaProvider API

```tsx
interface TagadaProviderProps {
  children: ReactNode;
  environment?: 'local' | 'development' | 'staging' | 'production';
  customApiConfig?: Partial<EnvironmentConfig>;
  debugMode?: boolean;
  localConfig?: string; // LOCAL DEV ONLY: Override config variant
  blockUntilSessionReady?: boolean; // Default: false

  // V2 Specific Options
  queryClientConfig?: QueryClientConfig; // TanStack Query configuration
  enableDevtools?: boolean; // Enable React Query Devtools
}
```

| Prop                     | Type        | Default              | Description                    |
| ------------------------ | ----------- | -------------------- | ------------------------------ |
| `children`               | `ReactNode` | -                    | Your plugin components         |
| `environment`            | `string`    | auto-detect          | Override environment detection |
| `customApiConfig`        | `object`    | -                    | Custom API configuration       |
| `debugMode`              | `boolean`   | auto (false in prod) | Enable debug features & drawer |
| `localConfig`            | `string`    | `'default'`          | Config variant for local dev   |
| `blockUntilSessionReady` | `boolean`   | `false`              | Use legacy blocking behavior   |
| `queryClientConfig`      | `object`    | -                    | **V2**: TanStack Query config  |
| `enableDevtools`         | `boolean`   | `false`              | **V2**: React Query Devtools   |

#### V2 Enhanced Provider Features

```tsx
import { TagadaProvider } from '@tagadapay/plugin-sdk/v3';

function App() {
  return (
    <TagadaProvider
      debugMode={true}
      enableDevtools={true} // Shows React Query Devtools
      queryClientConfig={{
        defaultOptions: {
          queries: {
            staleTime: 5 * 60 * 1000, // 5 minutes
            cacheTime: 10 * 60 * 1000, // 10 minutes
          },
        },
      }}
    >
      <YourApp />
    </TagadaProvider>
  );
}
```

> **Version Compatibility:** V2 features require `@tagadapay/plugin-sdk/v3`. The `blockUntilSessionReady` option was added in v2.3.0. For older versions, the blocking behavior was the default and only option.

### Development vs Production

| Environment    | Store/Account ID | Deployment Config | How it Works       |
| -------------- | ---------------- | ----------------- | ------------------ |
| **Local Dev**  | `.local.json`    | `config/*.json`   | Files on disk      |
| **Production** | HTTP Headers     | Meta Tags         | Platform injection |

```tsx
// ✅ ALWAYS use hooks - works in both environments
const { storeId, accountId, basePath, config } = usePluginConfig();

// ❌ NEVER access directly
// const config = window.__PLUGIN_CONFIG__; // Doesn't exist!
```

## 🎯 Key Features

### 🔧 **Plugin Configuration System**

- **Automatic Context Injection** - Store ID, Account ID, and custom config
- **Development & Production** - Seamless environment switching
- **Generic Configuration** - Support for any JSON structure
- **React Hooks** - Clean, type-safe configuration access

### 💳 **Payment Processing**

- Secure tokenized payments
- Multiple payment method support
- Real-time validation
- PCI compliance

### 🌍 **Address & Location**

- **Google Places Autocomplete** - Automatic API loading and address parsing
- **ISO Country/Region Data** - Complete ISO 3166-1/3166-2 database
- **Address Validation** - Structured component extraction
- **Multi-language Support** - 11+ languages for international users

### 🛒 **E-commerce Features**

- Dynamic pricing and promotional offers
- Cart management and tax calculations
- Currency conversion and formatting
- Customer profile management

### 🎨 **UI & Development**

- Pre-built React components
- Customizable themes with configuration
- Mobile-optimized and accessible
- TypeScript support throughout

## 📖 API Reference

### V2 Core Hooks (TanStack Query-based)

#### useCheckout()

Primary hook for checkout state management using TanStack Query for automatic caching and synchronization.

```typescript
const {
  // Query data
  checkout, // CheckoutData | undefined
  isLoading, // boolean
  error, // Error | null
  isSuccess, // boolean

  // Actions
  init, // (params: CheckoutInitParams) => Promise<{checkoutUrl, checkoutSession, checkoutToken}>
  refresh, // () => Promise<void>

  // Checkout operations
  updateLineItems, // (lineItems: CheckoutLineItem[]) => Promise<any>
  updateLineItemsOptimistic, // (lineItems: CheckoutLineItem[]) => void
  setItemQuantity, // (variantId: string, quantity: number, priceId?: string) => Promise<any>
  updateCustomer, // (data: {email: string, acceptsMarketing?: boolean}) => Promise<any>
  applyPromotionCode, // (code: string) => Promise<any>
  removePromotion, // (promotionId: string) => Promise<any>
} = useCheckout({ checkoutToken, enabled });
```

#### useOffers()

Hook for managing dynamic offers and pricing with automatic cache management.

```typescript
const {
  // Query data
  offers, // Offer[] | undefined
  isLoading, // boolean
  error, // Error | null

  // Actions
  refresh, // () => Promise<void>
} = useOffers({ storeId, enabled });
```

#### usePromotions()

Hook for managing promotion codes in checkout sessions with TanStack Query.

```typescript
const {
  // Query data
  promotions, // Promotion[] | undefined
  isLoading, // boolean
  error, // Error | null

  // Actions
  refresh, // () => Promise<void>
} = usePromotions({ checkoutToken, enabled });
```

#### useProducts()

Hook for product data management with caching.

```typescript
const {
  // Query data
  products, // Product[] | undefined
  isLoading, // boolean
  error, // Error | null

  // Actions
  refresh, // () => Promise<void>
} = useProducts({ storeId, enabled });
```

#### useStoreConfig()

Hook for fetching store configuration with automatic caching.

```typescript
const {
  // Query data
  storeConfig, // StoreConfig | undefined
  isLoading, // boolean
  error, // Error | null
  isSuccess, // boolean

  // Actions
  refetch, // () => Promise<void>
} = useStoreConfig({ storeId, enabled });
```

**Example:**

```tsx
import { useStoreConfig } from '@tagadapay/plugin-sdk/v3';

function StoreInfo() {
  const { storeConfig, isLoading } = useStoreConfig();

  if (isLoading) return <div>Loading...</div>;

  return (
    <div>
      <h1>{storeConfig?.storeName}</h1>
      <p>Currency: {storeConfig?.currency}</p>
    </div>
  );
}
```

See [useStoreConfig documentation](./docs/README-useStoreConfig.md) for more details.

#### useOrder()

Hook for order management and tracking.

```typescript
const {
  // Query data
  order, // Order | undefined
  isLoading, // boolean
  error, // Error | null

  // Actions
  refresh, // () => Promise<void>
} = useOrder({ orderId, enabled });
```

#### usePostPurchases()

Hook for post-purchase offers management.

```typescript
const {
  // Query data
  postPurchases, // PostPurchaseOffer[] | undefined
  isLoading, // boolean
  error, // Error | null

  // Actions
  refresh, // () => Promise<void>
} = usePostPurchases({ orderId, enabled });
```

#### usePayment()

Hook for payment processing with 3DS support.

```typescript
const {
  // Payment methods
  processPayment, // (options: PaymentOptions) => Promise<PaymentResponse>
  processApplePayPayment, // (token: ApplePayToken) => Promise<PaymentResponse>

  // State
  isProcessing, // boolean
  error, // Error | null
} = usePayment();
```

### V2 Utility Functions & Advanced Features

#### TanStack Query Integration

V2 provides direct access to TanStack Query features for advanced use cases:

```typescript
import {
  useApiQuery,
  useApiMutation,
  useInvalidateQuery,
  usePreloadQuery,
  queryKeys,
} from '@tagadapay/plugin-sdk/v3';

// Custom API queries
const { data, isLoading } = useApiQuery({
  queryKey: ['custom', 'endpoint'],
  queryFn: () => apiClient.get('/custom-endpoint'),
});

// Mutations with automatic cache updates
const mutation = useApiMutation({
  mutationFn: (data) => apiClient.post('/update', data),
  onSuccess: () => {
    // Invalidate related queries
    invalidateQuery(['checkout']);
  },
});

// Preload data for better UX
const preloadCheckout = usePreloadQuery();
preloadCheckout({
  queryKey: queryKeys.checkout(checkoutToken),
  queryFn: () => checkoutResource.get(checkoutToken),
});
```

#### Money Utilities

Enhanced money formatting with better TypeScript support:

```typescript
import { formatMoney, convertCurrency, getCurrencyInfo } from '@tagadapay/plugin-sdk/v3';

// Format money with automatic currency detection
const formatted = formatMoney(2999, 'USD'); // "$29.99"
const simple = formatSimpleMoney(2999, 'EUR'); // "29.99"
const withoutSymbol = formatMoneyWithoutSymbol(2999, 'GBP'); // "29.99"

// Currency conversion (if rates available)
const converted = convertCurrency(2999, 'USD', 'EUR'); // 2699

// Get currency information
const currencyInfo = getCurrencyInfo('USD');
// { symbol: '$', code: 'USD', minorUnits: 2 }

// Convert between major and minor units
const major = minorUnitsToMajorUnits(2999); // 29.99
const minor = moneyStringOrNumberToMinorUnits('29.99'); // 2999
```

#### Core Functions (Pure Functions)

V2 separates core business logic from React hooks:

```typescript
import {
  CheckoutResource,
  ProductsResource,
  PaymentsResource,
  PluginConfigUtils,
} from '@tagadapay/plugin-sdk/v3';

// Use core functions directly (useful for server-side or non-React contexts)
const checkoutResource = new CheckoutResource(apiClient);
const checkout = await checkoutResource.get(checkoutToken);

// Plugin config utilities
const config = PluginConfigUtils.getPluginConfig(rawConfig, context);
const isValid = PluginConfigUtils.validateConfig(config);
```

#### Debug Tools

V2 includes built-in debugging tools:

```tsx
import { TagadaProvider } from '@tagadapay/plugin-sdk/v3';

function App() {
  return (
    <TagadaProvider
      debugMode={true} // Shows debug drawer in development
      environment="development"
    >
      <YourApp />
    </TagadaProvider>
  );
}
```

## 🛠️ Development

### Local Development

```bash
# Install dependencies
npm install

# Start development server
npm run dev

# Build for production
npm run build
```

### Testing

```bash
# Run tests
npm test

# Run tests with coverage
npm run test:coverage
```

### Linting

```bash
# Check code style
npm run lint

# Fix linting issues
npm run lint:fix
```

## 📦 Build & Deploy

### Building Your Plugin

```bash
# Build optimized bundle
npm run build

# Analyze bundle size
npm run analyze
```

### Deployment

```bash
# Deploy using TagadaPay CLI
npx @tagadapay/plugin-cli deploy

# Deploy specific environment
npx @tagadapay/plugin-cli deploy --env production
```

## 🔧 Configuration

### Plugin Configuration

```json
{
  "name": "My Checkout Plugin",
  "version": "1.0.0",
  "description": "Custom checkout experience",
  "main": "dist/index.js",
  "tagadapay": {
    "type": "checkout",
    "mode": "direct",
    "framework": "react"
  }
}
```

## 🔐 Security

### Best Practices

- Never store sensitive payment data
- Always validate user inputs
- Use HTTPS in production
- Implement proper error handling
- Follow PCI DSS guidelines

### Token Management

```typescript
// ✅ Good: Use tokenized payments
const paymentToken = await tokenizePayment(cardData);
await processPayment({ token: paymentToken });

// ❌ Bad: Never store raw card data
// const cardNumber = '4111111111111111'; // Don't do this
```

## 📱 Mobile Optimization

### Responsive Design

```css
.checkout-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 16px;
}

@media (max-width: 768px) {
  .checkout-container {
    padding: 8px;
  }

  .checkout-form {
    font-size: 16px; /* Prevent zoom on iOS */
  }
}
```

### Touch Interactions

```typescript
const handleTouchStart = (e) => {
  // Optimize for touch devices
  e.preventDefault();
  // Handle touch interaction
};
```

## 🌐 Internationalization

### Multi-language Support

```typescript
import { useTranslation } from '@tagadapay/plugin-sdk';

function CheckoutForm() {
  const { t } = useTranslation();

  return (
    <form>
      <label>{t('checkout.email')}</label>
      <input type="email" placeholder={t('checkout.email_placeholder')} />
    </form>
  );
}
```

### Currency Support

```typescript
import { useCurrency } from '@tagadapay/plugin-sdk';

function PriceDisplay({ amount }) {
  const { formatPrice, currency } = useCurrency();

  return <span>{formatPrice(amount, currency)}</span>;
}
```

## 📊 Analytics & Monitoring

### Event Tracking

```typescript
import { trackEvent } from '@tagadapay/plugin-sdk';

// Track user interactions
trackEvent('checkout_started', {
  product_id: 'prod_123',
  value: 2999,
  currency: 'USD',
});

// Track conversions
trackEvent('purchase_completed', {
  transaction_id: 'txn_456',
  value: 2999,
  currency: 'USD',
});
```

### Performance Monitoring

```typescript
import { performance } from '@tagadapay/plugin-sdk';

// Measure load times
performance.mark('checkout-start');
// ... checkout logic
performance.mark('checkout-end');
performance.measure('checkout-duration', 'checkout-start', 'checkout-end');
```

## 🤝 Contributing

### Development Setup

```bash
# Clone the repository
git clone https://github.com/tagadapay/plugin-sdk.git

# Install dependencies
npm install

# Start development
npm run dev
```

### Submitting Changes

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request

## 📄 License

MIT License - see [LICENSE](./LICENSE) for details.

## 🆘 Support

- **Documentation**: [docs.tagadapay.com](https://docs.tagadapay.com)
- **Discord**: [discord.gg/tagadapay](https://discord.gg/tagadapay)
- **Email**: support@tagadapay.com
- **GitHub Issues**: [github.com/tagadapay/plugin-sdk/issues](https://github.com/tagadapay/plugin-sdk/issues)

---

Built with ❤️ by the TagadaPay team