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.
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
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 );
}
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.
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 } `
}
});
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 );
}
One-Time Purchase
Subscription
Gift Purchase
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.
Token Security : Store customer tokens securely (HttpOnly cookies, secure storage)
Error Handling : Always check for errors in API responses
Loading States : Show loading indicators during API calls
Cart Persistence : The cart is managed server-side and persists across sessions
Price Display : Use price_final from the pricing object for accurate display
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