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.

We're moving the community! Starting July 7, the current community will be read-only for approx. 2 weeks. You can browse content, but posting will be temporarily unavailable. Learn more

Use webhooks/orders/create to create new draft order with Node & React

Use webhooks/orders/create to create new draft order with Node & React

bmarshall511
Tourist
4 0 1

Keeping in mind I'm completely new to creating Shopify apps & React, my goal is to use the /webhooks/orders/create webform to create a new draft order using GraphQL. Here's what I currently have that's successfully firing when a order is created:

 

router.post('/webhooks/orders/create', webhook, (ctx) => {
    console.log('received webhook: ', ctx.state.webhook);

    // Order created, now create draft order
  });

Question is, what next? Looking at the documentation, looks like I need to use graphql-tag & react-apollo, so tried the following with no luck:

 

const gql = require('graphql-tag'); 
const { Mutation } = require('react-apollo');

const createDraftOrder = () => { const CREATE_DRAFT_ORDER = gql` mutation draftOrderCreate($input: DraftOrderInput!) { draftOrderCreate(input: $input) { draftOrder { id } userErrors { field message } } } `; return ( <Mutation mutation={CREATE_DRAFT_ORDER}> {(handleSubmit, { error, data }) => { console.log(error); console.log(data); }} </Mutation> );
}

Seems it doesn't like my return value so probably using this incorrectly. Also know I need to pass the input variables to the mutation, but not sure how. Any help would be greatly appreciated. 

Replies 3 (3)

bmarshall511
Tourist
4 0 1

Getting closer, think I need to do something along the lines of this after the webhook is fired:

const graphQLEndpoint =
      'https://mystore.myshopify.com/admin/api/graphql.json';

    return fetch(graphQLEndpoint, {
      headers: {
        'Content-Type': 'application/graphql',
        'X-Shopify-Access-Token': 'ACCESS TOKEN',
      },
      body: 'shop { name }',
    }).then((response) => {
      console.log(response);
      return response.json();
    });

Now the ?s is how do I get the access token and is the format of body correct in what I'm sending?


I've looked through this: https://help.shopify.com/en/api/getting-started/authentication/oauth

But not sure how to grab it in my server.js. Here's what I've got:

 

const Koa = require('koa');
const next = require('next');
const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
const dotenv = require('dotenv');
const { verifyRequest } = require('@shopify/koa-shopify-auth');
const session = require('koa-session');
require('isomorphic-fetch');
dotenv.config();
const { default: graphQLProxy } = require('@shopify/koa-shopify-graphql-proxy');
const Router = require('koa-router');
const {
  receiveWebhook,
  registerWebhook,
} = require('@shopify/koa-shopify-webhooks');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const routerFunctions = require('./server/router');

const { SHOPIFY_API_SECRET_KEY, SHOPIFY_API_KEY, TUNNEL_URL } = process.env;

app.prepare().then(() => {
  const server = new Koa();
  const router = new Router();
  server.use(session(server));
  server.keys = [SHOPIFY_API_SECRET_KEY];

  router.get('/', routerFunctions.processPayment);

  server.use(
    createShopifyAuth({
      apiKey: SHOPIFY_API_KEY,
      secret: SHOPIFY_API_SECRET_KEY,
      scopes: ['read_products', 'write_products', 'write_orders'],
      async afterAuth(ctx) {
        const { shop, accessToken } = ctx.session;
        ctx.cookies.set('shopOrigin', shop, { httpOnly: false });

        const registration = await registerWebhook({
          address: `${TUNNEL_URL}/webhooks/products/create`,
          topic: 'PRODUCTS_CREATE',
          accessToken,
          shop,
        });

        if (registration.success) {
          console.log('Successfully registered webhook!');
        } else {
          console.log('Failed to register webhook', registration.result);
        }
        // Create order
        const createOrderWebhook = await registerWebhook({
          address: `${TUNNEL_URL}/webhooks/orders/create`,
          topic: 'ORDERS_CREATE',
          accessToken,
          shop,
        });

        if (createOrderWebhook.success) {
          console.log('Successfully registered createOrderWebhook webhook!');
        } else {
          console.log(
            'Failed to register createOrderWebhook webhook',
            createOrderWebhook.result,
          );
        }
        // End create order

        ctx.redirect('/');
      },
    }),
  );

  const webhook = receiveWebhook({ secret: SHOPIFY_API_SECRET_KEY });

  router.post('/webhooks/products/create', webhook, (ctx) => {
    console.log('received webhook: ', ctx.state.webhook);
  });

  const createDraftOrder = () => {
    const graphQLEndpoint =
      'https://mystore.myshopify.com/admin/api/graphql.json';

    return fetch(graphQLEndpoint, {
      headers: {
        'Content-Type': 'application/graphql',
        'X-Shopify-Access-Token': '',
      },
      body: 'shop { name }',
    }).then((response) => {
      console.log(response);
      return response.json();
    });
  };

  router.post('/webhooks/orders/create', webhook, (ctx) => {
    // NEED TO MAKE THE CREATE NEW DRAFT ORDER VIA GRAPHQL HERE
    createDraftOrder();
  });
  // End order created

  server.use(graphQLProxy());

  router.get('*', verifyRequest(), async (ctx) => {
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
    ctx.res.statusCode = 200;
    return;
  });
  server.use(router.allowedMethods());
  server.use(router.routes());

  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});
LeeLGT
Shopify Partner
1 0 1

Was this ever resolved? I'm having exactly the same issue here.

zoultrex
Tourist
18 0 2

Same here, did anyone solved it?

Also, can anyone explain how in the tutorial there was a part of the server js code that read

server.use(verifyRequest());
server.use(async (ctx) => {
        await handle(ctx.req, ctx.res);
        ctx.respond = false;
        ctx.res.statusCode = 200;
        return
    });

But in the example above it was changed into:

router.get('*', verifyRequest(), async (ctx) => {
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
    ctx.res.statusCode = 200;
    return;
  });

How do you know when you have to handle this part of the server routines(first code snippet above) in another class (seconde code snippet above)