Why Shopify doesn't handle this natively
Shopify's variant system was designed for fixed SKU pricing. A Small Red Shirt is $25, a Medium Blue Shirt is $27, period. It wasn't designed for "base price + optional add-ons." A $5 gift wrap fee a customer can toggle on or off doesn't map to variants (it would double the SKU count for every product with the option) and doesn't map to line-item properties, which are informational only and don't affect price.
Three practical approaches emerged. Only one is the modern right answer.
Approach 1: Cart Transform Functions (the modern right answer)
Cart Transform is Shopify's server-side function API (2023+) that runs at checkout to modify cart lines: add fees, split, merge. It reads the customer's line-item properties (e.g. "Gift Wrap: yes") and adds the fee to the cart line's price.
Pros:
- Clean cart line: "Custom Mug: $25" then a separate line "Gift Wrap: $5"
- No hidden products cluttering your catalog
- Discount codes work correctly (or intentionally excluded via flag)
- Analytics reports remain clean (one SKU per variant, not a hidden fee product)
- Scales infinitely: one Cart Transform rule can price options across your entire catalog
Cons:
- Needs an app or custom code to set up (PIMW Product Personalizer's version works on every Shopify plan, no Plus needed)
- Requires Function extension deploy via Shopify CLI if building custom
Personalizer apps like PIMW Product Personalizer ($7.99+/mo), Bold Product Options ($14.99+/mo), and Hulk Product Options ($8.90+/mo) all provide add-on pricing that works without Shopify Plus, and PIMW's Cart Transform pricing is included on its Free plan too. Customer experience is identical.
Approach 2: Hidden fee products (deprecated: avoid)
Old pattern: create a hidden product called "Engraving Fee $5" with a variant per price point. When customer selects engraving, the personalizer app adds this hidden product to cart alongside the main product.
Why to avoid:
- Clutters your product catalog with 5-10 fee products
- Shows up as a separate line in checkout ("1 × Cotton T-Shirt $25, 1 × Engraving Fee $5"), which looks messy
- Breaks discount codes: "10% off" applies to the fee product too
- Breaks reports: fees appear as separate SKUs, distorting AOV + product performance analytics
- Breaks POD partner sync: hidden fee products may sync to POD partner and cause errors
Only use if you have a very old personalizer app that doesn't support Cart Transform yet.
Approach 3: Variant per fee (usable for finite tiers)
Create a "Standard" variant at $25 and an "Engraved" variant at $30. Customer picks the variant.
Pros: Simple, native Shopify, no app needed.
Cons: Doubles (or triples, or 10x) your variant count for every extra option. A t-shirt with 5 sizes × 8 colors × Standard/Engraved = 80 variants instead of 40. Add rush production and gift wrap and you're at 320 variants. Not scalable past 2-3 options with fees.
Use only when the fee corresponds to a truly different product (e.g. "Silver Chain" vs "Gold Chain" is variant-worthy; "+ engraving" is not).
Setup with PIMW Product Personalizer (Cart Transform on any plan)
- Install PIMW Product Personalizer (Free plan supports Cart Transform on 1 personalizer)
- Dashboard → New Personalizer
- Add the field customers will select (e.g. Checkbox "Add gift wrap" or Text "Engraving name")
- Click the field → Pricing tab
- Choose pattern: Per-option flat, Per-character, Percentage of base, or Tiered quantity
- Set the fee amount
- Preview updates cart in real time
- Attach personalizer to product
- Test order: cart should show fee as clean separate line
Pricing pattern examples
Pattern 1: Per-option flat fee (Gift Wrap +$5)
Best for: yes/no add-ons where the fee is uniform. Cart Transform rule: if Gift Wrap = "yes", add $5 to line price.
Pattern 2: Per-character pricing (Engraving after 10 free chars)
Best for: text personalization where surface size limits characters. Cart Transform rule: if Engraving Text exists, compute Math.max(0, chars - 10) * 0.50 and add to line price. Live counter shows customer "5 extra chars = +$2.50" as they type.
Pattern 3: Percentage of base (Rush Production +20%)
Best for: fees that should scale with product value. $200 necklace + 20% rush = $40 rush fee. $1500 wedding ring + 20% rush = $300 rush fee. Cart Transform reads variant base price and computes percentage.
Pattern 4: Tiered quantity (Volume Discount)
Best for: bulk pricing. 1-9 units = full price, 10-49 = -10%, 50+ = -20%. Cart Transform reads cart quantity across matching lines and applies discount.
Pattern 5: Combo discount ($5 off when both Engraving + Gift Wrap selected)
Best for: rewarding customers who buy multiple upgrades. Cart Transform: if both flags true, subtract $5 from line. Shows in cart as "Combo discount: -$5".
How the fee displays at checkout
With Cart Transform (PIMW Product Personalizer pattern):
- Cart page: Product line + separate fee lines, each with description ("Gift wrap: +$5", "Engraving 'Emma': +$2.50")
- Checkout page: Same clean breakdown, preserved through payment
- Order confirmation email: Fees listed as line items with clear labels
- Merchant admin order view: Fees visible in the order breakdown
With hidden fee products (old pattern):
- Cart: "1 × Cotton T-Shirt $25, 1 × Engraving Fee $5" appears as two separate products, which confuses customers
- Checkout: Same messiness
- Analytics: Engraving Fee shows as a product with sales; distorts your product performance reports
Discount code handling
By default, Cart Transform fees are subject to discount codes just like the base price. If a merchant runs "20% off everything" and you added a $5 gift wrap fee, the customer pays $5 - 20% = $4 for the wrap.
Usually that's what you want. Sometimes you don't: a rush production fee is a real cost you can't discount without losing margin. To exclude a fee:
- In PIMW Product Personalizer's field pricing settings, toggle "Exclude from discount codes"
- The app adds an underscore-prefixed attribute (
_discount_excluded) that Shopify's Discount Function skips when computing discounts - Requires a paired Discount Function on the store (auto-installed by PIMW Product Personalizer)
App comparison for fee pricing
| App | Fee pricing patterns | Entry price | Free plan? |
|---|---|---|---|
| PIMW Product Personalizer | All 5 patterns (flat, per-char, percentage, tiered, combo) | $7.99/mo Basic | Yes: 1 personalizer |
| Bold Product Options | Flat, percentage, tiered | $14.99/mo Basic | Trial only |
| Hulk Product Options | Flat, tiered | $8.90/mo | Limited free |
| Zepto Product Personalizer | Flat, per-char | $9.99/mo | Trial only |
| Zakeke | Flat, percentage | ~$29.99/mo | Trial only |
| Kickflip | Flat, tiered (+ 1.95% transaction fee) | Subscription + 1.95% | Trial only |
Tax handling on fees
Cart Transform fees inherit the tax rate of the parent product's cart line. If the product is subject to 8% sales tax, the fee is too. No separate tax configuration needed.
For EU VAT stores, the fee is treated as part of the same supply: same VAT rate as the product. Verify with your accountant that this matches your VAT classification for optional accessories vs core product.
Common issues + fixes
| Issue | Cause | Fix |
|---|---|---|
| Fee not applying at cart | Cart Transform rule inactive or misconfigured | Personalizer dashboard → Cart Transform logs → verify recent runs |
| Fee applies twice on same line | Function ran without idempotency check | App-side fix; report to app developer if persistent |
| Discount code makes fee negative | Discount larger than base + fee combined | Set minimum cart threshold on discount code |
| Fee doesn't show in checkout summary | Old theme's cart template missing line breakdown | Upgrade theme to Online Store 2.0 (Dawn) |
| Fee amount looks wrong on multi-currency store | Fee not converting to customer's currency | Personalizer must use variant's cost.amountPerQuantity, not a hardcoded amount |
Frequently asked questions
How do I charge extra for an option on Shopify?
Use Cart Transform via a personalizer app (PIMW Product Personalizer, Bold, Hulk). Configure the fee as per-option flat, per-character, percentage, or tiered. Fee shows as clean cart line at checkout.
Is Cart Transform Plus-only?
Not with PIMW Product Personalizer. Its Cart Transform pricing works on every Shopify plan without Plus, and it's included on the Free plan.
Should I create a hidden fee product?
No: deprecated pattern. Clutters catalog, breaks discount codes, breaks reports. Use Cart Transform instead.
Best pricing pattern for gift wrap?
Per-option flat fee ($5 typical). Cart Transform rule: if Gift Wrap = "yes", add $5. 40-50% take rate on gift orders.
Best pattern for engraving?
Per-character. First 10 chars free, $0.50-1.00/char after (depends on surface). Live counter shows fee as customer types.
Best pattern for rush production?
Percentage (15-25% of base) so fee scales with product value. Or flat if all products cost similar.
How to exclude fees from discount codes?
PIMW Product Personalizer field settings → "Exclude from discount codes" toggle. Adds hidden attribute; paired Discount Function skips fees.
Do fees inherit product tax rate?
Yes. Cart Transform fees taxed at same rate as parent product's cart line. No separate tax config.
Multi-currency store: do fees convert?
Yes if personalizer uses cost.amountPerQuantity from variant instead of hardcoded amount. PIMW Product Personalizer handles this correctly.
Best free app for option pricing?
PIMW Product Personalizer Free plan. 1 personalizer, all 5 pricing patterns, no trial expiry. Alternative: Hulk Product Options limited free tier.
Related setup guides
- Cart Transform Functions Developer Guide
- Per-Character Pricing Setup
- Tier-Based Option Pricing
- Cart Transform vs Variant Pricing
Sources & further reading
Primary sources referenced in this article. We link to official platform documentation and standards bodies rather than secondary summaries so you can verify claims directly.
- Shopify.dev: Cart Transform Function API reference
- Shopify Help Center: Discounts
- Shopify.dev: Build a Cart Transform Function
- Shopify Help Center: Product variants
- Shopify.dev: Product variant limits
- Shopify Help Center: Line item properties (customization)
Charge for options: free on Shopify
PIMW Product Personalizer's Free plan includes Cart Transform pricing on 1 personalizer. All 5 patterns (flat, per-char, percentage, tiered, combo). No credit card.
Install PIMW Product Personalizer