Join us for an upcoming Shopify Partner webinar on February 27, 2024. Discover the latest Checkout Extensibility features, and deep dive on improvements to Shopify Functions and Web Pixels. Register now for either the 10am EST or 2pm EST sessions.

Can't create recurring charge due to 'X-Frame-Options = deny'.

mfvas
Visitor
1 0 1

Hi,

 

I am trying to create a recurring charge in an embedded app created in Node.js and based on Express. Everything works perfectly until step 3 - these steps - where Shopify is redirecting the merchant to accept or decline the charge. It is simply not allowed because the app is embedded. In the console I get the following error:

 

Refused to display 'confirmation_url' in a frame because it set 'X-Frame-Options' to 'deny', where I've removed the confirmation_url for readability.

 

How do I circumvent this? It looks like I'm not the only one who has had this problem, so it is probably a problem that should be addressed in the documentation.


All the best,
Mathias

Replies 5 (5)

Busfox
Shopify Staff (Retired)
628 49 110

Hi @mfvas,

 

You need to do a top level redirect that escapes the iframe when redirecting the merchant to the confirmation url. There's an explanation in our oAuth documentation that also applies here:

 

Since the application is loaded inside an iframe, it is critical that the initial OAuth redirect to Shopify occurs at the parent level, escaped from the iframe. Shopify returns the X-Frame-Options=DENY header and prevents any Shopify admin pages from being loaded inside an iframe. The Embedded App SDK provides a method that can be used to perform a redirect within the parent window.

To learn more visit the Shopify Help Center or the Community Blog.

Pritam_Roy
Shopify Partner
5 1 12

Hi, you can do a top level page redirect to bypass this-
Eg. 
Instead of doing 
`window.location.href = response.data.confirmation_url;`

do
`window.top.location.href = response.data.confirmation_url;`

chenster
Shopify Partner
134 5 29

@Pritam_Roy 's comment works!

Cartoo
Not applicable

Thank you @Pritam_Roy  !

dylanpierce
Shopify Partner
203 3 91

I was stuck on this for awhile too. I wanted to offer multiple plans, but the Shopify app tutorial doesn't provide that example, and neither does the documentation on shopify.dev.

Below is an example using React & the AppBridge component:

 

NOTE: in the Shopify app tutorial example, the server redirects the client to the appSubscriptionCreate's confirmationURL. Instead you'll need to have your server return the confirmationURL in a string format. That way you can escape the iframe your app is embedded in and resolve the X-Frame-Options issue.

import { Page } from '@shopify/polaris'
import createApp from '@shopify/app-bridge';
import { Redirect } from '@shopify/app-bridge/actions';
import Cookies from "js-cookie";
import axios from 'axios';


export default function Plans() {
  const app = createApp({
    apiKey: API_KEY,
    shopOrigin: Cookies.get('shopOrigin'),
  });

  const redirect = Redirect.create(app);

  function openPlan(planUrl) {
    axios.get(planUrl)
      .then((res) => {
        redirect.dispatch(Redirect.Action.REMOTE, { url: res.data.confirmationUrl, newContext: false })
      })
      .catch(err => { console.log(err) })
  }


  return (
    <Page>
      Pick plan:

      <button onClick={() => { 
        openPlan('/api/plan/basic') 
      }}>
        Basic
      </button>
      <button onClick={() => { 
        openPlan('/api/plan/pro') 
      }}>
        Professional
      </button>
      <button onClick={() => { 
        openPlan('/api/plan/enterprise') 
      }}>
        Enterprise
      </button>
    </Page>
  )
}
Founder of Real ID - Verify your customer's real IDs easily & securely with modern AI