Post Purchase Extension - Order details returned as undefined

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 :slight_smile:

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.