Skip to main content

Overview

The Storefront API provides all the operations needed to build a complete customer-facing shopping experience. This guide covers the most common operations with practical examples.

Getting Store Information

Retrieve your store’s configuration and branding:
const store = await client.GET('/v1/store');

if (store.data) {
  console.log('Store Name:', store.data.name);
  console.log('Currency:', store.data.currency);
  console.log('Platform:', store.data.platform);
}
The store endpoint uses either the x-paynow-store-id header or extracts the store from a Customer token.

Product Browsing

List All Products

Fetch all available products for display:
const products = await client.GET('/v1/store/products', {
  headers: {
    'x-paynow-store-id': 'YOUR_STORE_ID',
    // Include IP headers for accurate VAT rates
    'CF-Connecting-IP': customerIP,
    'CF-IPCountry': customerCountry
  }
});

if (products.data) {
  products.data.forEach(product => {
    console.log(product.name, product.pricing?.price_final);
  });
}

Get Single Product

Retrieve a specific product by ID or slug:
const product = await client.GET('/v1/store/products/{idOrSlug}', {
  params: {
    path: { idOrSlug: 'premium-package' }
  },
  headers: {
    'x-paynow-store-id': 'YOUR_STORE_ID'
  }
});

if (product.data) {
  console.log('Product:', product.data.name);
  console.log('Description:', product.data.description);
  console.log('Price:', product.data.pricing?.price_final);
  console.log('Tags:', product.data.tags);
}
Get the store’s navigation structure for building menus:
const navlinks = await client.GET('/v1/store/navlinks', {
  headers: { 'x-paynow-store-id': 'YOUR_STORE_ID' }
});

const tags = await client.GET('/v1/store/tags', {
  headers: { 'x-paynow-store-id': 'YOUR_STORE_ID' }
});

Customer Authentication

Authenticate a customer to get a customer token:
const auth = await client.POST('/v1/store/customer/auth', {
  body: {
    platform: 'steam',
    id: '76561198152492642'
  },
  headers: { 'x-paynow-store-id': 'YOUR_STORE_ID' }
});

if (auth.data) {
  const customerToken = auth.data.customer_token;
  // Store this token for subsequent requests
}
Supported platforms: steam, minecraft, paynow_name, xbox_xuid, and more.

Get Current Customer

Retrieve the authenticated customer’s information:
const customer = await client.GET('/v1/store/customer', {
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});

if (customer.data) {
  console.log('Customer:', customer.data.name);
  console.log('Steam ID:', customer.data.steam_id);
}

Cart Operations

1

Get the Current Cart

Retrieve the customer’s shopping cart:
const cart = await client.GET('/v1/store/cart', {
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});

if (cart.data) {
  console.log('Cart total:', cart.data.total);
  console.log('Items:', cart.data.lines);
}
2

Add Products to Cart

Add or update product quantities:
const result = await client.PUT('/v1/store/cart/lines', {
  body: {
    product_id: 'PRODUCT_ID',
    quantity: 2,
    subscription: false,
    increment: true // Add to existing quantity
  },
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});
Set increment: false to replace the quantity instead of adding to it.
3

Add with Custom Variables

When a product has custom variables:
const result = await client.PUT('/v1/store/cart/lines', {
  body: {
    product_id: 'PRODUCT_ID',
    quantity: 1,
    custom_variables: {
      'player_name': 'john_doe',
      'server_choice': 'us-east'
    }
  },
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});
4

Clear the Cart

Remove all items from the cart:
await client.DELETE('/v1/store/cart', {
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});

Checkout Flow

Cart-Based Checkout

Create a checkout session from the current cart:
const checkout = await client.POST('/v1/store/cart/checkout', {
  body: {
    return_url: 'https://yourstore.com/success',
    cancel_url: 'https://yourstore.com/cart',
    affiliate_code: 'PARTNER123',
    auto_redirect: true
  },
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});

if (checkout.data) {
  // Redirect customer to PayNow checkout page
  window.location.href = checkout.data.url;
}

Direct Checkout

Create a checkout session without using the cart:
const checkout = await client.POST('/v1/checkouts', {
  body: {
    lines: [
      {
        product_id: 'PRODUCT_ID',
        quantity: 1,
        subscription: false,
        custom_variables: {
          'server': 'main'
        }
      }
    ],
    return_url: 'https://yourstore.com/success',
    cancel_url: 'https://yourstore.com/cancel'
  },
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});

if (checkout.data) {
  console.log('Checkout URL:', checkout.data.url);
  console.log('Session ID:', checkout.data.id);
}
const checkout = await client.POST('/v1/checkouts', {
  body: {
    lines: [{
      product_id: 'PRODUCT_ID',
      quantity: 1,
      subscription: false
    }]
  },
  headers: { 'Authorization': `Bearer ${customerToken}` }
});

Delivery Items

Retrieve a customer’s purchased items (inventory):
const items = await client.GET('/v1/store/customer/delivery/items', {
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});

if (items.data) {
  items.data.forEach(item => {
    console.log('Product:', item.product.name);
    console.log('State:', item.state);
    console.log('Expires:', item.expires_at);
  });
}
Delivery item states: usable, active, used, revoked, renewed

Gift Cards

Look up a gift card balance:
const giftcard = await client.GET('/v1/store/customer/giftcards/lookup/{code}', {
  params: {
    path: { code: 'GIFTCARD-CODE' }
  },
  headers: {
    'Authorization': `Bearer ${customerToken}`
  }
});

if (giftcard.data) {
  console.log('Balance:', giftcard.data.balance);
  console.log('Starting Balance:', giftcard.data.starting_balance);
  console.log('Expires:', giftcard.data.expires_at);
}

Best Practices

Always include IP headers (CF-Connecting-IP, CF-IPCountry) when fetching products to ensure accurate VAT calculations.
  1. Token Security: Store customer tokens securely (HttpOnly cookies, secure storage)
  2. Error Handling: Always check for errors in API responses
  3. Loading States: Show loading indicators during API calls
  4. Cart Persistence: The cart is managed server-side and persists across sessions
  5. Price Display: Use price_final from the pricing object for accurate display
  6. Subscription Support: Check allow_subscription before offering subscription options

Common Patterns

Product Filtering by Tag

// Get all products, then filter by tag
const products = await client.GET('/v1/store/products', {
  headers: { 'x-paynow-store-id': 'YOUR_STORE_ID' }
});

if (products.data) {
  const filtered = products.data.filter(product => 
    product.tags.some(tag => tag.slug === 'featured')
  );
}

Handling Sales & Discounts

if (product.data?.pricing?.active_sale) {
  const sale = product.data.pricing.active_sale;
  console.log('On Sale:', sale.name);
  console.log('Original:', product.data.pricing.price_original);
  console.log('Final:', product.data.pricing.price_final);
}

Next Steps

Management Operations

Learn how to manage products, orders, and customers

Webhooks

Set up webhooks to receive real-time event notifications

Build docs developers (and LLMs) love