Shopify appPurchaseOneTimeCreate confirmationUrl redirection error

Topic summary

Developers using Shopify’s appPurchaseOneTimeCreate mutation in Remix.js apps encounter an X-Frame-Options error when redirecting users to the confirmation URL after clicking the purchase button. The error message indicates the confirmation URL is “denied by X-Frame-Options directive set to deny,” preventing the payment flow from completing within the embedded app frame.

Two working solutions have been identified:

  1. Client-side redirect using top-level navigation:
top.location.href = res.confirmationUrl

This breaks out of the iframe restriction by redirecting the entire browser window.

  1. Server-side redirect with _parent target (Remix-specific):
const { redirect } = await authenticate.admin(request);
return redirect(response, { target: "_parent" });

This uses Shopify’s authentication redirect method with the _parent target to navigate the parent frame.

Alternative for Polaris components:

<Button variant="primary" url={ConfirmationUrl} target="_parent">Proceed</Button>

The root cause is Shopify’s restriction on opening new pages within embedded apps, requiring redirects to target the parent frame rather than the embedded iframe.

Summarized with AI on October 31. AI used: claude-sonnet-4-5-20250929.

Hi,

I built a Shopify app with Remix.js using the app Purchase One Time Create billing method. After the user clicks the purchase button, it creates a confirmation URL. For that, I followed (https://shopify.dev/docs/api/admin-graphql/2024-01/mutations/appPurchaseOneTimeCreate).

In the server action, the app Purchase One Time Create mutation is executed, and it redirects to the confirmation URL.

During the redirection process, I’m getting the following error:

If I open this link in a separate tab, it opens, but it does not open when the checkout button is clicked.

Please help me resolve this issue.

2 Likes

I am also experiencing an issue with the appPurchaseOneTimeCreate billing method in my Shopify app built with Remix.js. After the user clicks the purchase button, the appPurchaseOneTimeCreate mutation creates a confirmation URL, which I then attempt to redirect to. However, I encounter the following error:
The loading of “https://admin.shopify.com/store/demo-store/charges/ApplicationCharge/confirm_application_charge?signature=” in a frame is denied by “X-Frame-Options“ directive set to “deny“.

This issue is blocking our One Time Payment feature and affecting our users’ ability to complete the purchase process.

Can you provide guidance on how to resolve this issue? Is there a specific way to handle the redirection to the confirmation URL to avoid the X-Frame-Options restriction, or any alternative approach to ensure the payment process works seamlessly?

3 Likes

please, tell me you guys found the problem… i am facing the exact same problem and i have been days now trying to find a solution

1 Like

I found solution for this like use below code for redirect and this will work.

top.location.href = res.confirmationUrl

I found this solution in this question
https://community.shopify.com/c/shopify-apps/recurring-charges-confirmation-url-changing-when-using-app/m-p/2112934/highlight/true

You should use the redirect from the authentication

const { redirect } = await authenticate.admin(request);
return redirect(response, { target: "_parent" });

@Manoj_M

You should use the redirect from the authentication

const { redirect } = await authenticate.admin(request);
return redirect(response, { target: "_parent" });

Hi why is this better? And how to implement it in the node template

@Peterpot , I’m not sure but I think shopify doesn’t allow to open new page in embedded apps. You could try to redirect it in the parent frame. e.g. same like _parent behavior

If you’re using remix you can extract redirect from await authenticate.admin(request);

or if using polaris you could used Proceed