# Products

## Get products

> Retrieves the available products. To make sure all VAT rates are properly displayed, pass in the IP headers as instructed.

```json
{"openapi":"3.1.1","info":{"title":"PayNow Storefront (Headless) API","version":"v1"},"tags":[{"name":"products"}],"security":[{},{"Customer":[],"APIKey":[]}],"components":{"securitySchemes":{"Customer":{"type":"apiKey","description":"A Customer token generated using an API Key in the format 'Customer TOKEN_HERE'.","name":"Authorization","in":"header"}},"schemas":{"StorefrontProductDto":{"required":["allow_one_time_purchase","allow_subscription","currency","custom_variables","description","gameservers","id","is_affiliate_links_disabled","is_coupons_disabled","is_gift_cards_disabled","is_gifting_disabled","name","price","remove_after_enabled","remove_after_time_scale","remove_after_time_value","single_game_server_only","slug","sort_order","store_id","subscription_interval_scale","subscription_interval_value","tags","trial","version_id"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"store_id":{"$ref":"#/components/schemas/FlakeId"},"version_id":{"$ref":"#/components/schemas/FlakeId"},"image_url":{"type":["null","string"],"description":"The URL to the product image."},"slug":{"type":"string","description":"The unique slug for the product."},"name":{"type":"string","description":"The display name of the product."},"description":{"type":"string","description":"The detailed description of the product."},"enabled_at":{"type":["null","string"],"description":"The date and time when the product becomes enabled.","format":"date-time"},"enabled_until":{"type":["null","string"],"description":"The date and time until which the product remains enabled.","format":"date-time"},"label":{"type":["null","string"],"description":"The display label for the product."},"sort_order":{"type":"integer","description":"The sort order for displaying the product.","format":"int32"},"price":{"type":"integer","description":"The price of the product, in the lowest denominator (e.g. cents).","format":"int64"},"currency":{"type":"string","description":"The ISO three-letter lowercase currency code (e.g., usd, eur, gbp) the product is denominated in."},"single_game_server_only":{"type":"boolean","description":"Indicates whether the product is limited to a single game server."},"allow_one_time_purchase":{"type":"boolean","description":"Indicates whether one-time purchases are allowed."},"allow_subscription":{"type":"boolean","description":"Indicates whether subscription purchases are allowed."},"is_gifting_disabled":{"type":"boolean","description":"Indicates whether gifting is disabled for this product."},"is_gift_cards_disabled":{"type":"boolean","description":"Indicates whether gift cards are disabled entirely for the product."},"is_coupons_disabled":{"type":"boolean","description":"Indicates whether coupons are disabled entirely for the product."},"is_affiliate_links_disabled":{"type":"boolean","description":"Indicates whether affiliate links are disabled entirely for the product."},"subscription_interval_value":{"type":"integer","description":"The subscription interval value.","format":"int32"},"subscription_interval_scale":{"$ref":"#/components/schemas/ProductSubscriptionIntervalScale"},"remove_after_enabled":{"type":"boolean","description":"Indicates whether automatic removal is enabled."},"remove_after_time_value":{"type":"integer","description":"The time value for automatic removal.","format":"int32"},"remove_after_time_scale":{"$ref":"#/components/schemas/ProductRemoveAfterIntervalScale"},"pricing":{"$ref":"#/components/schemas/StorefrontProductPricingDetailsDto"},"stock":{"$ref":"#/components/schemas/StorefrontProductStockStatusDto"},"trial":{"$ref":"#/components/schemas/StorefrontProductTrialDto"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/ProductTagDto"},"description":"The tags associated with the product."},"gameservers":{"type":"array","items":{"$ref":"#/components/schemas/ProductGameServerDto"},"description":"The game servers associated with the product."},"custom_variables":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontCustomVariableDto"},"description":"Custom Variables associated with the product."},"deliverable_actions":{"$ref":"#/components/schemas/ProductDeliverableActionsDto"},"metadata":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Additional metadata for the product."},"created_at":{"type":["null","string"],"description":"The date and time when the product was created.","format":"date-time"},"updated_at":{"type":["null","string"],"description":"The date and time when the product was last updated.","format":"date-time"},"tier_group_id":{"$ref":"#/components/schemas/FlakeId"},"active_tier_group":{"$ref":"#/components/schemas/CustomerTierGroupDto"}},"additionalProperties":false},"FlakeId":{"type":"string","additionalProperties":false,"format":"flake-id"},"ProductSubscriptionIntervalScale":{"enum":["invalid","day","week","month","year"],"type":"string"},"ProductRemoveAfterIntervalScale":{"enum":["invalid","day","week","month"],"type":"string"},"StorefrontProductPricingDetailsDto":{"required":["price_final","price_original","upsell_discount_amount"],"type":"object","properties":{"active_sale":{"$ref":"#/components/schemas/StorefrontSaleDto"},"sale_value":{"type":["null","integer"],"description":"The amount of the sale discount in the lowest denominator (e.g. cents).","format":"int64"},"upsell_offer_id":{"$ref":"#/components/schemas/FlakeId"},"upsell_discount_amount":{"type":"integer","format":"int64"},"vat_rate":{"$ref":"#/components/schemas/VatRateDto"},"regional_pricing":{"$ref":"#/components/schemas/StorefrontProductPricingDetailsRegionalPricingDto"},"price_original":{"type":"integer","description":"The original price of the product before any discounts, in the lowest denominator (e.g. cents).","format":"int64"},"price_final":{"type":"integer","description":"The final price of the product after all discounts, in the lowest denominator (e.g. cents).","format":"int64"}},"additionalProperties":false,"description":"The pricing details for the product in the storefront."},"StorefrontSaleDto":{"required":["begins_at","discount_amount","discount_type","id","minimum_order_value","name"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"name":{"type":"string","description":"The name of the sale."},"discount_type":{"$ref":"#/components/schemas/SaleDiscountType"},"discount_amount":{"type":"integer","description":"The amount of the discount, either as a percentage in permille or as an absolute value in cents.","format":"int64"},"minimum_order_value":{"type":"integer","description":"The minimum order value required to apply the discount, in the lowest denominator (e.g. cents).","format":"int64"},"begins_at":{"type":"string","description":"The date and time when the sale begins.","format":"date-time"},"ends_at":{"type":["null","string"],"description":"The date and time when the sale ends, if applicable.","format":"date-time"}},"additionalProperties":false},"SaleDiscountType":{"enum":["percent","amount"],"type":"string"},"VatRateDto":{"required":["country_code","country_name","currency","eservice_rate","eu_member_state","percentage","vat_abbreviation","vat_local_name"],"type":"object","properties":{"country_code":{"type":"string","description":"The ISO country code."},"country_name":{"type":"string","description":"The full name of the country."},"currency":{"type":"string","description":"The local currency used in the country."},"vat_abbreviation":{"type":"string","description":"The abbreviation of the VAT term in the local language."},"vat_local_name":{"type":"string","description":"The full name of the VAT term in the local language."},"eu_member_state":{"type":"boolean","description":"Indicates whether the country is a member of the European Union."},"eservice_rate":{"type":"number","description":"The VAT rate applicable for electronic services, as a percentage.","format":"double"},"percentage":{"type":"number","description":"The VAT rate (synonym for EServiceRate).","format":"double","readOnly":true}},"additionalProperties":false,"description":"The VAT rate estimation for the passed in customer country / IP.\nInclude the VAT percentage + abbreviation in your product view to inform your customers about the tax."},"StorefrontProductPricingDetailsRegionalPricingDto":{"required":["base_price","currency","region_id","tax_inclusive"],"type":"object","properties":{"region_id":{"type":"string","description":"The identifier for the region."},"currency":{"type":"string","description":"The currency code used in the region."},"tax_inclusive":{"type":"boolean","description":"Indicates whether the base price includes tax."},"base_price":{"type":"integer","description":"The base price in the regional currency, in the lowest denominator (e.g. cents).","format":"int64"}},"additionalProperties":false,"description":"Regional pricing information for this product.\nOnly present if there is a regional pricing configured."},"StorefrontProductStockStatusDto":{"required":["available_to_purchase","customer_available"],"type":"object","properties":{"available_to_purchase":{"type":"boolean","description":"Indicates whether the product is currently available for purchase (there is available stock)."},"customer_available":{"type":"integer","description":"The number of items available for the customer to purchase (customer stock limit remaining).","format":"int32"}},"additionalProperties":false,"description":"The stock status information for the product in the storefront."},"StorefrontProductTrialDto":{"required":["eligible","enabled","period_scale","period_value"],"type":"object","properties":{"enabled":{"type":"boolean","description":"Indicates whether the trial period is enabled for this product."},"eligible":{"type":"boolean","description":"Indicates whether the customer is eligible for the trial period."},"period_value":{"type":"integer","description":"The duration value of the trial period.","format":"int32"},"period_scale":{"$ref":"#/components/schemas/ProductSubscriptionIntervalScale"}},"additionalProperties":false},"ProductTagDto":{"required":["id","name","slug"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"slug":{"type":"string","description":"The unique slug for the tag."},"name":{"type":"string","description":"The display name of the tag."}},"additionalProperties":false},"ProductGameServerDto":{"required":["enabled","id","name"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"name":{"type":"string","description":"The name of the game server."},"enabled":{"type":"boolean","description":"Indicates whether this game server is enabled."}},"additionalProperties":false},"StorefrontCustomVariableDto":{"required":["description","identifier","name","options","type"],"type":"object","properties":{"identifier":{"type":"string","description":"Unique identifier string used to reference this custom variable programmatically.\nMust contain only letters, numbers, underscores, and hyphens."},"name":{"type":"string","description":"Display name for the custom variable shown to customers."},"description":{"type":"string","description":"Description explaining what this custom variable is for. Can be shown to customers."},"type":{"$ref":"#/components/schemas/CustomVariableType"},"value_regex":{"type":["null","string"],"description":"Optional regex pattern to validate text/number input values.\nOnly applies to text and number types.\nUses RE2 syntax - does not support negative lookarounds, backreferences, or other advanced regex features."},"options":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontCustomVariableOptionDto"},"description":"Available options for dropdown type custom variables.\nEmpty for text and number types."}},"additionalProperties":false},"CustomVariableType":{"enum":["dropdown","text","number"],"type":"string","description":"Defines the type of input method for a custom variable."},"StorefrontCustomVariableOptionDto":{"required":["is_default","name","price","sort_order","value"],"type":"object","properties":{"name":{"type":"string","description":"Display name shown to customers for this option."},"value":{"type":"string","description":"Internal value used for product command variable replacement, without brackets."},"price":{"type":"integer","description":"Additional price in the lowest denominator (e.g. cents) when this option is selected.","format":"int64"},"is_default":{"type":"boolean","description":"Whether this option is selected by default when the custom variable is presented.\nOnly one option per custom variable should be marked as default."},"sort_order":{"type":"integer","description":"Sort order for displaying options to customers.\nLower numbers appear first.","format":"int32"}},"additionalProperties":false},"ProductDeliverableActionsDto":{"required":["grant_giftcard"],"type":"object","properties":{"grant_giftcard":{"type":"boolean","description":"Value indicating whether to grant a giftcard with the product with the subtotal amount."}},"additionalProperties":false},"CustomerTierGroupDto":{"required":["active_product_id","currency","next_billing_amount","next_billing_presentment_amount","next_renewal_at","presentment_currency","tier_group_id"],"type":"object","properties":{"tier_group_id":{"$ref":"#/components/schemas/FlakeId"},"active_product_id":{"$ref":"#/components/schemas/FlakeId"},"pending_change_product_id":{"$ref":"#/components/schemas/FlakeId"},"next_renewal_at":{"type":"string","description":"The date and time of the next subscription renewal for this tier group.","format":"date-time"},"next_billing_amount":{"type":"integer","description":"The next billing amount in the smallest currency unit (e.g., cents) in the settlement currency.","format":"int64"},"next_billing_presentment_amount":{"type":"integer","description":"The next billing amount in the smallest currency unit (e.g., cents) in the customer-facing presentment currency.","format":"int64"},"currency":{"type":"string","description":"The settlement currency code (e.g., \"usd\")."},"presentment_currency":{"type":"string","description":"The customer-facing presentment currency code (e.g., \"eur\")."}},"additionalProperties":false},"PayNowError":{"required":["code","message","status"],"type":"object","properties":{"status":{"type":"integer","description":"The HTTP status code.","format":"int32"},"code":{"type":"string","description":"The PayNow parseable error code."},"message":{"type":"string","description":"The human-readable error message."},"trace_id":{"type":["null","string"],"description":"A distributed trace ID used for debugging."},"errors":{"type":["null","array"],"items":{"$ref":"#/components/schemas/ValidationError"},"description":"An array of multiple errors. Only used by some API services."}},"additionalProperties":false,"description":"Represents a PayNow error"},"ValidationError":{"required":["code","message","path","validation"],"type":"object","properties":{"code":{"type":"string","description":"The parseable error code."},"message":{"type":"string","description":"The human-readable error message."},"path":{"type":"string","description":"The path leading to the validation error."},"validation":{"type":"string","description":"Type of the validation that failed."}},"additionalProperties":false,"description":"A validation error."}}},"paths":{"/v1/store/products":{"get":{"tags":["products"],"summary":"Get products","description":"Retrieves the available products. To make sure all VAT rates are properly displayed, pass in the IP headers as instructed.","operationId":"StorefrontProducts_GetStorefrontProducts","parameters":[{"name":"tag","in":"query","description":"Tag slugs to filter by. Each tag slug is a separate query parameter.","schema":{"type":"array","items":{"type":"string"}}},{"name":"currency","in":"query","description":"The ISO three-letter lowercase currency code (e.g., usd, eur, gbp) to display prices in. If not provided, the store's default currency will be used.","schema":{"type":"string"}},{"name":"x-paynow-store-id","in":"header","description":"PayNow Store Identifier (Store ID) available in Store Settings","required":true,"schema":{"type":"string","format":"flake-id"}},{"name":"x-paynow-customer-ip","in":"header","description":"The IP address (IPv4 or IPv6) of the customer. Required if the request is not being made from the customer's browser.","schema":{"type":"string","format":"ipv4"}},{"name":"x-paynow-customer-countrycode","in":"header","description":"The customer's country code in ISO 3166-1 alpha-2 format. Optional, but recommended if you have this available.","schema":{"pattern":"^[A-Z]{2}$","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontProductDto"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayNowError"}}}}}}}}}
```

