# 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"}}}}}}}}}
```
