Securely Passing Bundle Discount from Cart Transform to Discount Function

Solved

Securely Passing Bundle Discount from Cart Transform to Discount Function

carloscrespo
Shopify Partner
11 0 3

Hi everyone!,

 

I have two Shopify Functions:

 

1. A Cart Transform function that merges multiple child products into a single “bundle” line item.
2. A Discount Function that needs to show a separate discount line (so customers and analytics see it as a discount).

 

Problem:


- The discount function doesn’t see the original child lines (because they’re merged).
- I need to pass the total discount amount (calculated in the cart transform) over to the discount function in a way that can’t be tampered with by someone in the storefront.

 

I tried using cart line attributes to store something like bundle_discount_amount for the discount function to read. However, attributes can be modified from the frontend, so it’s not secure. I looked into cart/line metafields, but they don’t seem writable in a tamper-proof way during Cart Transform. I really want the discount to appear as a separate line item, which is why I’m using the discount function (instead of just overriding the line price in the cart transform).

 

Does anyone know of a secure way to store or verify discount data that the Cart Transform function calculates, so my Discount Function can trust it? Or is there another approach to show the discount line in a tamper-proof manner?

 

Thanks for any insights!

Accepted Solution (1)
jam_chan
Shopify Partner
938 24 193

This is an accepted solution.

There is no direct linkage between functions. My suggestion was to use an app/shop/function owner metafield to store and pass all discounts.

 

If your updates are frequently happened, you can subscribe to webhook and do the updates. I don't have the issue myself.

 

HMAC approach is likely not feasible with Shopify functions, since Functions are not supporting crypto with js. But Rust is possible though I don't know Rust. Chatgpt tells me Rust can support hmac and sha2 libraries in Shopify Functions.

 

No, I don't think Shopify Function caches metafield values. But your sync approach may cause out of sync metafield issues. Let's say the function executes during metafield updates.

 

In the discount function, what is the parent product price after merge operation? The total of all bundle component prices? I just wonder if the discount can apply for the right price

BYOB - Build Your Own Bundles, SPO - SEO App to research keywords & edit social link preview

View solution in original post

Replies 8 (8)

CodingFifty
Shopify Partner
919 138 165

Hi @carloscrespo,

 

Use HMAC signing in your Cart Transform function to securely pass the discount amount to the Discount Function.

Steps:

  1. Cart Transform Function:

    • Calculate the discount.
    • Generate an HMAC hash (crypto.createHmac('sha256', SECRET_KEY).update(amount).digest('hex')).
    • Store the discount + hash in cart attributes.
  2. Discount Function:

    • Read the stored discount + hash.
    • Recalculate the hash.
    • If it matches, apply the discount; otherwise, reject it.

This ensures the discount data can't be tampered with. 

Coding Fifty || Shopify Partner
For any custom section queries, please visit: Fiverr Profile
Found my response useful? Like it and mark as Accepted Solution!
For additional discussions, reach out via: Email ID: codingfifty@gmail.com
carloscrespo
Shopify Partner
11 0 3

Thanks for the idea, the problem here is crypto cannot be used in the shopify functions environment. Anyway, I will try downloading "js-sha256" and test the performance.

 

Any other ideas?

 

Thanks a lot!!

jam_chan
Shopify Partner
938 24 193

Store all your discounts into a single metafield. Read the metafield in your functions?

BYOB - Build Your Own Bundles, SPO - SEO App to research keywords & edit social link preview
carloscrespo
Shopify Partner
11 0 3

Thank you for the suggestion!

In the discount function, I would only be able to read metafields from the parent product (the bundled product), not directly from the individual child products. I could store the total discount in the parent product’s metafield, but the issue arises when the child products’ discounts change.

To keep the discount values updated, the app that creates the bundles would need to subscribe to the product/update webhook and ensure that every time a child product's discount is modified, the parent product's metafield is updated accordingly.

This could be a viable alternative, especially since the HMAC approach isn’t feasible due to Shopify Functions not supporting crypto. I'll explore this option further—thanks for the insight!

Would you happen to know if Shopify Functions cache metafield values? I want to ensure that updated metafields are always read correctly during function execution.

jam_chan
Shopify Partner
938 24 193

This is an accepted solution.

There is no direct linkage between functions. My suggestion was to use an app/shop/function owner metafield to store and pass all discounts.

 

If your updates are frequently happened, you can subscribe to webhook and do the updates. I don't have the issue myself.

 

HMAC approach is likely not feasible with Shopify functions, since Functions are not supporting crypto with js. But Rust is possible though I don't know Rust. Chatgpt tells me Rust can support hmac and sha2 libraries in Shopify Functions.

 

No, I don't think Shopify Function caches metafield values. But your sync approach may cause out of sync metafield issues. Let's say the function executes during metafield updates.

 

In the discount function, what is the parent product price after merge operation? The total of all bundle component prices? I just wonder if the discount can apply for the right price

BYOB - Build Your Own Bundles, SPO - SEO App to research keywords & edit social link preview
carloscrespo
Shopify Partner
11 0 3

I think the best approach is using Rust with the hash method, but I have to try it myself since I do not know Rust either. Personally, with the current limitations for shopify functions I believe Rust is probably the best way.

Liviu_Ungureanu
Shopify Partner
19 0 2

You can use the cart attributes approach but create a hash (using a custom hash function) of the bundle_discount_amount with a secret and store it in a different attribute bundle_discount_key.

 

 

So let's say the bundle_discount_amount = 100 and the secret is aaabbbccc:

In Cart transform:

1. set a cart attribute: bundle_discount_amount

2. generate a hash for bundle_discount_amount + "aaabbbccc" and save it in a different attribute: bundle_discount_key

 

In the Discount Function you will get:

1. bundle_discount_amount = 100

2. bundle_discount_key  = <has calculated in the cart function>

3. Calculate the hash again using bundle_discount_amount = 100 with the secret (aaabbbccc) and compare the calculated hash with bundle_discount_key.

If they match then your bundle_discount_amount was not modified.

 

 

jam_chan
Shopify Partner
938 24 193

If I use cart attributes, customers remove the bundle and the cart attributes will remain? If the customers add a bundle again, it will likely have a conflict? I don't think cart attributes are good because they don't get removed when customers remove the bundle from the cart.

 

Also, how do you store the hash in cart attributes in the Shopify function? Is it possible to do so?

BYOB - Build Your Own Bundles, SPO - SEO App to research keywords & edit social link preview