Skip to main content

SDK API Reference for React

Latest Version

v2.7.14 - Complete TypeScript documentation

Framework

React SDK - Hooks-based API for React 18+
Complete API documentation for all hooks, components, and utilities in the TagadaPay Plugin SDK v2.
React is Required: This API reference covers the React-based TagadaPay Plugin SDK v2 (@tagadapay/plugin-sdk/v2). All hooks and components require React 18+. For V1 docs, see the legacy documentation.

Quick Navigation

Installation & Setup

npm install @tagadapay/plugin-sdk

Provider Setup

Wrap your app with TagadaProvider:
import { TagadaProvider } from '@tagadapay/plugin-sdk/v2';

export default function App() {
  return (
    <TagadaProvider>
      <YourPlugin />
    </TagadaProvider>
  );
}

Query Hooks

useCheckout()

Fetch and manage checkout data with automatic caching.
import { useCheckout } from '@tagadapay/plugin-sdk/v2';

function CheckoutPage() {
  const { data: checkout, isLoading, error, refetch } = useCheckout();

  if (isLoading) return <div>Loading checkout...</div>;
  if (error) return <div>Error loading checkout</div>;

  return (
    <div>
      <h1>Checkout</h1>
      <p>
        Total: {checkout.total} {checkout.currency}
      </p>
      <button onClick={() => refetch()}>Refresh</button>
    </div>
  );
}
Returns:
  • data: Checkout object with all checkout data
  • isLoading: Boolean loading state
  • error: Error object if request failed
  • refetch(): Function to manually refetch data
  • isFetching: Boolean indicating background refetch
Checkout Data Structure:
interface CheckoutData {
  checkoutSession: {
    id: string;
    token: string;
    status: string;
  };
  items: CartItem[];
  total: number;
  currency: string;
  customer?: CustomerInfo;
  shipping?: ShippingInfo;
  payment?: PaymentInfo;
}

useProducts()

Fetch product catalog with automatic caching.
import { useProducts } from '@tagadapay/plugin-sdk/v2';

function ProductCatalog() {
  const { data: products, isLoading } = useProducts();

  return (
    <div>
      {products?.map((product) => (
        <ProductCard key={product.id} product={product} />
      ))}
    </div>
  );
}
Returns:
  • data: Array of product objects
  • isLoading: Loading state
  • error: Error state
  • refetch(): Manual refetch function

useOffer()

Fetch dynamic offers and pricing.
import { useOffer } from '@tagadapay/plugin-sdk/v2';

function OffersSection() {
  const { data: offers } = useOffer();

  return (
    <div>
      {offers?.map((offer) => (
        <OfferCard key={offer.id} offer={offer} />
      ))}
    </div>
  );
}

usePromotions()

Fetch active promotions and campaigns.
import { usePromotions } from '@tagadapay/plugin-sdk/v2';

function PromotionsBanner() {
  const { data: promotions, isLoading } = usePromotions();

  return (
    <div>
      {promotions?.map((promo) => (
        <PromotionBadge key={promo.id} promotion={promo} />
      ))}
    </div>
  );
}

useDiscounts()

Manage discount codes and validation.
import { useDiscounts } from '@tagadapay/plugin-sdk/v2';

function DiscountInput() {
  const { data: discounts, mutate: applyDiscount } = useDiscounts();

  const handleApply = (code: string) => {
    applyDiscount({ code });
  };

  return (
    <div>
      <input type="text" placeholder="Enter discount code" onBlur={(e) => handleApply(e.target.value)} />
      {discounts?.applied && <p>✅ Discount applied: {discounts.applied.code}</p>}
    </div>
  );
}

useOrder()

Fetch order details.
import { useOrder } from '@tagadapay/plugin-sdk/v2';

function OrderDetails({ orderId }: { orderId: string }) {
  const { data: order, isLoading } = useOrder({ orderId });

  if (isLoading) return <div>Loading order...</div>;

  return (
    <div>
      <h2>Order #{order.id}</h2>
      <p>Status: {order.status}</p>
      <p>
        Total: {order.total} {order.currency}
      </p>
    </div>
  );
}

useOrderBump()

Manage upsell offers (order bumps).
import { useOrderBump } from '@tagadapay/plugin-sdk/v2';

