Handling app subscription cancel

Solved
kt13
Tourist
5 0 0

It seems Shopify first installs the app and then asks the user for authorizing payment. It seems if a user cancels the app subscription, they're not charged for the app but the app remains installed and it can be used for free without any problems.

I searched through the community forums here and it seems people suggest querying the Shopify endpoint to check if the merchant has authorized your app or not and then redirect them to the authorization page again if not.

My question is, which graphql endpoint should I query to check if a merchant has authorized my app or not ?

0 Likes
Mircea_Piturca
Shopify Partner
1462 39 285

This is an accepted solution.

You can get the subscription data by accessing currentAppInstallation in GraphQl.

When merchants log into the app, you get the app activeSubscriptions status, and based on that redirect to the billing page (if subscription is not active)/

Finally—Add variant descriptions to your products
kt13
Tourist
5 0 0

Hello,

Thanks for the quick response. I was able to get the subscrption info as you mentioned and created a middleware on my server to redirect users if a subscription is not active.

I added the following middleware:

 

  server.use(async (ctx, next) => {
    const { shop, accessToken } = ctx.session;
    const isActiveSubscription = await getCurrentSubscription(accessToken, shop);

    if (!isActiveSubscription) {
      const returnUrl = `${HOST}?shop=${shop}`;
      const subscriptionUrl = await getSubscriptionUrl(accessToken, shop, returnUrl);
      return ctx.redirect(subscriptionUrl);
    }

    await next();
  });

 

The problem now is that when a user opens an app (even after denying the charges), Spotify opens the app as an embedded iframe and thus the redirect happens inside the iframe now instead of happening outside. Because of it, the browser complains and refuses to open the redirect url with the following error:
 

Refused to display '<URL>' in a frame because it set 'X-Frame-Options' to 'deny'.

How can I redirect before the embedded application opens just like during installation flow ?

0 Likes
Mircea_Piturca
Shopify Partner
1462 39 285

This is an accepted solution.

There are several ways of handling that.

I am doing this check on the client not on the server. Presenting a modal when the charges are not approved (and kill the app functionality).

You can also pass the billing URL as a query string from the server to an app page and do the redirect from there. Something like: server redirects to /plans?redirect_url=some_billing_api_url, on plans you read the query param and redirect to that URL. It's a bit lame but should work.

image (6).png

Finally—Add variant descriptions to your products
kt13
Tourist
5 0 0

Hey @Mircea_Piturca 

Thanks for the tips, these are really helpful. One last question, I understand the redirect trick from the server since we also have the ability to create a confirm subscription url from the server easily.

For creating this url at client end, do you use the same mutation query which we use at server end ? I mean do you use the following code at client end as well or is there a simpler alternative ?

const returnUrl = `${HOST}?shop=${shop}`;

const getSubscriptionUrl = async (accessToken, shop, returnUrl = process.env.HOST) => {
  const query = JSON.stringify({
    query: `mutation {
      appSubscriptionCreate(
        name: "Plan Name"
        returnUrl: "${returnUrl}"
        test: true
        lineItems: [
          {
            plan: {
              appRecurringPricingDetails: {
                price: { amount: 99.99, currencyCode: USD }
              }
            }
          }
        ]
      )
      {
        userErrors {
          field
          message
        }
        confirmationUrl
        appSubscription {
          id
        }
      }
    }`
  });

  const response = await fetch(`https://${shop}/admin/api/2020-10/graphql.json`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      "X-Shopify-Access-Token": accessToken,
    },
    body: query
  })

  const responseJson = await response.json();
  return responseJson.data.appSubscriptionCreate.confirmationUrl;
};

export default getSubscriptionUrl;

 

 

0 Likes
Mircea_Piturca
Shopify Partner
1462 39 285

This is an accepted solution.

Hey there,

My billing URL is fetched from the server. I have a route that will output that URL. On the client, I just fetch that route.

There are few ways of doing this

Finally—Add variant descriptions to your products
kt13
Tourist
5 0 0

Hey @Mircea_Piturca 

Thank you so much for the detailed help!

Cheers!

0 Likes
Mircea_Piturca
Shopify Partner
1462 39 285

@kt13 happy to help out when I can.

Cheers

Finally—Add variant descriptions to your products