Have your say in Community Polls: What was/is your greatest motivation to start your own business?
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Charge is sending merchant to their shop after approval, instead of back to App

Solved

Charge is sending merchant to their shop after approval, instead of back to App

Alex-Miller
Excursionist
18 2 4

Hello! Thanks for reading this and your patient advice 🙂

I'm new Next.js and the React context API, but excited to use these technologies! So i've been kicking the tires on the default react app from the Shopify CLI and got to the point where i can install the app and create a charge, but for some reason, after approval the charge is sending the user to their shop, instead of back to the app.

I've left the _app.js default, aside from passing the shopOrigin in the props:

 

class MyApp extends App {
  render() {
    const { Component, pageProps, shopOrigin } = this.props;
    return (
      <PolarisProvider i18n={translations}>
        <AppBridgeProvider
          config={{
            apiKey: API_KEY,
            shopOrigin: shopOrigin,
            forceRedirect: false,
          }}
        >
          <ApolloClientProvider Component={Component} {...pageProps} shopOrigin={shopOrigin} pageProps={pageProps}/>
        </AppBridgeProvider>
      </PolarisProvider>
    );
  }
}

 

 

Next in the index.js I create a useMutation hook called subscribeMutation and dispatch the redirect to the mutation's confirmationUrl

 

 

import { useContext, useState } from 'react';
import { AppBridgeContext } from "@shopify/app-bridge-react/context";
import { Button, Heading, Page } from "@shopify/polaris";
import { Redirect } from '@shopify/app-bridge/actions';
import { useMutation } from '@apollo/react-hooks';

const Index = (...props) => {
  const {shopOrigin} = props[0];
  const fullOrigin = `https://${shopOrigin}`

  const appBridge = useContext(AppBridgeContext);
  const redirect = Redirect.create(appBridge);

  const [ subscribeMutation, 
    { loading: mutationLoading, error: mutationError }]
    = useMutation(gqlSubscriptionQuery(fullOrigin), null, {enabled:false} );
    // USE MUTATION, enabled:false = doesnt run on first load
  
  const handleClick = async () => {
    const data = await subscribeMutation() // returned by useMutation
    
    const redirectUrl = data.data.appSubscriptionCreate.confirmationUrl;
    /// https://myshop.myshopify.com/admin/charges/{my_app_id}/confirm_recurring_application_charge?signature=xxx
    
    const redirectAdminPath = redirectUrl.split(`${fullOrigin}/admin`)[1]
    /// /charges/{my_app_id}/confirm_recurring_application_charge?signature=xxx
    
    redirect.dispatch(Redirect.Action.REMOTE, redirectUrl);
  }
  
  
  return (
    <Page title="Product Selector" >
      <Heading>Shopify app with Node and React ?</Heading>
      <p>props: {JSON.stringify(props)}</p>
      {/* [{"shopOrigin":"myshop.myshopify.com"},{}]*/}
      
      <Button onClick={handleClick}>Subscribe</Button>
      
      {mutationLoading && <p>Loading...</p>}
      {mutationError && <p>Error 😞 Please try again</p>}

    </Page>
  );
}

 

then the user gets redirected to confirm the subscription (✓) and then they get sent off to their storefront with charge_id in the query string (⚠)...

How do i send them back to the app (i also tried using the ADMIN_PATH redirect action, but same result)?

 

Other, related questions:

I'm assuming after the charge I'll get a webhook, but should i be doing this from the server side instead? 

how do you use the /server/handlers/mutations which exports a const getSubscriptionUrl = async ctx ? 

Create a route for it and make a rest request? I wish there was better documentation on this part of the app.

It also took me quite a while to figure out how to use the context and pass the the shopOrigin down as props... i still dont think i'm doing it right - any hints here would be handy too!

 

Thank you!!!

 
 

 

 

AIMHUGE GROWTH CONSULTING
Alex@aimhuge.com
Accepted Solution (1)

Alex-Miller
Excursionist
18 2 4

This is an accepted solution.

A little more head banging and i realized that there's a returnurl parameter in the graphql mutation... I can use that to send the user back to my app's thank you page with 

 

 

const data = await subscribe() // returned by useMutation
const redirectUrl = data.data.appSubscriptionCreate.confirmationUrl;
redirect.dispatch(Redirect.Action.REMOTE, redirectUrl);

 

 

 

const gqlSubscriptionQuery = (returnUrl) => {
  return gql`
  mutation {
      appSubscriptionCreate(
          name: "Super Duper Plan"
          returnUrl: "${returnUrl}"

 

 

AIMHUGE GROWTH CONSULTING
Alex@aimhuge.com

View solution in original post

Reply 1 (1)

Alex-Miller
Excursionist
18 2 4

This is an accepted solution.

A little more head banging and i realized that there's a returnurl parameter in the graphql mutation... I can use that to send the user back to my app's thank you page with 

 

 

const data = await subscribe() // returned by useMutation
const redirectUrl = data.data.appSubscriptionCreate.confirmationUrl;
redirect.dispatch(Redirect.Action.REMOTE, redirectUrl);

 

 

 

const gqlSubscriptionQuery = (returnUrl) => {
  return gql`
  mutation {
      appSubscriptionCreate(
          name: "Super Duper Plan"
          returnUrl: "${returnUrl}"

 

 

AIMHUGE GROWTH CONSULTING
Alex@aimhuge.com