function OrderBumpSection() {
  const { data: orderBumps } = useOrderBump();

  return (
    <div>
      {orderBumps?.map((bump) => (
        <OrderBumpCard key={bump.id} orderBump={bump} />
      ))}
    </div>
  );
}

useStoreConfig()

Access store configuration and settings.
import { useStoreConfig } from '@tagadapay/plugin-sdk/v2';

function StoreHeader() {
  const { data: config } = useStoreConfig();

  return (
    <header>
      <h1>{config?.storeName}</h1>
      <p>{config?.storeDescription}</p>
    </header>
  );
}

useShippingRates()

Fetch available shipping options.
import { useShippingRates } from '@tagadapay/plugin-sdk/v2';

function ShippingSelector() {
  const { data: rates, isLoading } = useShippingRates();

  return (
    <div>
      {rates?.map((rate) => (
        <ShippingOption key={rate.id} rate={rate} />
      ))}
    </div>
  );
}

usePostPurchases()

Fetch post-purchase offers.
import { usePostPurchases } from '@tagadapay/plugin-sdk/v2';

function PostPurchaseOffers() {
  const { data: offers } = usePostPurchases();

  return (
    <div>
      {offers?.map((offer) => (
        <PostPurchaseOffer key={offer.id} offer={offer} />
      ))}
    </div>
  );
}

useVipOffers()

Fetch VIP exclusive offers.
import { useVipOffers } from '@tagadapay/plugin-sdk/v2';

function VipSection() {
  const { data: vipOffers } = useVipOffers();

  return (
    <div className="vip-section">
      <h2>VIP Exclusive Offers</h2>
      {vipOffers?.map((offer) => (
        <VipOfferCard key={offer.id} offer={offer} />
      ))}
    </div>
  );
}

useClubOffers()

Manage subscription/club offers.
import { useClubOffers } from '@tagadapay/plugin-sdk/v2';

function ClubOffers() {
  const { data: clubOffers } = useClubOffers();

  return (
    <div>
      {clubOffers?.map((offer) => (
        <ClubOfferCard key={offer.id} offer={offer} />
      ))}
    </div>
  );
}

useCustomerOrders()

Fetch customer order history.
import { useCustomerOrders } from '@tagadapay/plugin-sdk/v2';

function OrderHistory() {
  const { data: orders, isLoading } = useCustomerOrders();

  if (isLoading) return <div>Loading orders...</div>;

  return (
    <div>
      <h2>Order History</h2>
      {orders?.map((order) => (
        <OrderCard key={order.id} order={order} />
      ))}
    </div>
  );
}

useCustomerSubscriptions()

Manage customer subscriptions.
import { useCustomerSubscriptions } from '@tagadapay/plugin-sdk/v2';

function Subscriptions() {
  const { data: subscriptions } = useCustomerSubscriptions();

  return (
    <div>
      {subscriptions?.map((sub) => (
        <SubscriptionCard key={sub.id} subscription={sub} />
      ))}
    </div>
  );
}

Mutation Hooks

useCheckout()

Manage checkout sessions with create, update, and payment capabilities.
import { useCheckout } from '@tagadapay/plugin-sdk/v2';

function CheckoutPage() {
  const { 
    checkout, 
    init,
    updateLineItems,
    updateCustomerAndSessionInfo,
    error 
  } = useCheckout({
    checkoutToken: '', // Empty if creating new checkout
  });

  // Initialize new checkout with items
  const handleCreateCheckout = async () => {
    await init({
      storeId: 'your-store-id',
      lineItems: [
        {
          variantId: 'variant_abc123',
          quantity: 1,
        },
      ],
    });
  };

  return <button onClick={handleCreateCheckout}>Create Checkout</button>;
}
Parameters:
  • checkoutToken: String - Existing checkout token, or empty string to create new
Returns:
  • checkout: Checkout session object
  • init(): Function to create a new checkout session with line items
  • updateLineItems(): Function to update cart items
  • updateCustomerAndSessionInfo(): Function to update customer/shipping info
  • error: Error object if any operation fails
Creating a checkout from scratch? See the complete Initialize Checkout guide for detailed examples including BOGO funnels, bundle selectors, and static resources.

usePayment()

Process payments with automatic state management.
import { usePayment } from '@tagadapay/plugin-sdk/v2';

