Hi Team,
We’re developing a Shopify app that includes a Post-Purchase UI Extension. Our primary goal is to reliably log and attribute specific line items that are added to an order because a customer accepted an offer within this post-purchase extension. We need to store metadata like source="post-purchase-offers"
, type="upsell"
, and potentially an internal offer/sale ID against the specific order_line_items
record in our database (Prisma/PlanetScale).
We’ve explored two main approaches, encountering challenges with both:
1. Using Webhooks (orders/create
, orders/update
)
- Attempt: We tried processing the
orders/create
andorders/update
webhooks (handled inpages/api/webhooks/orders/create.ts
andpages/api/webhooks/orders/update.ts
respectively) to identify the newly added line item and update its metadata. We attempted to pass metadata via line item properties (e.g.,_platter_sale
,_platter_source
) added during the extension’scalculateChangeset
call, and also tried storing related data in the order’snote_attributes_json
(via a separate API call) for the webhook to look up. - Challenge: Reliably associating the correct metadata at the time the line item is first processed by the webhook has been difficult.
- We initially faced issues potentially creating duplicate order records or failing unique constraints (
P2002
error when usingprisma.orders.upsert
inorders/update.ts
, which we’ve since changed toprisma.orders.update
with a fallback). - There seems to be a timing issue where the webhook might process the line item before our attribution metadata (e.g., from the
note_attributes_json
update) is available, or the line item properties added viacalculateChangeset
aren’t consistently available or sufficient for the lookup logic (seeextractPlatterProperties
and handle lookup logic inpages/api/webhooks/orders/update.ts
).
- We initially faced issues potentially creating duplicate order records or failing unique constraints (
2. Using Direct API Calls from the Extension
- Attempt: After the
applyChangeset
call succeeds within the post-purchase extension (checkout-extensions/post-purchase-offers/pages/post-purchase-offers.tsx
→handleAcceptOffer
function), we triggerfetch
calls to custom API endpoints in our app (/api/log-upsell
,/api/log-post-purchase
,/api/store-order-metadata
) to directly log the event and associate metadata (likeplatterSaleId
, source, type, numericlineItemId
, numericvariantId
) with the order/line item in our database. - Challenge: We initially faced issues where these
fetch
calls weren’t executing, likely due to using relative URLs from the sandboxed extension environment.- We fixed this by using absolute URLs constructed from
process.env.NEXT_PUBLIC_APP_URL
(set correctly in Vercel). - We also corrected the payload for
/api/log-upsell
to send required numeric IDs. - Current Blocker: Despite these fixes, browser console logs show that the execution within
handleAcceptOffer
appears to be terminating after the successful call to sign the changeset (/api/sign-changeset
returns 200 OK in Network tab) but before ourPRE-FETCH
console logs for the logging API calls (/api/log-upsell
, etc.). This suggests a potential failure during or immediately after the ShopifyapplyChangeset(jwt)
function call, preventing our subsequent logging logic from running. We’ve added detailed[PP DEBUG]
console logs throughouthandleAcceptOffer
to pinpoint this, but the execution doesn’t seem to reach the point afterapplyChangeset
completes successfully. (Note: We are also seeing persistent 400 errors for/api/post-purchase/logging
and/api/post-purchase/analytics
in logs, but believe these might be unrelated calls from older code/deployments as they aren’t explicitly called in the currenthandleAcceptOffer
).
- We fixed this by using absolute URLs constructed from
Our Question:
What is the recommended best practice for reliably attributing line items added via a post-purchase extension?
- Is the webhook approach generally preferred, and if so, are there specific techniques or standard line item properties we should use during
calculateChangeset
that theorders/update
webhook can reliably use for attribution before potentially creating/updating the line item record without the metadata? - Or is the direct API call approach viable? If so, what could be causing the execution to halt after
applyChangeset
succeeds but before our subsequentfetch
calls are logged or made? Are there common pitfalls or limitations with executingfetch
calls within the post-purchase extension environment afterapplyChangeset
?
We need a robust way to ensure that when a line item is added via the post-purchase extension, we can definitively flag that specific order_line_items
record in our database with the correct source and offer context.
Any guidance or pointers would be greatly appreciated. We’re happy to provide more detailed logs or code snippets if needed.
Thanks,
Jesse