## Get product by ID or slug

> Retrieves a product by an ID or a slug. To make sure all VAT rates are properly displayed, pass in the IP headers as instructed.

```json
{"openapi":"3.1.1","info":{"title":"PayNow Storefront (Headless) API","version":"v1"},"tags":[{"name":"products"}],"security":[{},{"Customer":[],"APIKey":[]}],"components":{"securitySchemes":{"Customer":{"type":"apiKey","description":"A Customer token generated using an API Key in the format 'Customer TOKEN_HERE'.","name":"Authorization","in":"header"}},"schemas":{"StorefrontProductDto":{"required":["allow_one_time_purchase","allow_subscription","currency","custom_variables","description","gameservers","id","is_affiliate_links_disabled","is_coupons_disabled","is_gift_cards_disabled","is_gifting_disabled","name","price","remove_after_enabled","remove_after_time_scale","remove_after_time_value","single_game_server_only","slug","sort_order","store_id","subscription_interval_scale","subscription_interval_value","tags","trial","version_id"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"store_id":{"$ref":"#/components/schemas/FlakeId"},"version_id":{"$ref":"#/components/schemas/FlakeId"},"image_url":{"type":["null","string"],"description":"The URL to the product image."},"slug":{"type":"string","description":"The unique slug for the product."},"name":{"type":"string","description":"The display name of the product."},"description":{"type":"string","description":"The detailed description of the product."},"enabled_at":{"type":["null","string"],"description":"The date and time when the product becomes enabled.","format":"date-time"},"enabled_until":{"type":["null","string"],"description":"The date and time until which the product remains enabled.","format":"date-time"},"label":{"type":["null","string"],"description":"The display label for the product."},"sort_order":{"type":"integer","description":"The sort order for displaying the product.","format":"int32"},"price":{"type":"integer","description":"The price of the product, in the lowest denominator (e.g. cents).","format":"int64"},"currency":{"type":"string","description":"The ISO three-letter lowercase currency code (e.g., usd, eur, gbp) the product is denominated in."},"single_game_server_only":{"type":"boolean","description":"Indicates whether the product is limited to a single game server."},"allow_one_time_purchase":{"type":"boolean","description":"Indicates whether one-time purchases are allowed."},"allow_subscription":{"type":"boolean","description":"Indicates whether subscription purchases are allowed."},"is_gifting_disabled":{"type":"boolean","description":"Indicates whether gifting is disabled for this product."},"is_gift_cards_disabled":{"type":"boolean","description":"Indicates whether gift cards are disabled entirely for the product."},"is_coupons_disabled":{"type":"boolean","description":"Indicates whether coupons are disabled entirely for the product."},"is_affiliate_links_disabled":{"type":"boolean","description":"Indicates whether affiliate links are disabled entirely for the product."},"subscription_interval_value":{"type":"integer","description":"The subscription interval value.","format":"int32"},"subscription_interval_scale":{"$ref":"#/components/schemas/ProductSubscriptionIntervalScale"},"remove_after_enabled":{"type":"boolean","description":"Indicates whether automatic removal is enabled."},"remove_after_time_value":{"type":"integer","description":"The time value for automatic removal.","format":"int32"},"remove_after_time_scale":{"$ref":"#/components/schemas/ProductRemoveAfterIntervalScale"},"pricing":{"$ref":"#/components/schemas/StorefrontProductPricingDetailsDto"},"stock":{"$ref":"#/components/schemas/StorefrontProductStockStatusDto"},"trial":{"$ref":"#/components/schemas/StorefrontProductTrialDto"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/ProductTagDto"},"description":"The tags associated with the product."},"gameservers":{"type":"array","items":{"$ref":"#/components/schemas/ProductGameServerDto"},"description":"The game servers associated with the product."},"custom_variables":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontCustomVariableDto"},"description":"Custom Variables associated with the product."},"deliverable_actions":{"$ref":"#/components/schemas/ProductDeliverableActionsDto"},"metadata":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Additional metadata for the product."},"created_at":{"type":["null","string"],"description":"The date and time when the product was created.","format":"date-time"},"updated_at":{"type":["null","string"],"description":"The date and time when the product was last updated.","format":"date-time"},"tier_group_id":{"$ref":"#/components/schemas/FlakeId"},"active_tier_group":{"$ref":"#/components/schemas/CustomerTierGroupDto"}},"additionalProperties":false},"FlakeId":{"type":"string","additionalProperties":false,"format":"flake-id"},"ProductSubscriptionIntervalScale":{"enum":["invalid","day","week","month","year"],"type":"string"},"ProductRemoveAfterIntervalScale":{"enum":["invalid","day","week","month"],"type":"string"},"StorefrontProductPricingDetailsDto":{"required":["price_final","price_original","upsell_discount_amount"],"type":"object","properties":{"active_sale":{"$ref":"#/components/schemas/StorefrontSaleDto"},"sale_value":{"type":["null","integer"],"description":"The amount of the sale discount in the lowest denominator (e.g. cents).","format":"int64"},"upsell_offer_id":{"$ref":"#/components/schemas/FlakeId"},"upsell_discount_amount":{"type":"integer","format":"int64"},"vat_rate":{"$ref":"#/components/schemas/VatRateDto"},"regional_pricing":{"$ref":"#/components/schemas/StorefrontProductPricingDetailsRegionalPricingDto"},"price_original":{"type":"integer","description":"The original price of the product before any discounts, in the lowest denominator (e.g. cents).","format":"int64"},"price_final":{"type":"integer","description":"The final price of the product after all discounts, in the lowest denominator (e.g. cents).","format":"int64"}},"additionalProperties":false,"description":"The pricing details for the product in the storefront."},"StorefrontSaleDto":{"required":["begins_at","discount_amount","discount_type","id","minimum_order_value","name"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"name":{"type":"string","description":"The name of the sale."},"discount_type":{"$ref":"#/components/schemas/SaleDiscountType"},"discount_amount":{"type":"integer","description":"The amount of the discount, either as a percentage in permille or as an absolute value in cents.","format":"int64"},"minimum_order_value":{"type":"integer","description":"The minimum order value required to apply the discount, in the lowest denominator (e.g. cents).","format":"int64"},"begins_at":{"type":"string","description":"The date and time when the sale begins.","format":"date-time"},"ends_at":{"type":["null","string"],"description":"The date and time when the sale ends, if applicable.","format":"date-time"}},"additionalProperties":false},"SaleDiscountType":{"enum":["percent","amount"],"type":"string"},"VatRateDto":{"required":["country_code","country_name","currency","eservice_rate","eu_member_state","percentage","vat_abbreviation","vat_local_name"],"type":"object","properties":{"country_code":{"type":"string","description":"The ISO country code."},"country_name":{"type":"string","description":"The full name of the country."},"currency":{"type":"string","description":"The local currency used in the country."},"vat_abbreviation":{"type":"string","description":"The abbreviation of the VAT term in the local language."},"vat_local_name":{"type":"string","description":"The full name of the VAT term in the local language."},"eu_member_state":{"type":"boolean","description":"Indicates whether the country is a member of the European Union."},"eservice_rate":{"type":"number","description":"The VAT rate applicable for electronic services, as a percentage.","format":"double"},"percentage":{"type":"number","description":"The VAT rate (synonym for EServiceRate).","format":"double","readOnly":true}},"additionalProperties":false,"description":"The VAT rate estimation for the passed in customer country / IP.\nInclude the VAT percentage + abbreviation in your product view to inform your customers about the tax."},"StorefrontProductPricingDetailsRegionalPricingDto":{"required":["base_price","currency","region_id","tax_inclusive"],"type":"object","properties":{"region_id":{"type":"string","description":"The identifier for the region."},"currency":{"type":"string","description":"The currency code used in the region."},"tax_inclusive":{"type":"boolean","description":"Indicates whether the base price includes tax."},"base_price":{"type":"integer","description":"The base price in the regional currency, in the lowest denominator (e.g. cents).","format":"int64"}},"additionalProperties":false,"description":"Regional pricing information for this product.\nOnly present if there is a regional pricing configured."},"StorefrontProductStockStatusDto":{"required":["available_to_purchase","customer_available"],"type":"object","properties":{"available_to_purchase":{"type":"boolean","description":"Indicates whether the product is currently available for purchase (there is available stock)."},"customer_available":{"type":"integer","description":"The number of items available for the customer to purchase (customer stock limit remaining).","format":"int32"}},"additionalProperties":false,"description":"The stock status information for the product in the storefront."},"StorefrontProductTrialDto":{"required":["eligible","enabled","period_scale","period_value"],"type":"object","properties":{"enabled":{"type":"boolean","description":"Indicates whether the trial period is enabled for this product."},"eligible":{"type":"boolean","description":"Indicates whether the customer is eligible for the trial period."},"period_value":{"type":"integer","description":"The duration value of the trial period.","format":"int32"},"period_scale":{"$ref":"#/components/schemas/ProductSubscriptionIntervalScale"}},"additionalProperties":false},"ProductTagDto":{"required":["id","name","slug"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"slug":{"type":"string","description":"The unique slug for the tag."},"name":{"type":"string","description":"The display name of the tag."}},"additionalProperties":false},"ProductGameServerDto":{"required":["enabled","id","name"],"type":"object","properties":{"id":{"$ref":"#/components/schemas/FlakeId"},"name":{"type":"string","description":"The name of the game server."},"enabled":{"type":"boolean","description":"Indicates whether this game server is enabled."}},"additionalProperties":false},"StorefrontCustomVariableDto":{"required":["description","identifier","name","options","type"],"type":"object","properties":{"identifier":{"type":"string","description":"Unique identifier string used to reference this custom variable programmatically.\nMust contain only letters, numbers, underscores, and hyphens."},"name":{"type":"string","description":"Display name for the custom variable shown to customers."},"description":{"type":"string","description":"Description explaining what this custom variable is for. Can be shown to customers."},"type":{"$ref":"#/components/schemas/CustomVariableType"},"value_regex":{"type":["null","string"],"description":"Optional regex pattern to validate text/number input values.\nOnly applies to text and number types.\nUses RE2 syntax - does not support negative lookarounds, backreferences, or other advanced regex features."},"options":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontCustomVariableOptionDto"},"description":"Available options for dropdown type custom variables.\nEmpty for text and number types."}},"additionalProperties":false},"CustomVariableType":{"enum":["dropdown","text","number"],"type":"string","description":"Defines the type of input method for a custom variable."},"StorefrontCustomVariableOptionDto":{"required":["is_default","name","price","sort_order","value"],"type":"object","properties":{"name":{"type":"string","description":"Display name shown to customers for this option."},"value":{"type":"string","description":"Internal value used for product command variable replacement, without brackets."},"price":{"type":"integer","description":"Additional price in the lowest denominator (e.g. cents) when this option is selected.","format":"int64"},"is_default":{"type":"boolean","description":"Whether this option is selected by default when the custom variable is presented.\nOnly one option per custom variable should be marked as default."},"sort_order":{"type":"integer","description":"Sort order for displaying options to customers.\nLower numbers appear first.","format":"int32"}},"additionalProperties":false},"ProductDeliverableActionsDto":{"required":["grant_giftcard"],"type":"object","properties":{"grant_giftcard":{"type":"boolean","description":"Value indicating whether to grant a giftcard with the product with the subtotal amount."}},"additionalProperties":false},"CustomerTierGroupDto":{"required":["active_product_id","currency","next_billing_amount","next_billing_presentment_amount","next_renewal_at","presentment_currency","tier_group_id"],"type":"object","properties":{"tier_group_id":{"$ref":"#/components/schemas/FlakeId"},"active_product_id":{"$ref":"#/components/schemas/FlakeId"},"pending_change_product_id":{"$ref":"#/components/schemas/FlakeId"},"next_renewal_at":{"type":"string","description":"The date and time of the next subscription renewal for this tier group.","format":"date-time"},"next_billing_amount":{"type":"integer","description":"The next billing amount in the smallest currency unit (e.g., cents) in the settlement currency.","format":"int64"},"next_billing_presentment_amount":{"type":"integer","description":"The next billing amount in the smallest currency unit (e.g., cents) in the customer-facing presentment currency.","format":"int64"},"currency":{"type":"string","description":"The settlement currency code (e.g., \"usd\")."},"presentment_currency":{"type":"string","description":"The customer-facing presentment currency code (e.g., \"eur\")."}},"additionalProperties":false},"PayNowError":{"required":["code","message","status"],"type":"object","properties":{"status":{"type":"integer","description":"The HTTP status code.","format":"int32"},"code":{"type":"string","description":"The PayNow parseable error code."},"message":{"type":"string","description":"The human-readable error message."},"trace_id":{"type":["null","string"],"description":"A distributed trace ID used for debugging."},"errors":{"type":["null","array"],"items":{"$ref":"#/components/schemas/ValidationError"},"description":"An array of multiple errors. Only used by some API services."}},"additionalProperties":false,"description":"Represents a PayNow error"},"ValidationError":{"required":["code","message","path","validation"],"type":"object","properties":{"code":{"type":"string","description":"The parseable error code."},"message":{"type":"string","description":"The human-readable error message."},"path":{"type":"string","description":"The path leading to the validation error."},"validation":{"type":"string","description":"Type of the validation that failed."}},"additionalProperties":false,"description":"A validation error."}}},"paths":{"/v1/store/products/{idOrSlug}":{"get":{"tags":["products"],"summary":"Get product by ID or slug","description":"Retrieves a product by an ID or a slug. To make sure all VAT rates are properly displayed, pass in the IP headers as instructed.","operationId":"StorefrontProducts_GetStorefrontProductByIdOrSlug","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"}},{"name":"currency","in":"query","description":"The ISO three-letter lowercase currency code (e.g., usd, eur, gbp) to display prices in. If not provided, the store's default currency will be used.","schema":{"type":"string"}},{"name":"x-paynow-store-id","in":"header","description":"PayNow Store Identifier (Store ID) available in Store Settings","required":true,"schema":{"type":"string","format":"flake-id"}},{"name":"x-paynow-customer-ip","in":"header","description":"The IP address (IPv4 or IPv6) of the customer. Required if the request is not being made from the customer's browser.","schema":{"type":"string","format":"ipv4"}},{"name":"x-paynow-customer-countrycode","in":"header","description":"The customer's country code in ISO 3166-1 alpha-2 format. Optional, but recommended if you have this available.","schema":{"pattern":"^[A-Z]{2}$","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorefrontProductDto"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayNowError"}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.paynow.gg/storefront-headless/storefront-api/products.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