function PaymentForm() {
  const { mutate: processPayment, isPending, error } = usePayment();

  const handleSubmit = async (paymentData) => {
    await processPayment({
      method: 'card',
      cardNumber: '4242424242424242',
      // ... other payment data
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Payment form fields */}
      <button type="submit" disabled={isPending}>
        {isPending ? 'Processing...' : 'Pay Now'}
      </button>
      {error && <p>Error: {error.message}</p>}
    </form>
  );
}

usePaymentPolling()

Poll payment status for async payments.
import { usePaymentPolling } from '@tagadapay/plugin-sdk/v2';

function PaymentStatus({ paymentId }: { paymentId: string }) {
  const { data: status, isPolling } = usePaymentPolling({ paymentId });

  return (
    <div>
      {isPolling && <p>Checking payment status...</p>}
      <p>Status: {status?.status}</p>
    </div>
  );
}

Utility Hooks

useAuth()

Manage authentication and user sessions.
import { useAuth } from '@tagadapay/plugin-sdk/v2';

function AuthButton() {
  const { user, isAuthenticated, login, logout } = useAuth();

  if (isAuthenticated) {
    return (
      <div>
        <p>Welcome, {user?.name}</p>
        <button onClick={logout}>Logout</button>
      </div>
    );
  }

  return <button onClick={login}>Login</button>;
}
Returns:
  • user: Current user object
  • isAuthenticated: Boolean auth state
  • login(): Login function
  • logout(): Logout function
  • isLoading: Auth check in progress

useCustomer()

Access customer profile data.
import { useCustomer } from '@tagadapay/plugin-sdk/v2';

function CustomerProfile() {
  const { data: customer, updateProfile } = useCustomer();

  return (
    <div>
      <h2>
        {customer?.firstName} {customer?.lastName}
      </h2>
      <p>{customer?.email}</p>
      <button onClick={() => updateProfile({ phone: '123-456-7890' })}>Update Phone</button>
    </div>
  );
}

useCustomerInfos()

Manage customer information and validation.
import { useCustomerInfos } from '@tagadapay/plugin-sdk/v2';

function CustomerInfoForm() {
  const { data, update, validate } = useCustomerInfos();

  const handleSubmit = async (formData) => {
    const isValid = await validate(formData);
    if (isValid) {
      await update(formData);
    }
  };

  return <form onSubmit={handleSubmit}>{/* form fields */}</form>;
}

useCredits()

Manage store credit and balance.
import { useCredits } from '@tagadapay/plugin-sdk/v2';

function CreditBalance() {
  const { data: credits, apply, remove } = useCredits();

  return (
    <div>
      <p>Available Credits: ${credits?.balance}</p>
      <button onClick={() => apply(10)}>Apply $10 Credit</button>
      {credits?.applied && <button onClick={remove}>Remove Credit</button>}
    </div>
  );
}

useFunnel()

Navigate and track funnel steps.
import { useFunnel } from '@tagadapay/plugin-sdk/v2';

function FunnelNavigation() {
  const { currentStep, nextStep, previousStep, goToStep } = useFunnel();

  return (
    <div>
      <p>Current Step: {currentStep}</p>
      <button onClick={previousStep}>← Back</button>
      <button onClick={nextStep}>Next →</button>
      <button onClick={() => goToStep(3)}>Skip to Step 3</button>
    </div>
  );
}

useCheckoutToken()

Manage checkout session tokens.
import { useCheckoutToken } from '@tagadapay/plugin-sdk/v2';

function CheckoutSession() {
  const { checkoutToken, isValid, refresh } = useCheckoutToken();

  if (!isValid) {
    return (
      <div>
        Session expired. <button onClick={refresh}>Refresh</button>
      </div>
    );
  }

  return <div>Token: {checkoutToken}</div>;
}

useCurrency()

Format money and handle currency conversions.
import { useCurrency } from '@tagadapay/plugin-sdk/v2';

function PriceDisplay({ amount, currency }) {
  const { formatMoney, convertCurrency } = useCurrency();

  return (
    <div>
      <p>Price: {formatMoney(amount, currency)}</p>
      <p>In USD: {formatMoney(convertCurrency(amount, currency, 'USD'), 'USD')}</p>
    </div>
  );
}
formatMoney Options:
formatMoney(amount: number, currency: string, options?: {
  showSymbol?: boolean;     // Show currency symbol (default: true)
  showCode?: boolean;       // Show currency code (default: false)
  decimals?: number;        // Decimal places (default: 2)
  locale?: string;          // Locale for formatting (default: 'en-US')
})

useGeoLocation()

Detect user’s geographic location.
import { useGeoLocation } from '@tagadapay/plugin-sdk/v2';

function LocationBasedContent() {
  const { country, region, city, loading } = useGeoLocation();

  if (loading) return <div>Detecting location...</div>;

  return (
    <div>
      <p>
        Shipping to: {city}, {region}, {country}
      </p>
    </div>
  );
}

usePluginConfig()

Access plugin-specific configuration.
import { usePluginConfig } from '@tagadapay/plugin-sdk/v2';

function ThemedButton() {
  const config = usePluginConfig();

  return (
    <button
      style={{
        backgroundColor: config?.theme?.primaryColor,
        color: config?.theme?.textColor,
      }}
    >
      Buy Now
    </button>
  );
}

useTranslation()

Internationalization and localization.
import { useTranslation } from '@tagadapay/plugin-sdk/v2';

function TranslatedContent() {
  const { formatMessage, locale, changeLocale } = useTranslation();

  return (
    <div>
      <h1>{formatMessage({ id: 'checkout.title' })}</h1>
      <p>Current locale: {locale}</p>
      <button onClick={() => changeLocale('fr')}>French</button>
      <button onClick={() => changeLocale('es')}>Spanish</button>
    </div>
  );
}

useApiClient()

Direct access to API client for custom requests.
import { useApiClient } from '@tagadapay/plugin-sdk/v2';

function CustomApiCall() {
  const apiClient = useApiClient();

  const fetchCustomData = async () => {
    const response = await apiClient.get('/custom-endpoint');
    return response.data;
  };

  return <button onClick={fetchCustomData}>Fetch Data</button>;
}

useApiQuery()

Create custom API queries with TanStack Query.
import { useApiQuery } from '@tagadapay/plugin-sdk/v2';

function CustomQuery() {
  const { data, isLoading } = useApiQuery({
    queryKey: ['custom-data'],
    queryFn: async () => {
      // Custom API call
      return await fetch('/api/custom').then((r) => r.json());
    },
  });

  return <div>{data?.result}</div>;
}

Payment Hooks

useThreeds()

Handle 3D Secure authentication.
import { useThreeds } from '@tagadapay/plugin-sdk/v2';

function PaymentWithThreeDS() {
  const { handleThreeDS, isProcessing } = useThreeds();

  const processPayment = async (paymentData) => {
    const result = await handleThreeDS(paymentData);
    if (result.authenticated) {
      // Proceed with payment
    }
  };

  return (
    <button onClick={() => processPayment(data)} disabled={isProcessing}>
      Pay with 3DS
    </button>
  );
}

useThreedsModal()

Manage 3DS modal display.
import { useThreedsModal } from '@tagadapay/plugin-sdk/v2';

function ThreeDSModalManager() {
  const { isOpen, open, close, authUrl } = useThreedsModal();

  return (
    <>
      {isOpen && (
        <div className="modal">
          <iframe src={authUrl} />
          <button onClick={close}>Cancel</button>
        </div>
      )}
    </>
  );
}

useExpressPaymentMethods()

Integrate Apple Pay and Google Pay.
import { useExpressPaymentMethods } from '@tagadapay/plugin-sdk/v2';

function ExpressCheckout() {
  const { applePay, googlePay, isAvailable } = useExpressPaymentMethods();

  return (
    <div>
      {isAvailable.applePay && <button onClick={() => applePay.pay()}>Apple Pay</button>}
      {isAvailable.googlePay && <button onClick={() => googlePay.pay()}>Google Pay</button>}
    </div>
  );
}

Location Hooks

useGoogleAutocomplete()

Address autocomplete with Google Places API.
import { useGoogleAutocomplete } from '@tagadapay/plugin-sdk/v2';

function AddressInput() {
  const { getPlacePredictions, getPlaceDetails } = useGoogleAutocomplete();

  const [predictions, setPredictions] = useState([]);

  const handleSearch = async (input) => {
    const results = await getPlacePredictions(input);
    setPredictions(results);
  };

  const handleSelect = async (placeId) => {
    const details = await getPlaceDetails(placeId);
    // Use address details
  };

  return (
    <div>
      <input type="text" onChange={(e) => handleSearch(e.target.value)} placeholder="Enter address" />
      <ul>
        {predictions.map((p) => (
          <li key={p.place_id} onClick={() => handleSelect(p.place_id)}>
            {p.description}
          </li>
        ))}
      </ul>
    </div>
  );
}

useISOData()

Access country and region data.
import { useISOData } from '@tagadapay/plugin-sdk/v2';

function CountrySelector() {
  const { countries, regions, getCountry, getRegions } = useISOData();

  const [selectedCountry, setSelectedCountry] = useState('US');

  const countryData = getCountry(selectedCountry);
  const countryRegions = getRegions(selectedCountry);

  return (
    <div>
      <select onChange={(e) => setSelectedCountry(e.target.value)}>
        {countries.map((country) => (
          <option key={country.code} value={country.code}>
            {country.name}
          </option>
        ))}
      </select>
      <select>
        {countryRegions?.map((region) => (
          <option key={region.code} value={region.code}>
            {region.name}
          </option>
        ))}
      </select>
    </div>
  );
}

Components

ApplePayButton

Pre-styled Apple Pay button component.
import { ApplePayButton } from '@tagadapay/plugin-sdk/v2';

function Checkout() {
  const handleApplePay = async (paymentData) => {
    // Process Apple Pay payment
  };

  return <ApplePayButton onPayment={handleApplePay} amount={99.99} currency="USD" />;
}

GooglePayButton

Pre-styled Google Pay button component.
import { GooglePayButton } from '@tagadapay/plugin-sdk/v2';

function Checkout() {
  const handleGooglePay = async (paymentData) => {
    // Process Google Pay payment
  };

  return <GooglePayButton onPayment={handleGooglePay} amount={99.99} currency="USD" />;
}

DebugDrawer

Development helper for debugging plugin state.
import { DebugDrawer } from '@tagadapay/plugin-sdk/v2';

function App() {
  return (
    <div>
      <YourPlugin />
      {process.env.NODE_ENV === 'development' && <DebugDrawer />}
    </div>
  );
}

Path Remapping Functions

Path Remapping Guide

See the complete path remapping guide for detailed examples, testing, and advanced patterns

matchRoute()

New in v2.7.14 Check if the current URL matches an internal path pattern AND extract URL parameters. Signature:
function matchRoute(internalPath: string): RouteMatchResult;

interface RouteMatchResult {
  matched: boolean;
  params: Record<string, string>;
}
Parameters:
  • internalPath - Your plugin’s internal path pattern (e.g., /checkout, /product/:id)
Returns:
  • matched - true if the current URL matches the internal path (considering remapping)
  • params - Object containing extracted URL parameters
Example 1: Basic Usage
import { matchRoute } from '@tagadapay/plugin-sdk/v2';

function RemappableRoutes() {
  const match = matchRoute('/checkout');

  if (match.matched) {
    return <CheckoutPage />;
  }

  return <NotFound />;
}
Example 2: Parameter Extraction
function ProductRoutes() {
  const match = matchRoute('/product/:productId');

  if (match.matched) {
    // ✅ Params automatically extracted!
    // Works with both:
    // - /product/headphones (no remapping)
    // - /p/headphones (remapped to /product/:productId)
    return <ProductPage productId={match.params.productId} />;
  }

  return <NotFound />;
}
Example 3: Multiple Parameters
function OrderRoutes() {
  const match = matchRoute('/order/:orderId/item/:itemId');

  if (match.matched) {
    const { orderId, itemId } = match.params;
    return <OrderItemPage orderId={orderId} itemId={itemId} />;
  }

  return <NotFound />;
}
Example 4: Conditional Rendering
function App() {
  const checkoutMatch = matchRoute('/checkout/:step');
  const productMatch = matchRoute('/product/:id');

  if (checkoutMatch.matched) {
    return <CheckoutFlow step={checkoutMatch.params.step} />;
  }

  if (productMatch.matched) {
    return <ProductDetail id={productMatch.params.id} />;
  }

  return <HomePage />;
}

shouldMatchRoute()

Check if the current URL matches an internal path pattern (without parameter extraction).
Tip: Use matchRoute() instead if you need URL parameters. shouldMatchRoute() only returns a boolean.
Signature:
function shouldMatchRoute(internalPath: string): boolean;
Parameters:
  • internalPath - Your plugin’s internal path pattern
Returns:
  • boolean - true if the current URL matches
Example:
import { shouldMatchRoute } from '@tagadapay/plugin-sdk/v2';

function RemappableRoute() {
  // Simple boolean check
  if (shouldMatchRoute('/checkout')) {
    return <CheckoutPage />;
  }

  if (shouldMatchRoute('/products/:id')) {
    return <ProductPage />;
  }

  return <NotFound />;
}
When to use:
  • ✅ Simple route matching without parameters
  • ✅ Conditional rendering based on route
  • ✅ Route guards and redirects
When to use matchRoute() instead:
  • ✅ When you need URL parameters
  • ✅ When passing params to child components

getPathInfo()

Get detailed information about the current path and remapping status. Signature:
function getPathInfo(): PathInfo;

interface PathInfo {
  externalPath: string; // URL the user sees in browser
  internalPath: string | null; // Plugin's internal path (if remapped)
  isRemapped: boolean; // Whether path remapping is active
  query: URLSearchParams; // Query string parameters
  hash: string; // URL hash fragment
}
Returns:
  • PathInfo object with detailed path information
Example 1: Debug Panel
import { getPathInfo } from '@tagadapay/plugin-sdk/v2';

function PathDebugger() {
  const pathInfo = getPathInfo();

  return (
    <div className="debug-panel">
      <h3>🔍 Path Information</h3>

      <dl>
        <dt>Current URL:</dt>
        <dd>
          <code>{pathInfo.externalPath}</code>
        </dd>

        {pathInfo.isRemapped && (
          <>
            <dt>Internal Path:</dt>
            <dd>
              <code>{pathInfo.internalPath}</code>
            </dd>

            <dt>Status:</dt>
            <dd>✅ Path remapping active</dd>
          </>
        )}

        {!pathInfo.isRemapped && (
          <>
            <dt>Status:</dt>
            <dd>ℹ️ No remapping (using original paths)</dd>
          </>
        )}

        {pathInfo.query.size > 0 && (
          <>
            <dt>Query Parameters:</dt>
            <dd>
              <code>?{pathInfo.query.toString()}</code>
            </dd>
          </>
        )}

        {pathInfo.hash && (
          <>
            <dt>Hash:</dt>
            <dd>
              <code>{pathInfo.hash}</code>
            </dd>
          </>
        )}
      </dl>
    </div>
  );
}
Example 2: SEO Canonical URL
import { Helmet } from 'react-helmet';

function CheckoutPage() {
  const pathInfo = getPathInfo();

  // Use external path for SEO (what user/search engines see)
  const canonicalUrl = `https://example.com${pathInfo.externalPath}`;

  return (
    <>
      <Helmet>
        <link rel="canonical" href={canonicalUrl} />
        <meta property="og:url" content={canonicalUrl} />
      </Helmet>
      <div>Checkout content...</div>
    </>
  );
}
Example 3: Analytics Tracking
function AnalyticsTracker() {
  const pathInfo = getPathInfo();

  useEffect(() => {
    // Track with external path (user-facing URL)
    analytics.page({
      path: pathInfo.externalPath,
      isRemapped: pathInfo.isRemapped,
      internalPath: pathInfo.internalPath,
    });
  }, [pathInfo.externalPath]);

  return null;
}
Example 4: Conditional Feature Display
function RemappingIndicator() {
  const pathInfo = getPathInfo();

  // Show indicator only in development
  if (process.env.NODE_ENV !== 'development') return null;

  if (!pathInfo.isRemapped) return null;

  return (
    <div className="dev-indicator">
      🔄 Path Remapping Active
      <br />
      External: {pathInfo.externalPath}
      <br />
      Internal: {pathInfo.internalPath}
    </div>
  );
}

getInternalPath()

Get the current internal path, or null if no remapping is active. Signature:
function getInternalPath(): string | null;
Returns:
  • string - Internal path if remapping is active
  • null - If no remapping is active
Example 1: Simple Check
import { getInternalPath } from '@tagadapay/plugin-sdk/v2';

function CurrentPath() {
  const internalPath = getInternalPath();

  if (internalPath) {
    return (
      <div>
        ✅ Remapping active
        <br />
        Internal path: <code>{internalPath}</code>
      </div>
    );
  }

  return <div>ℹ️ No remapping - using original paths</div>;
}
Example 2: Conditional Logic
function App() {
  const internalPath = getInternalPath();

  // Different behavior based on remapping
  if (internalPath) {
    console.log('Plugin remapped to:', internalPath);
  } else {
    console.log('Plugin using original paths');
  }

  return <YourApp />;
}
When to use:
  • ✅ Quick remapping status check
  • ✅ Logging and debugging
  • ✅ Conditional behavior based on remapping
When to use getPathInfo() instead:
  • ✅ Need both external and internal paths
  • ✅ Need query parameters or hash
  • ✅ Building debug UI

Path Remapping Types

RouteMatchResult

interface RouteMatchResult {
  matched: boolean; // Whether route matched
  params: Record<string, string>; // Extracted URL parameters
}
Example Usage:
const result = matchRoute('/product/:productId');

if (result.matched) {
  console.log('Product ID:', result.params.productId);
}

PathInfo

interface PathInfo {
  externalPath: string; // User-facing URL
  internalPath: string | null; // Plugin's internal path
  isRemapped: boolean; // Remapping status
  query: URLSearchParams; // Query parameters
  hash: string; // URL hash (#fragment)
}
Example:
const info = getPathInfo();

// info.externalPath = "/buy-now"
// info.internalPath = "/checkout"
// info.isRemapped = true
// info.query = URLSearchParams { }
// info.hash = ""

Path Remapping Best Practices

Never parse window.location directly! Always use SDK functions to ensure remapping works correctly.

✅ Good Practices

// ✅ Use matchRoute() for params
const match = matchRoute('/product/:id');
if (match.matched) {
  return <Product id={match.params.id} />;
}

// ✅ Use shouldMatchRoute() for simple checks
if (shouldMatchRoute('/checkout')) {
  return <CheckoutPage />;
}

// ✅ Use getPathInfo() for detailed info
const pathInfo = getPathInfo();
if (pathInfo.isRemapped) {
  console.log('External:', pathInfo.externalPath);
  console.log('Internal:', pathInfo.internalPath);
}

❌ Bad Practices

// ❌ Don't parse window.location manually
if (window.location.pathname === '/checkout') {
  // Won't work with remapping!
}

// ❌ Don't use React Router params directly with remapping
const { id } = useParams(); // May be empty with remapping
return <Product id={id} />; // ❌

// ✅ Instead, use matchRoute()
const match = matchRoute('/product/:id');
if (match.matched) {
  return <Product id={match.params.id} />; // ✅
}

// ❌ Don't assume specific URL format
if (location.pathname.startsWith('/checkout/')) {
  // Won't work if remapped to /buy-now/
}

// ✅ Use SDK functions
if (shouldMatchRoute('/checkout/*')) {
  // Works with any external URL
}

Complete Path Remapping Guide

See the complete guide for configuration, testing, troubleshooting, and advanced patterns

TypeScript Types

The SDK exports comprehensive TypeScript types:
import type {
  CheckoutData,
  ProductData,
  OfferData,
  OrderData,
  CustomerData,
  PaymentData,
  ShippingData,
  // ... many more
} from '@tagadapay/plugin-sdk/v2';

Best Practices

1. Always Use V2 for New Projects

// ✅ Recommended
import { useCheckout } from '@tagadapay/plugin-sdk/v2';

// ❌ Avoid (V1)
import { useCheckout } from '@tagadapay/plugin-sdk';

2. Handle Loading and Error States

function SafeComponent() {
  const { data, isLoading, error } = useCheckout();

  if (isLoading) return <LoadingSpinner />;
  if (error) return <ErrorMessage error={error} />;
  if (!data) return <EmptyState />;

  return <YourContent data={data} />;
}

3. Use TanStack Query Features

function OptimizedComponent() {
  const { data, refetch } = useCheckout({
    staleTime: 60000, // Cache for 1 minute
    refetchInterval: 30000, // Refetch every 30s
    refetchOnWindowFocus: true, // Refetch on tab focus
  });

  return <YourContent data={data} />;
}

4. Combine Multiple Hooks

function ComprehensiveCheckout() {
  const { data: checkout } = useCheckout();
  const { data: offers } = useOffers();
  const { formatMoney } = useCurrency();
  const { mutate: pay, isPending } = usePayment();

  // Use all data together
  return (
    <CheckoutUI
      checkout={checkout}
      offers={offers}
      formatMoney={formatMoney}
      onPay={pay}
      isProcessing={isPending}
    />
  );
}

Support