# null Source: https://docs.functionlab.app/advanced/conditions/README # Complex Conditions > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/conditions/array-matching # Array Matching > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/conditions/boolean-logic # Boolean Logic > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/conditions/relative # Relative Conditions > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/dynamic-values/README # Dynamic Values > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/dynamic-values/selector-pv # Selector PV > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/dynamic-values/value-buckets # Value Buckets > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/dynamic-values/value-case # Value Case > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/facts/README # Facts System > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/facts/examples # Facts Examples > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/facts/filters # Custom Filter Syntax > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/facts/jmespath # JMESPath Syntax > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/multi-rule-strategies # Multi-Rule Strategies > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/parameterized-events # Parameterized Events > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/advanced/performance # Performance Optimization > **Status**: To be written in Phase 4 # null Source: https://docs.functionlab.app/function-types/cart-transforms/examples # Cart Transforms - Examples > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/cart-transforms/merge # Cart Transforms - Merge Operations > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/cart-transforms/overview # Cart Transforms - Overview > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/cart-transforms/update # Cart Transforms - Update Operations > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/delivery-customization/examples # Delivery Customization - Examples > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/delivery-customization/hide # Delivery Customization - Hide Methods > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/delivery-customization/hide-others # Delivery Customization - Hide Others > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/delivery-customization/move # Delivery Customization - Move Methods > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/delivery-customization/overview # Delivery Customization - Overview > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/order-discounts/configuration # Order Discounts - Configuration > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/order-discounts/examples # Order Discounts - Examples > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/order-discounts/overview # Order Discounts - Overview > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/payment-customization/configuration # Payment Customization - Configuration > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/payment-customization/examples # Payment Customization - Examples > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/payment-customization/overview # Payment Customization - Overview > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/product-discounts/advanced # Product Discounts - Advanced Features > **Status**: Content planned, to be written in Phase 3 Advanced product discount features including dynamic values, quantity control, and complex pricing strategies. ## Topics Covered * `quantity` parameter for BOGO and quantity breaks * `appliesToEachItem` flag * `flatten_targets` for nested targeting * `selector_pv` for dynamic per-product values * `value_case` for conditional pricing * `value_buckets` for tiered pricing * Parameterized events for multi-product discounts ## Coming Soon Detailed documentation with examples for each advanced feature will be added in Phase 3 of documentation development. # null Source: https://docs.functionlab.app/function-types/product-discounts/basic-usage # Product Discounts - Basic Usage Learn the essential parameters and structure for product discount events. ## Event Structure ```json theme={null} { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 15, "message": "15% Off Sale" } } ``` ## Required Parameters ### discount\_type Specifies the type of discount to apply. **Options:** * `"percentage"`: Percentage discount * `"fixed_amount"`: Fixed dollar amount off **Example:** ```json theme={null} { "discount_type": "percentage" } ``` ### value The discount amount (numeric). **For percentage:** * Use whole numbers: `15` = 15%, `20` = 20% * Not decimals: ~~`0.15`~~ ❌ **For fixed\_amount:** * Dollar amount: `10` = \$10 off * Per item by default (see `appliesToEachItem`) **Examples:** ```json theme={null} // 25% off { "discount_type": "percentage", "value": 25 } // $5 off per item { "discount_type": "fixed_amount", "value": 5 } ``` ## Optional Parameters ### message Customer-facing text displayed with the discount. ```json theme={null} { "message": "VIP Member Discount" } ``` **Best Practices:** * Keep it short and clear * Explain why they got the discount * Avoid technical jargon * Examples: "10% Off Sale Items", "VIP Discount", "Bulk Order Savings" ### handles Target specific products by their handle. ```json theme={null} { "handles": ["cool-t-shirt", "awesome-jeans"] } ``` **Notes:** * Handles are URL-friendly product identifiers * Find in Shopify admin or product URL * Case-sensitive * Multiple handles = OR logic (any matching product) ### variant\_ids Target specific variants by ID. ```json theme={null} { "variant_ids": [12345678, 87654321] } ``` **Notes:** * Numeric IDs or GIDs both accepted * Most specific targeting method * Find in Shopify admin under product variants ### vendors Target all products from specific vendors. ```json theme={null} { "vendors": ["Nike", "Adidas"] } ``` **Notes:** * Exact match (case-sensitive) * Multiple vendors = OR logic * Vendor name must match exactly as stored in Shopify ### variant\_titles Target variants by their option values. ```json theme={null} { "variant_titles": ["Large", "X-Large"] } ``` **Notes:** * Matches against variant option combinations * Case-sensitive * Useful for size/color-based discounts ## Discount Types in Detail ### Percentage Discount Reduces price by a percentage. ```json theme={null} { "discount_type": "percentage", "value": 20, "message": "20% Off" } ``` **Calculation:** * Original Price: \$100 * Discount: 20% * Final Price: \$80 **Best for:** * Sales (20% off everything) * Customer segments (VIP gets 15% off) * Promotional events ### Fixed Amount Discount Reduces price by a fixed dollar amount. ```json theme={null} { "discount_type": "fixed_amount", "value": 10, "message": "$10 Off" } ``` **Default behavior (per item):** * Original Price: \$50 per item * Quantity: 2 * Discount: \$10 per item * Total Discount: \$20 * Final Total: \$80 **Best for:** * Bulk discounts (\$5 off each) * Clearance pricing * Fixed savings promotions ## Complete Examples ### Simple Percentage Discount 10% off all products: ```json theme={null} { "rules": [ { "conditions": {}, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 10, "message": "10% Off Sitewide" } } ] } ] } ``` ### Targeted Product Discount \$15 off specific product: ```json theme={null} { "rules": [ { "conditions": {}, "events": [ { "discount": "product_discount", "params": { "handles": ["premium-sneakers"], "discount_type": "fixed_amount", "value": 15, "message": "$15 Off Premium Sneakers" } } ] } ] } ``` ### Conditional Vendor Discount 20% off Nike products for VIP customers: ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "VIP" } }, "events": [ { "discount": "product_discount", "params": { "vendors": ["Nike"], "discount_type": "percentage", "value": 20, "message": "VIP Special - 20% Off Nike" } } ] } ] } ``` ### Multiple Product Discount 15% off specific products: ```json theme={null} { "rules": [ { "conditions": {}, "events": [ { "discount": "product_discount", "params": { "handles": ["t-shirt", "hoodie", "jacket"], "discount_type": "percentage", "value": 15, "message": "15% Off Apparel" } } ] } ] } ``` ## Common Patterns ### No Targeting = All Products Omit targeting parameters to apply to entire cart: ```json theme={null} { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 10, "message": "10% Off Everything" } } ``` ### Multiple Targeting Methods Combine targeting (OR logic): ```json theme={null} { "params": { "handles": ["t-shirt"], "vendors": ["Nike"], "discount_type": "percentage", "value": 20 } } ``` Applies to: products with handle "t-shirt" OR from vendor "Nike". ## Next Steps * [Targeting Strategies](targeting.md) - Advanced product selection with selectors * [Advanced Features](advanced.md) - Dynamic pricing, quantity breaks, value\_case * [Examples](examples.md) - More real-world configurations # null Source: https://docs.functionlab.app/function-types/product-discounts/examples # Product Discounts - Examples > **Status**: Content planned, to be written in Phase 3 Real-world product discount configurations. ## Examples to be Added * Percentage discount * Fixed amount discount * Per-item discount * Volume pricing * B2B wholesale pricing * New customer discount * Product metafield pricing * Vendor-specific discount * Collection discount * Tag-based discount * Conditional tiered pricing ## Coming Soon Complete examples with full JSON configurations will be added in Phase 3. # null Source: https://docs.functionlab.app/function-types/product-discounts/overview # Product Discounts - Overview Apply percentage or fixed amount discounts to specific products in the cart. ## What are Product Discounts? Product discounts modify the price of individual line items in a cart. They can target specific products, variants, collections, or use complex selectors to choose which items receive the discount. ## Use Cases * Percentage discounts (15% off) * Fixed amount discounts (\$10 off per item) * BOGO (Buy One Get One) offers * Volume/quantity-based pricing * Customer segment pricing * Collection or tag-based sales * Vendor-specific discounts * Dynamic pricing based on metafields * Tiered pricing structures ## Key Features ### Multiple Targeting Strategies * **Direct**: Target by variant IDs or product handles * **Attribute-Based**: Target by vendor, title, tags * **Selector-Based**: Use JMESPath/filters to target by any attribute * **Collection-Based**: Target all items in a collection ### Discount Types * **Percentage**: `discount_type: "percentage"`, value: 15 (for 15%) * **Fixed Amount**: `discount_type: "fixed_amount"`, value: 10 (for \$10 off) ### Advanced Capabilities * **Dynamic Values**: Use `value_case`, `value_buckets`, `selector_pv` for conditional pricing * **Quantity Control**: Apply discount to specific quantities with `quantity` parameter * **Message Customization**: Show customer-facing messages * **Per-Item vs Total**: Control with `appliesToEachItem` flag ## Basic Example ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "VIP" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 15, "message": "VIP Discount - 15% Off" } } ] } ] } ``` ## When to Use Product Discounts Use product discounts when you need to: * Apply discounts to specific items (not the entire cart) * Show per-item discount amounts * Target products by complex criteria * Implement BOGO or quantity break pricing * Apply different discounts to different products in the same cart ## Limitations * Cannot discount below \$0 * Some discount combinations may conflict (use `discountApplicationStrategy`) * Shopify may limit stacking with manual discount codes (depends on store settings) * Performance considerations for very large carts with complex selectors ## Next Steps * [Basic Usage](basic-usage.md) - Learn the core parameters * [Targeting Strategies](targeting.md) - Master product selection * [Advanced Features](advanced.md) - Dynamic pricing and complex scenarios * [Examples](examples.md) - Real-world configurations # null Source: https://docs.functionlab.app/function-types/product-discounts/targeting # Product Discounts - Targeting Strategies Advanced techniques for selecting which products receive discounts. ## Targeting Overview Product discounts support multiple targeting strategies: 1. **Direct Targeting**: IDs, handles, vendors (simple, fast) 2. **Selector-Based**: JMESPath/filters (flexible, powerful) 3. **Combination**: Mix multiple strategies ## Direct Targeting Methods ### By Product Handle Target specific products by URL-friendly handle: ```json theme={null} { "handles": ["cool-t-shirt", "awesome-jeans"] } ``` **When to use:** * Known product handles * Small, specific product sets * Performance-critical scenarios ### By Variant ID Most specific targeting method: ```json theme={null} { "variant_ids": [12345678, 87654321] } ``` **When to use:** * Specific sizes/colors * Exact variant targeting * Integration with external systems ### By Vendor All products from specific brands: ```json theme={null} { "vendors": ["Nike", "Adidas", "Puma"] } ``` **When to use:** * Brand-specific sales * Vendor agreements * Multi-brand discounts ### By Variant Title Target by size, color, or other options: ```json theme={null} { "variant_titles": ["Large", "X-Large", "XX-Large"] } ``` **When to use:** * Size-specific discounts * Color-based pricing * Option-based sales ## Selector-Based Targeting Use `selector` parameter with JMESPath or filter syntax for complex queries. ### Basic Selector ```json theme={null} { "selector": "cart.lines[?merchandise.product.handle=='t-shirt'].id" } ``` Returns array of line IDs where product handle is 't-shirt'. ### Collection-Based Selection Target all items in a collection: ```json theme={null} { "facts": { "sale_items": "cart.lines[?merchandise.product.collections[?handle=='sale']].id" }, "events": [ { "discount": "product_discount", "params": { "selector": "$sale_items", "discount_type": "percentage", "value": 25 } } ] } ``` **How it works:** 1. Query finds lines where product is in 'sale' collection 2. Extracts line IDs 3. Applies discount to those lines ### Tag-Based Selection Target products with specific tags: ```json theme={null} { "facts": { "clearance_items": "cart.lines[?merchandise.product.tags[?@ == 'clearance']].id" }, "events": [ { "discount": "product_discount", "params": { "selector": "$clearance_items", "discount_type": "percentage", "value": 50 } } ] } ``` ### Price Range Selection Target products in specific price range: ```json theme={null} { "facts": { "premium_items": "cart.lines[?merchandise.priceV2.amount >= `100`].id" }, "events": [ { "discount": "product_discount", "params": { "selector": "$premium_items", "discount_type": "fixed_amount", "value": 20, "message": "$20 Off Premium Items" } } ] } ``` ### Multiple Criteria Selection Combine multiple conditions: ```json theme={null} { "facts": { "targeted_items": "cart.lines[?merchandise.product.vendor=='Nike' && merchandise.product.collections[?handle=='sale']].id" }, "events": [ { "discount": "product_discount", "params": { "selector": "$targeted_items", "discount_type": "percentage", "value": 30 } } ] } ``` Targets: Nike products that are also in the sale collection. ## Selector Syntax Reference ### JMESPath Filtering ```json theme={null} "cart.lines[?{condition}].id" ``` **Common conditions:** * `merchandise.product.handle == 'value'`: Exact match * `merchandise.product.vendor == 'Nike'`: Vendor match * `merchandise.priceV2.amount >= `100\`\`: Price comparison * `merchandise.product.tags[?@ == 'sale']`: Array contains * `merchandise.product.collections[?handle=='sale']`: Nested array query ### Custom Filter Syntax Alternative to JMESPath: ```json theme={null} "cart.lines | select(merchandise.product.handle == 'shirt') | map(id)" ``` **Filters:** * `select()`: Filter items * `map()`: Extract property * `sum()`: Aggregate values ## Targeting Decision Guide ``` Need to target... ├─ Specific known products? │ └─ Use: handles or variant_ids ├─ All from a brand? │ └─ Use: vendors ├─ Products in a collection? │ └─ Use: selector with collection query ├─ Products with specific tags? │ └─ Use: selector with tag query ├─ Products by price range? │ └─ Use: selector with price filter └─ Complex multi-criteria? └─ Use: selector with combined conditions ``` ## Performance Considerations ### Fastest (use when possible) 1. `variant_ids`: Direct ID lookup 2. `handles`: Simple string match 3. `vendors`: Indexed field lookup ### Moderate 4. `selector` with simple conditions: Single field filter ### Slower (use when necessary) 5. `selector` with nested queries: Collection/tag traversal 6. `selector` with multiple conditions: Complex logic **Optimization tips:** * Cache selector results in facts * Use direct targeting when product set is known * Test with realistic cart sizes ## Advanced Patterns ### Exclude Products Target all except specific products: ```json theme={null} { "facts": { "discountable_items": "cart.lines[?merchandise.product.handle != 'gift-card'].id" }, "events": [ { "discount": "product_discount", "params": { "selector": "$discountable_items", "discount_type": "percentage", "value": 10 } } ] } ``` ### Metafield-Based Targeting Target using custom metafields: ```json theme={null} { "facts": { "b2b_items": "cart.lines[?merchandise.product.metafields[?namespace=='custom' && key=='b2b_eligible'].value == 'true'].id" }, "events": [ { "discount": "product_discount", "params": { "selector": "$b2b_items", "discount_type": "percentage", "value": 25, "message": "B2B Wholesale Pricing" } } ] } ``` ### Conditional Targeting Different products based on customer: ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "VIP" } }, "facts": { "vip_items": "cart.lines[?merchandise.product.vendor == 'Premium Brand'].id" }, "events": [ { "discount": "product_discount", "params": { "selector": "$vip_items", "discount_type": "percentage", "value": 30 } } ] } ] } ``` ## Next Steps * [Advanced Features](advanced.md) - Dynamic values, quantity breaks, value\_case * [Examples](examples.md) - Complete real-world configurations * [Facts System](../../advanced/facts/README.md) - Deep dive into selectors # null Source: https://docs.functionlab.app/function-types/shipping-discounts/advanced # Shipping Discounts - Advanced Features > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/shipping-discounts/basic-usage # Shipping Discounts - Basic Usage > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/shipping-discounts/examples # Shipping Discounts - Examples > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/function-types/shipping-discounts/overview # Shipping Discounts - Overview > **Status**: Content planned, to be written in Phase 3 Apply discounts to shipping costs. ## Coming Soon Documentation for shipping discounts including free shipping, percentage discounts, fixed amount discounts, and method-specific targeting. # null Source: https://docs.functionlab.app/function-types/shipping-discounts/targeting # Shipping Discounts - Targeting > **Status**: To be written in Phase 3 # null Source: https://docs.functionlab.app/getting-started/common-patterns # Common Patterns Ready-to-use examples for frequent discount scenarios. ## Customer Segmentation ### VIP Customer Discount 10% off for customers with VIP tag: ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "VIP" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 10, "message": "VIP Customer - 10% Off" } } ] } ] } ``` ### First-Time Customer Discount 15% off for new customers: ```json theme={null} { "rules": [ { "conditions": { "customer.ordersCount": { "eq": 0 } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 15, "message": "Welcome! First Order 15% Off" } } ] } ] } ``` ### Returning Customer Offer \$20 off for customers with 3+ previous orders: ```json theme={null} { "rules": [ { "conditions": { "customer.ordersCount": { "gte": 3 } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "fixed_amount", "value": 20, "message": "Thank You - $20 Off" } } ] } ] } ``` ## Product Targeting ### Specific Product Discount 20% off a specific product by handle: ```json theme={null} { "rules": [ { "conditions": {}, "events": [ { "discount": "product_discount", "params": { "handles": ["cool-t-shirt"], "discount_type": "percentage", "value": 20, "message": "20% Off Cool T-Shirt" } } ] } ] } ``` ### Collection Discount 25% off all items in "Sale" collection: ```json theme={null} { "rules": [ { "facts": { "sale_items": "cart.lines[?merchandise.product.collections[?handle=='sale']].id" }, "conditions": { "$sale_items": { "empty": false } }, "events": [ { "discount": "product_discount", "params": { "selector": "$sale_items", "discount_type": "percentage", "value": 25, "message": "25% Off Sale Items" } } ] } ] } ``` ### Vendor Discount 15% off all products from specific vendor: ```json theme={null} { "rules": [ { "conditions": {}, "events": [ { "discount": "product_discount", "params": { "vendors": ["Awesome Brand"], "discount_type": "percentage", "value": 15, "message": "15% Off Awesome Brand" } } ] } ] } ``` ## Quantity-Based Discounts ### Bulk Discount 10% off when buying 5+ items: ```json theme={null} { "rules": [ { "facts": { "total_quantity": "cart.lines[].quantity | sum(@)" }, "conditions": { "$total_quantity": { "gte": 5 } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 10, "message": "Bulk Order - 10% Off" } } ] } ] } ``` ### Buy One Get One (BOGO) Buy 2, get 50% off the second item: ```json theme={null} { "rules": [ { "conditions": {}, "events": [ { "discount": "product_discount", "params": { "handles": ["t-shirt"], "quantity": 1, "discount_type": "percentage", "value": 50, "message": "BOGO 50% Off" } } ] } ] } ``` ## Cart Value Discounts ### Minimum Order Discount $10 off orders over $100: ```json theme={null} { "rules": [ { "conditions": { "cart.cost.subtotalAmount.amount": { "gte": "100" } }, "events": [ { "discount": "order_discount", "params": { "discount_type": "fixed_amount", "value": 10, "message": "$10 Off Orders Over $100" } } ] } ] } ``` ### Tiered Cart Discounts Increasing discount based on cart value: ```json theme={null} { "rules": [ { "conditions": { "cart.cost.subtotalAmount.amount": { "gte": "200" } }, "events": [ { "discount": "order_discount", "params": { "discount_type": "percentage", "value": 20, "message": "20% Off - Orders $200+" } } ] }, { "conditions": { "cart.cost.subtotalAmount.amount": { "gte": "100" }, "cart.cost.subtotalAmount.amount": { "lt": "200" } }, "events": [ { "discount": "order_discount", "params": { "discount_type": "percentage", "value": 10, "message": "10% Off - Orders $100+" } } ] } ], "discountApplicationStrategy": "FIRST" } ``` ## Shipping Discounts ### Free Shipping Threshold Free shipping on orders over \$50: ```json theme={null} { "rules": [ { "conditions": { "cart.cost.subtotalAmount.amount": { "gte": "50" } }, "events": [ { "discount": "shipping_discount", "params": { "discount_type": "percentage", "value": 100, "message": "Free Shipping" } } ] } ] } ``` ### VIP Free Shipping Free shipping for VIP customers: ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "VIP" } }, "events": [ { "discount": "shipping_discount", "params": { "discount_type": "percentage", "value": 100, "message": "VIP Free Shipping" } } ] } ] } ``` ### Collection-Based Free Shipping Free shipping when cart includes sale items: ```json theme={null} { "rules": [ { "facts": { "has_sale_items": "cart.lines[?merchandise.product.collections[?handle=='sale']] | length(@) > `0`" }, "conditions": { "$has_sale_items": { "eq": true } }, "events": [ { "discount": "shipping_discount", "params": { "discount_type": "percentage", "value": 100, "message": "Free Shipping on Sale Items" } } ] } ] } ``` ## Combined Conditions ### VIP + Minimum Order 20% off for VIP customers spending \$100+: ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "VIP" }, "cart.cost.subtotalAmount.amount": { "gte": "100" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 20, "message": "VIP Special - 20% Off" } } ] } ] } ``` ### Multi-Tier Customer Segments Different discounts for different customer tiers: ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "GOLD" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 20, "message": "Gold Member - 20% Off" } } ] }, { "conditions": { "customer.tags": { "includes": "SILVER" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 15, "message": "Silver Member - 15% Off" } } ] }, { "conditions": { "customer.tags": { "includes": "BRONZE" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 10, "message": "Bronze Member - 10% Off" } } ] } ], "discountApplicationStrategy": "FIRST" } ``` ## Next Steps * [Product Discounts](../function-types/product-discounts/overview.md) - Deep dive into product discount features * [Cookbook](../reference/cookbook/README.md) - 30+ advanced recipes * [Advanced Features](../advanced/facts/README.md) - Complex conditions and dynamic values # null Source: https://docs.functionlab.app/getting-started/core-concepts # Core Concepts Understanding the fundamental building blocks of Function Lab. ## Overview Function Lab configurations consist of **rules** that evaluate **conditions** and execute **events**. Optional **facts** enable complex data transformations. ``` Input Data → Facts → Conditions → Events → Output ``` ## Rules A rule is the basic unit of logic in Function Lab. ### Structure ```json theme={null} { "rules": [ { "facts": { /* optional data transformations */ }, "conditions": { /* when to apply this rule */ }, "events": [ /* what to do when conditions match */ ] } ] } ``` ### Required Fields * `conditions`: Object defining when the rule applies * `events`: Array of actions to take when conditions are met ### Optional Fields * `facts`: Named calculations for reuse in conditions and events * `if-not-events`: Alternative events when conditions don't match ## Conditions Conditions determine when a rule should fire. They query the input data using dot notation and predicates. ### Simple Condition ```json theme={null} { "conditions": { "customer.tags": { "includes": "VIP" } } } ``` Checks if customer tags array includes "VIP". ### Multiple Conditions (AND) ```json theme={null} { "conditions": { "customer.tags": { "includes": "VIP" }, "cart.totalAmount": { "gte": 100 } } } ``` Both conditions must be true (implicit AND). ### OR Logic ```json theme={null} { "conditions": { "or": [ { "customer.tags": { "includes": "VIP" } }, { "customer.tags": { "includes": "WHOLESALE" } } ] } } ``` ### Available Predicates | Predicate | Description | Example | | ---------------------- | --------------------- | ------------------------------------------------ | | `equal`, `eq`, `is` | Exact match | `"customer.email": { "is": "user@example.com" }` | | `includes`, `contains` | Array contains value | `"customer.tags": { "includes": "VIP" }` | | `gt`, `greater` | Greater than | `"cart.totalAmount": { "gt": 100 }` | | `gte`, `greaterEq` | Greater than or equal | `"cart.totalAmount": { "gte": 100 }` | | `lt`, `less` | Less than | `"cart.lineCount": { "lt": 5 }` | | `lte`, `lessEq` | Less than or equal | `"cart.lineCount": { "lte": 10 }` | | `exists` | Field exists | `"customer.id": { "exists": true }` | | `empty` | Array/string is empty | `"customer.tags": { "empty": false }` | See [Predicates Reference](../reference/api/predicates.md) for complete list. ## Events Events define what happens when conditions match. Event structure depends on the function type. ### Product Discount Event ```json theme={null} { "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 15, "message": "15% Off Sale" } } ] } ``` ### Multiple Events A rule can have multiple events: ```json theme={null} { "events": [ { "discount": "product_discount", "params": { "handles": ["t-shirt"], "discount_type": "percentage", "value": 20, "message": "20% off T-Shirts" } }, { "discount": "product_discount", "params": { "handles": ["jeans"], "discount_type": "percentage", "value": 15, "message": "15% off Jeans" } } ] } ``` ## Facts Facts are named calculations that transform input data for reuse in conditions and events. ### Basic Fact ```json theme={null} { "facts": { "total_quantity": "cart.lines[].quantity | sum(@)" }, "conditions": { "$total_quantity": { "gte": 10 } } } ``` The `$` prefix references a fact in conditions. ### Why Use Facts? * **Reusability**: Calculate once, use everywhere * **Readability**: Name complex expressions * **Performance**: Avoid redundant calculations * **Power**: Use JMESPath or custom filters for complex queries ### Example: Collection Filtering ```json theme={null} { "facts": { "sale_items": "cart.lines[?merchandise.product.collections[?handle=='sale']].id" }, "conditions": { "$sale_items": { "empty": false } }, "events": [ { "discount": "product_discount", "params": { "selector": "$sale_items", "discount_type": "percentage", "value": 25, "message": "25% off Sale Items" } } ] } ``` See [Facts System](../advanced/facts/README.md) for deep dive. ## Input Data Structure Function Lab receives cart and customer data from Shopify in a standardized format: ```json theme={null} { "cart": { "lines": [ { "id": "gid://shopify/CartLine/...", "quantity": 2, "merchandise": { "id": "gid://shopify/ProductVariant/...", "title": "Size M", "product": { "id": "gid://shopify/Product/...", "title": "Cool T-Shirt", "handle": "cool-t-shirt", "vendor": "Awesome Brand", "collections": [...] } } } ], "totalAmount": 100.00, "buyerIdentity": { "customer": { "id": "gid://shopify/Customer/...", "email": "customer@example.com", "tags": ["VIP", "WHOLESALE"] } } } } ``` See [Input Structure Reference](../reference/api/input.md) for complete schema. ## Path Notation Access nested data using dot notation: | Path | Accesses | | ----------------------------------------- | ----------------------------- | | `customer.email` | Customer's email address | | `customer.tags` | Array of customer tags | | `cart.lines` | Array of cart line items | | `cart.lines[].merchandise.product.handle` | Product handles for all lines | ### Array Access Arrays are automatically traversed: ```json theme={null} { "customer.tags": { "includes": "VIP" } } ``` Checks if **any** tag equals "VIP" (automatic ANY semantics). ## Execution Flow 1. **Input Received**: Shopify sends cart/checkout data 2. **Facts Computed**: Named calculations evaluated once 3. **Conditions Evaluated**: Check if rule should fire 4. **Events Executed**: Generate discounts/operations 5. **Output Returned**: Results sent back to Shopify ## Next Steps * [How It Works](how-it-works.md) - Detailed execution model * [Testing](testing.md) - Test and debug your functions * [Common Patterns](common-patterns.md) - Real-world examples * [Function Types](../function-types/product-discounts/overview.md) - Explore specific function types # null Source: https://docs.functionlab.app/getting-started/how-it-works # How It Works Understanding the execution model and data flow in Function Lab. ## Architecture Overview ``` ┌─────────────────┐ │ Shopify Cart │ │ / Checkout │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Shopify │ │ Functions API │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Function Lab │ │ Rules Engine │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Your Rules │ │ Configuration │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Discounts or │ │ Customizations │ └─────────────────┘ ``` ## Execution Phases ### 1. Input Processing When a customer interacts with their cart or checkout, Shopify calls your Function Lab configuration with cart data: **Input Structure:** ```json theme={null} { "cart": { "lines": [...], "buyerIdentity": { "customer": {...} }, "deliveryGroups": [...] } } ``` This input is parsed and made available for querying via conditions and facts. ### 2. Facts Computation If your rules define facts, they're evaluated first: ```json theme={null} { "facts": { "total_items": "cart.lines[].quantity | sum(@)", "has_sale_items": "cart.lines[?merchandise.product.collections[?handle=='sale']] | length(@) > `0`" } } ``` **Facts are:** * Computed once per rule execution * Available to all conditions and events * Cached for performance * Referenced with `$` prefix: `$total_items` ### 3. Condition Evaluation For each rule, conditions are evaluated against the input data and computed facts: ```json theme={null} { "conditions": { "$total_items": { "gte": 5 }, "customer.tags": { "includes": "VIP" } } } ``` **Evaluation Logic:** * Multiple conditions = implicit AND (all must be true) * Array properties use ANY semantics (any element can match) * `or` operator for alternative conditions * `not` operator for negation * Short-circuit evaluation for performance **Result:** `true` (fire events) or `false` (skip events) ### 4. Event Execution When conditions match, events are executed to generate outputs: ```json theme={null} { "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 15, "message": "VIP Bulk Discount" } } ] } ``` **Event Processing:** * Each event generates one or more discount/operation objects * Multiple events in a rule = multiple outputs * Parameterized events expand to multiple outputs * Events can reference facts for dynamic values ### 5. Output Assembly All outputs from matching rules are collected and returned to Shopify: **For Discounts:** ```json theme={null} { "discounts": [ { "targets": [...], "value": { "percentage": { "value": "15" } }, "message": "VIP Bulk Discount" } ], "discountApplicationStrategy": "FIRST" } ``` **For Customizations:** ```json theme={null} { "operations": [ { "hide": { "deliveryOptionHandle": "expedited-shipping" } } ] } ``` ## Rule Execution Order Multiple rules are evaluated in order: ```json theme={null} { "rules": [ { /* Rule 1 - evaluated first */ }, { /* Rule 2 - evaluated second */ }, { /* Rule 3 - evaluated third */ } ] } ``` **Important:** * All rules are evaluated independently * Facts are isolated per rule * Results from all matching rules are combined * Use `discountApplicationStrategy` to control how discounts stack ## Discount Application Strategies Control how multiple discounts combine: ### FIRST (Default for most scenarios) ```json theme={null} { "discountApplicationStrategy": "FIRST" } ``` Only the first matching discount is applied. Use when discounts shouldn't stack. ### MAXIMUM ```json theme={null} { "discountApplicationStrategy": "MAXIMUM" } ``` Apply the largest discount found. Good for "best deal" scenarios. ### ALL ```json theme={null} { "discountApplicationStrategy": "ALL" } ``` All matching discounts are applied (if Shopify allows stacking for the function type). ## Performance Considerations ### Efficient Condition Ordering Place simple conditions first: ```json theme={null} { "conditions": { "customer.tags": { "includes": "VIP" }, // Fast: simple lookup "$complex_calculation": { "gte": 100 } // Slower: fact computation } } ``` ### Fact Reuse Calculate once, use everywhere: ❌ **Inefficient:** ```json theme={null} { "rules": [ { "conditions": { "cart.lines[?merchandise.product.vendor=='Acme'].quantity | sum(@)": { "gte": 5 } } } ] } ``` ✅ **Efficient:** ```json theme={null} { "rules": [ { "facts": { "acme_quantity": "cart.lines[?merchandise.product.vendor=='Acme'].quantity | sum(@)" }, "conditions": { "$acme_quantity": { "gte": 5 } } } ] } ``` ### Selector Optimization Use direct targeting when possible: ❌ **Slower:** ```json theme={null} { "selector": "cart.lines[?merchandise.product.handle=='t-shirt'].id" } ``` ✅ **Faster:** ```json theme={null} { "handles": ["t-shirt"] } ``` ## Shopify Integration ### Function Types Function Lab supports all Shopify Function types: * **Product Discounts**: Line item price adjustments * **Order Discounts**: Cart-level discounts * **Shipping Discounts**: Delivery cost adjustments * **Delivery Customization**: Show/hide/reorder shipping methods * **Payment Customization**: Control payment method availability * **Cart Transform**: Merge/update line items Each has specific input/output schemas - see [Function Types](../function-types/product-discounts/overview.md). ### Metafield Access Access custom data via metafields: ```json theme={null} { "conditions": { "customer.metafields[?namespace=='custom' && key=='tier'].value": { "is": "gold" } } } ``` ### GID Handling Shopify IDs are Global IDs (GIDs): ``` gid://shopify/ProductVariant/12345678 ``` Function Lab handles conversion automatically: * Accept numeric IDs: `"variant_ids": [12345678]` * Auto-converts to GIDs internally * Returns proper GID format to Shopify ## Error Handling ### Invalid Configuration * Rules with syntax errors are skipped * Logs show validation errors * Other rules continue executing ### Runtime Errors * Fact computation errors return `null` * Selector errors skip that event * Functions fail safely (no discount rather than cart breakage) ### Testing Always test in Shopify admin preview mode before activating. ## Next Steps * [Testing Guide](testing.md) - Debug and validate your rules * [Advanced Features](../advanced/facts/README.md) - Complex conditions and dynamic values * [Performance Optimization](../advanced/performance.md) - Optimize for speed # null Source: https://docs.functionlab.app/getting-started/quick-start # Quick Start Build your first Function Lab discount in under 5 minutes. ## Prerequisites * Shopify Plus store * Function Lab app installed * Admin access to your Shopify store ## Your First Discount Function We'll create a simple 10% discount for VIP customers. ### Step 1: Access Function Lab 1. Log into your Shopify admin 2. Navigate to Apps → Function Lab 3. Click "Create New Function" 4. Select "Product Discount" ### Step 2: Configure Your Rule ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "VIP" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 10, "message": "VIP Customer Discount" } } ] } ] } ``` ### Step 3: Test Your Function 1. Click "Preview" in the Function Lab interface 2. Enter a test cart with a customer tagged "VIP" 3. Verify the 10% discount appears ### Step 4: Activate 1. Give your function a name: "VIP Customer Discount" 2. Click "Save and Activate" 3. Your function is now live! ## What Just Happened? You created a **rule** with: * **Condition**: Checks if customer has "VIP" tag * **Event**: Applies 10% discount when condition is true * **Message**: Shows "VIP Customer Discount" to customer ## Next Steps * [Core Concepts](core-concepts.md) - Understand rules, conditions, events, and facts * [Common Patterns](common-patterns.md) - Explore more discount scenarios * [Product Discounts](../function-types/product-discounts/overview.md) - Deep dive into product discount features ## Common First Issues **Discount not appearing?** * Verify customer has "VIP" tag (case-sensitive) * Check function is activated in Shopify admin * Ensure no conflicting discounts exist **Wrong discount amount?** * Percentage discounts use whole numbers (10 = 10%, not 0.10) * Check `discount_type` is set to "percentage" # null Source: https://docs.functionlab.app/getting-started/testing # Testing Your Functions Learn how to test and debug Function Lab configurations. ## Preview Mode Function Lab provides a built-in preview mode in the Shopify admin. ### Accessing Preview 1. Navigate to Apps → Function Lab 2. Select your function 3. Click "Preview" or "Test" 4. Enter test cart data ### Test Scenarios Create test scenarios with different: * Customer tags * Cart contents * Product variants * Order totals * Geographic locations ## Common Testing Patterns ### Test Customer Segments ```json theme={null} // Test VIP customer { "customer": { "tags": ["VIP"] } } // Test first-time customer { "customer": { "tags": [], "ordersCount": 0 } } ``` ### Test Cart Conditions ```json theme={null} // Test minimum order value { "cart": { "totalAmount": 150.00 } } // Test quantity thresholds { "cart": { "lines": [ { "quantity": 5, "merchandise": {...} } ] } } ``` ## Debugging Strategies ### Enable Console Logging Add console output to track execution: ```json theme={null} { "facts": { "debug_total": "cart.totalAmount" }, "conditions": { "$debug_total": { "gte": 100 } } } ``` ### Test Conditions in Isolation Simplify rules to test one condition at a time: ```json theme={null} // Test just the customer condition { "conditions": { "customer.tags": { "includes": "VIP" } } } ``` ### Verify Selector Output Test selectors separately: ```json theme={null} { "facts": { "selected_items": "cart.lines[?merchandise.product.handle=='t-shirt'].id" } } ``` ## Validation Checklist Before activating a function: * [ ] JSON syntax is valid * [ ] All required fields are present * [ ] Predicates are spelled correctly * [ ] Paths reference valid fields * [ ] GIDs are properly formatted * [ ] Discount values are in correct format * [ ] Messages are customer-friendly * [ ] Tested with multiple cart scenarios * [ ] Verified in Shopify preview mode ## Common Issues ### "No discount applied" **Possible causes:** 1. Conditions not met 2. Wrong path in condition 3. Case-sensitive string comparison 4. Empty selector result **Debug steps:** * Check input data matches condition * Verify field paths exist * Test with simplified conditions * Add facts to inspect intermediate values ### "Wrong discount amount" **Possible causes:** 1. `discount_type` mismatch (percentage vs fixed) 2. Value format incorrect 3. `appliesToEachItem` confusion **Debug steps:** * Verify `discount_type` is correct * Check value is numeric * Test with round numbers first ### "Discount on wrong products" **Possible causes:** 1. Selector returns unexpected results 2. Handle doesn't match 3. GID format issue **Debug steps:** * Test selector in facts * Verify product handles * Check variant IDs ## Testing Best Practices ### Start Simple Begin with minimal configuration: ```json theme={null} { "rules": [ { "conditions": { "customer.tags": { "includes": "TEST" } }, "events": [ { "discount": "product_discount", "params": { "discount_type": "percentage", "value": 10, "message": "Test Discount" } } ] } ] } ``` ### Add Complexity Gradually Once basic rule works, add: 1. Additional conditions 2. Facts 3. Complex selectors 4. Multiple events ### Test Edge Cases * Empty cart * Single item * Large quantity * Zero-price items * Customer without account ### Document Test Cases Keep a record of test scenarios: ```markdown theme={null} ## Test Cases 1. VIP customer with $100+ cart → 15% discount 2. First-time customer → 10% discount 3. Bulk order (10+ items) → $50 off 4. Geographic restriction (US only) → No discount for CA ``` ## Performance Testing ### Monitor Execution Time * Keep rules simple when possible * Limit fact complexity * Use direct targeting over selectors * Test with realistic cart sizes ### Stress Testing Test with: * Large carts (20+ line items) * Complex product structures * Multiple rules * Heavy fact computations ## Next Steps * [Common Patterns](common-patterns.md) - Real-world tested examples * [Troubleshooting](../reference/troubleshooting/README.md) - Detailed error solutions * [Performance](../advanced/performance.md) - Optimization guide # null Source: https://docs.functionlab.app/overview # Function Lab Documentation **Function Lab** is a powerful Shopify app that enables advanced configuration of Shopify Functions through a flexible rule-based engine. Build sophisticated discount logic, customize checkout behavior, and create dynamic cart transformations—all through JSON configuration, no code required. ## What is Function Lab? Function Lab leverages Shopify's Functions API to provide fine-grained control over your store's pricing, checkout, and cart behavior. Instead of writing and deploying custom functions, you configure rules using a declarative JSON format powered by the `shopify-rules-engine`. ### Key Capabilities * **Product Discounts**: Percentage or fixed amount discounts with advanced targeting * **Shipping Discounts**: Free shipping, rate adjustments, and method-specific rules * **Order Discounts**: Cart-level discounts with flexible targeting * **Delivery Customization**: Hide, reorder, or filter shipping methods * **Payment Customization**: Control available payment methods * **Cart Transforms**: Merge line items into bundles or update cart properties ## Why Use Function Lab? ### No Code Required Configure complex business logic through JSON rules instead of writing and maintaining custom functions. ### Powerful Expression System Use JMESPath or custom filter syntax to query cart data, customer attributes, product metadata, and more. ### Dynamic Pricing Implement tiered pricing, customer-specific rates, geographic pricing, and conditional discounts. ### Real-Time Testing Test your configurations directly in the Shopify admin with instant preview feedback. ### Professional-Grade Features * Multi-rule strategies with precedence control * Facts system for complex calculations * Conditional logic with boolean operations * Metafield and customer attribute integration * Performance-optimized evaluation engine ## Quick Navigation ### New to Function Lab? Start with the [Quick Start Guide](getting-started/quick-start.md) to create your first function in 5 minutes. ### Understanding the Basics Read [Core Concepts](getting-started/core-concepts.md) to learn the fundamental building blocks: rules, conditions, events, and facts. ### Building Specific Functions Jump to [Function Types](function-types/product-discounts/overview.md) to explore detailed documentation for each function type with examples. ### Advanced Use Cases Explore [Advanced Features](advanced/facts/README.md) for complex conditions, dynamic values, and performance optimization. ### Looking for Examples? Browse the [Cookbook](reference/cookbook/README.md) for 30+ ready-to-use recipes covering common business scenarios. ### Need Help? Check the [Troubleshooting Guide](reference/troubleshooting/README.md) for common errors and debugging strategies. ## Version & Compatibility This documentation covers Function Lab for Shopify Functions API. All examples are tested and validated against the current Shopify Functions API specification. **Requirements:** * Shopify Plus plan (required for Functions API access) * Function Lab app installed from Shopify App Store * Admin API access for function configuration ## What's in This Documentation | Section | What You'll Find | | --------------------- | ---------------------------------------------------------------------- | | **Getting Started** | Quick start tutorial, core concepts, testing guide, common patterns | | **Function Types** | Detailed reference for each function type with parameters and examples | | **Advanced Features** | Facts system, complex conditions, dynamic values, optimization | | **Reference** | Complete API reference, cookbook recipes, troubleshooting guide | ## Community & Support * **GitHub Issues**: Report bugs or request features * **Documentation Feedback**: Help us improve these docs * **App Support**: Contact Function Lab support team *** **Ready to get started?** → [Quick Start Guide](getting-started/quick-start.md) **Want to understand the concepts first?** → [Core Concepts](getting-started/core-concepts.md) **Looking for specific examples?** → [Cookbook](reference/cookbook/README.md)