Environment
- Shopify CLI version: Latest (using
npx shopify app deploy) - Extension API version: 2024-07
- Store type: Production store (Plus plan)
- Payment methods affected: Shop Pay with credit card, regular credit card
Problem Description
My post-purchase extension works correctly in the development environment but fails silently in production. The ShouldRender phase executes successfully, but the Render phase never runs.
What’s happening:
- Customer completes checkout
- My backend receives the
/offerAPI call fromShouldRender(confirmed via server logs) - Backend returns a valid offer with
{ render: true } storage.update({ offer })is called before returning- The post-purchase page never appears - customer goes directly to thank you page
- No errors in any logs
Evidence from server logs:
[requestId] POST /offer received
[requestId] Offer prepared: shop=mystore.myshopify.com, orderId=xxx, product=Product Name
Sending offer with changes: [{"type":"add_variant","variantID":12345,...}]
{"method":"POST","path":"/offer","status":200,"duration":4071}
The /offer endpoint returns 200 with a valid offer, but my /render endpoint (called in the Render phase) is never hit.
Code Structure
ShouldRender phase:
extend("Checkout::PostPurchase::ShouldRender", async ({ inputData, storage }) => {
try {
const response = await fetch(`${API_BASE_URL}/offer`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: inputData.token }),
});
if (!response.ok) {
return { render: false };
}
const data = await response.json();
const { offer } = data;
if (!offer) {
return { render: false };
}
// Store the offer for the Render phase
await storage.update({ offer });
return { render: true };
} catch (error) {
console.error("Error in ShouldRender:", error);
return { render: false };
}
});
Render phase:
render("Checkout::PostPurchase::Render", () => <PostPurchaseOffer />);
function PostPurchaseOffer() {
const { storage, inputData, done } = useExtensionInput();
const [offer, setOffer] = React.useState(null);
React.useEffect(() => {
async function loadOffer() {
const initialData = await storage.initialData;
if (initialData?.offer) {
setOffer(initialData.offer);
// Notify backend that render executed
await fetch(`${API_BASE_URL}/render`, { /* ... */ });
}
}
loadOffer();
}, []);
// ... rest of component
}
What I’ve verified:
- Extension deployed and active (confirmed in Partner Dashboard)
- Post-purchase page enabled in Settings → Checkout
- “Access post-purchase extensions” - Full access granted
- “Request for Checkout Extension” - Granted
- App installed on production store
network_access = truein shopify.extension.toml- Backend returning valid response with offer data
- Multiple payment methods tested (Shop Pay, credit card)
- Same currency as store default
Questions:
- Is there a way to debug why Shopify decides not to execute the Render phase after ShouldRender returns
{ render: true }? - Are there any platform-level restrictions that would cause this behavior silently?
- Is there a known issue with
storage.update()data not persisting between ShouldRender and Render in production?
Any guidance would be greatly appreciated!