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.

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)