I have created a post-purchase extension to get the order details and pass them to the API when the customer clicks the CTA. It should redirect to the link with these parameters.
But I am stuck at passing the parameters — the order ID is always coming as undefined, even in the live environment.
I tried with both PayPal and credit card payments, but it always returns undefined.
FYI, I’ve updated the tag to checkout-ui-ext, rather than pos-ext (POS extensions), so hopefully you’ll get some eyes on this ![]()
Hi! Thanks for reaching out.
Can you provide a bit more information about the issue you are having? Do you have a minimal reproduction of the code that is not working as expected?
These docs show the APIs available to post purchase extensions:
Thanks. I have updated in Categories @bkspace
Here is the code. I’m trying to get the order reference ID and customer email id in the post-purchase extension, but the order object always returns as undefined.
/**
* Extend Shopify Checkout with a custom Post Purchase user experience.
*/
import React from 'react';
import {
extend,
render,
BlockStack,
Button,
CalloutBanner,
Heading,
Image,
Layout,
TextBlock,
TextContainer,
Link,
View,
} from "@shopify/post-purchase-ui-extensions-react";
/**
* ShouldRender → checks if extension should appear
*/
extend("Checkout::PostPurchase::ShouldRender", async ({ storage }) => {
const initialState = await getRenderData();
await storage.update(initialState);
return { render: true };
});
extend('Checkout::PostPurchase::Render', (root, api) => {
console.log("POST PURCHASE LOADED api", api);
root.appendChild(<App />);
});
async function getRenderData() {
return { status: "ready" };
}
/**
* Render → displays the UI after payment success
*/
render("Checkout::PostPurchase::Render", App);
/**
* Main Component
*/
export function App({ order }) {
// -----------------------------------------
// CUSTOMER DETAILS
// -----------------------------------------
console.log("POST PURCHASE LOADED", order);
const orderId = order?.initialPurchase?.referenceId || "3350289";
const customerId = order?.initialPurchase?.customerId || "NA";
const customer = order?.customer || {};
const firstName = customer?.firstName || "";
const lastName = customer?.lastName || "";
const email = customer?.email || "";
const country = "US";
// Shopify Preview does NOT provide customer info
const isPreview = !email;
// Provide fallback mock data in preview mode
const safeEmail = isPreview ? "kirubha@xxx.com" : email;
const safeFirstName = isPreview ? "Kirubha" : firstName;
const safeLastName = isPreview ? "Sankar" : lastName;
// -----------------------------------------
// PRODUCT NAME → monitorType DETECTION
// -----------------------------------------
const lineItems = order?.lineItems || [];
const productTitle = lineItems[0]?.title || "";
let monitorType = 0;
if (productTitle.includes("Pet Monitor")) {
monitorType = 1;
} else if (productTitle.includes("RV 4G")) {
monitorType = 12;
} else {
monitorType = 0;
}
// -----------------------------------------
// BUILD REDIRECT URL
// -----------------------------------------
const baseUrl = "https://mywaggle.com/subs_outside/index.html";
// const redirectUrl =
// `${baseUrl}` +
// `?orderId=${encodeURIComponent(orderId)}` +
// `&firstName=${encodeURIComponent(safeFirstName)}` +
// `&lastName=${encodeURIComponent(safeLastName)}` +
// `&email=${encodeURIComponent(safeEmail)}` +
// `&country=${country}` +
// `&monitorType=${monitorType}`;
const redirectUrl =
`${baseUrl}` +
`?orderId=${encodeURIComponent(orderId)}`+`&customerId=${encodeURIComponent(customerId)}`;
return (
<BlockStack spacing="xloose">
<CalloutBanner title="Your purchase is complete!">
</CalloutBanner>
<Layout
maxInlineSize={0.95}
media={[
{ viewportSize: "small", sizes: [1, 30, 1] },
{ viewportSize: "medium", sizes: [300, 30, 0.5] },
{ viewportSize: "large", sizes: [400, 30, 0.33] },
]}
>
{/* IMAGE */}
<View>
<Image
source="https://nimbleapi-images.s3.us-west-2.amazonaws.com/others/shopify_subscription_image.jpg"
/>
</View>
<View />
<BlockStack spacing="xloose">
<TextContainer>
<Heading>Just one more step</Heading>
<TextBlock>
Pick your plan and activate it for an instant
</TextBlock>
<Heading level={1}>
10% OFF.
</Heading>
<TextBlock>
Your subscription unlocks real-time alerts, live monitoring, and full protection.
You can also purchase your subscription through the Waggle Pet App.
</TextBlock>
</TextContainer>
<Button
to={redirectUrl}
kind="primary"
appearance="success"
>
Grab 10% OFF
</Button>
</BlockStack>
</Layout>
</BlockStack>
);
}
Thanks for sending over the code! I think I see the issue.
Your App component that you are passing the the render function with render("Checkout::PostPurchase::Render", App); is expecting to be passed an order prop, but that extension point does not pass an order prop.
The props it will be passed are documented here under PostPurchaseRenderApi. I think inputData is what you are looking for. You should be able to get the reference ID from inputData.initialPurchase.referenceId. A customer ID is also available on the initialPurchase, but the email is not available.