preface


Due to the company’s need to develop Shopify’s own application plug-in specifically documented. Shopify is a Canadian e-commerce software developer founded by Tobias Luke and headquartered in Ottawa, Canada. Its service software Shopify is a shopping cart system in the field of SaaS, suitable for cross-border e-commerce to establish independent sites. For a fee, users can build their own online store on it using various themes/templates.

Because it is a foreign official website documents are also in English, it looks a little difficult oh (small English level is limited 🤣🤣). But it should be in Chinese in the future and now many pages have Chinese already.

The official recommendation is to use GraphQL with the React Next-js server rendering framework and Node.js as the backend language. As someone who has never touched GraphQL before, I quickly made up a wave of knowledge. And then I stumbled along and now I get the general idea. I ended up using Node as the main entry to verify that the application plug-in got the relevant Access_token and store address. For the rest of the request, the Shopify interface didn’t use GraphQL but instead used ResfulApi for the backend staff to operate on, and THEN I asked the backend interface for a series of operations. (Finally, I learned that any validation was left to the back end, and that I could use a variety of frameworks for the front end instead of just using next.js).

Register for development prerequisites

  1. createShopifyDeveloper account

    As shown in figure indevelopers.shopify.com/Website registration relevant accounts.

  2. In the relevantpartnersPage creation store (for later application development) and application
    1. There are custom apps and public apps for creating apps as shown below:

      In general I believe that we are creating public applications, and the applications THAT I’ve developed so far have been of the public type, when creating applicationsURLAnd related redirectsURLAll must write because I also did not register domain name what of bar, so at this time is usedngrokIntranet penetration is also used in the official development notes. We filled it out hereURLI’m gonna use it with youngrokThe exposed address corresponds, but usesnodethekoaThe framework has a special middleware is also the official use of redirection addresses are domain name plusshopify/authFor example: URL:https://30aca829.ngrok.io, redirect URL:https://30aca829.ngrok.io/shopify/auth/(Rebooting the computer reveals that even the address has to be filled out again, and thenkoaThe middleware will jump tohttps://30aca829.ngrok.io/shopify/auth/Perform relevant validation operations. (This is at the back entrance). In order to code, and then in later we don’t use itkoaAs an entrance, this address can be filled in as you wish.

    2. Create complete (it is important to get the relevant keys!! Very important!! Read data and request official as developedapiUse)

      So that’s it, that’s it, that’s it, that’s it, that’s it, that’s it.

Write development environment programs

  1. Create the project directory (sample-app) and initialize the project directory using NPM

    npm init -y
    Copy the code
  2. Installation-dependent dependencies

    npm install --save react react-dom next
    Copy the code
  3. Nextjs.frontendx.cn/for those unfamiliar with next.js

    Create the file pages and create index.js below

    const Index = () => (
      <div>
        <p>Sample app using React and Next.js</p>
      </div>
    );
    
    export default Index;
    Copy the code

    Add related run commands to open package.json file to add

    {
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"."dev": "next"."build": "next build"."start": "next start"}}Copy the code

    Running the development environment

    npm run dev
    Copy the code

    This should create a next. Js project and then connect to Shopify

  4. Use ngrok to expose your own port 3000 because next. Js starts with port 3000 by default

    ngrok http 3000
    Copy the code

    Then add it in the Settings of the app you createdThe corresponding url(use thehttpsJust fill in the blanks aboveurl

  5. Use Node’s KOA to render the page

    1. Create the env environment variable file and write the application KEY created on it

      SHOPIFY_API_KEY='YOUR API KEY FROM SHOPIFY PARTNERS DASHBOARD'
      SHOPIFY_API_SECRET_KEY='YOUR API SECRET KEY FROM SHOPIFY PARTNERS DASHBOARD'
      Copy the code
    2. Install verified KOA middleware associated with Shopify

      npm install --save koa @shopify/koa-shopify-auth dotenv koa-session isomorphic-fetch
      Copy the code
    3. Create server.js to write the relevant validation code

      require('isomorphic-fetch');
      const dotenv = require('dotenv');
      const Koa = require('koa');
      const next = require('next');
      const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
      const { verifyRequest } = require('@shopify/koa-shopify-auth');
      const session = require('koa-session'); dotenv.config(); // Graphql middleware const {default: graphQLProxy} = require('@shopify/koa-shopify-graphql-proxy'); 
      const { ApiVersion } = require('@shopify/koa-shopify-graphql-proxy'); const port = parseInt(process.env.PORT, 10) || 3000; const dev = process.env.NODE_ENV ! = ='production'; const app = next({ dev }); const handle = app.getRequestHandler(); const { SHOPIFY_API_SECRET_KEY, SHOPIFY_API_KEY } = process.env; // App.prepare (). Then (() => {const server = new Koa(); server.use(session(server)); server.keys = [SHOPIFY_API_SECRET_KEY]; server.use( createShopifyAuth({ apiKey: SHOPIFY_API_KEY, secret: SHOPIFY_API_SECRET_KEY, scopes: ['read_products'.'write_products'AfterAuth (CTX) {const {shop, accessToken} = ctx.session; afterAuth(CTX) {const {shop, accessToken} = ctx.session; AccessToken ctx.cookies. Set ('shopOrigin', shop, { httpOnly: false }); 
              ctx.redirect('/'); // Redirect to index home},}),); server.use(verifyRequest()); server.use(async (ctx) => { await handle(ctx.req, ctx.res); ctx.respond =false;
          ctx.res.statusCode = 200;
          return}); server.use(graphQLProxy({version: Apiversion.october19})) // Enter the version of the relevant API server.listen(port, () => {console.log(' > Ready on http://localhost:${port}`); // Listening port}); });Copy the code
    4. Modify the package.json file to start the project using our server.js

      {
        "scripts": {
          "test": "echo \"Error: no test specified\" && exit 1"."dev": "node server.js"."start": "NODE_ENV=production node server.js"."build": "next build",}}Copy the code

      Now we start the project and use the ngrok exposed domain name to see it

      Here also in the domain nameshopFill in our store address for example my own:

      https://e44132cd.ngrok.io/auth/inline?shop=jetbn.myshopify.com
      Copy the code

      After everything is filled in, the enter page will automatically jump.

      The last page shown:

Toss around other frames to try

I developed two or three applications using React next. Js, but I felt that it was too troublesome to develop. The pages displayed were all on Shopify’s own platform, and it was very slow to respond after the code was written. For this reason, I started to look for other solutions to see if I could get on top of it after I had developed it myself, and let the verification of Shopify’s series of operations be done by our back end guy. Finally, I selected Vue front-end and put the validation on the back end, so I could develop Vue items as usual.

The following is an introduction to my pure front-end Shopify validation operation using Vue. (The prerequisite element is Intranet penetration, but it is not needed during development)

  1. The installation application route was added

     {
        path: '/shopify/install',
        beforeEnter(to, _from, next) {
          if(to.query.shop) {// Add the developable store address after the domain name const shop = to.query.shop, scopes ='read_orders,read_products,write_products'// API permission // Redirect_uri = // API permission // Redirect_uri = // API permission // Redirect_uri ='https://' + process.env.VUE_APP_ROOT_URL + '/shopify/auth', // splitter install application address need SHOPIFY_API_KEY which I filled in my. Env file with install_URL ='http://' + shop + '/admin/oauth/authorize? client_id=' +
                    process.env.VUE_APP_SHOPIFY_API_KEY +
                    '&scope=' + scopes + '&redirect_uri='+ redirect_uri // local redirect installation address window.location = install_URL}else {
            next({ path: '/error'}}}}),Copy the code
  2. Redirection verifies the route

      {
        path: '/shopify/auth', beforeEnter(to, _FROM, next) {beforeEnter(to, _from, next) {const shop = to.query.shop, hmac = to.query.hmac, Code = to.query.code // Validate with SHOPIFY_API_SECRET_KEY and then fetch access_token.if (shop && hmac && code) {
            const map = Object.assign({}, to.query)
            delete map['signature']
            delete map['hmac']
            const message = querystring.stringify(map)
            const encrypted =
              crypto.createHmac('sha256', process.env.VUE_APP_SHOPIFY_API_SECRET_KEY)
                    .update(message)
                    .digest('hex')
            // const providedHmac =  Buffer.from(hmac, 'utf-8')
            // const generatedHash = Buffer.from(encrypted, 'utf-8')
    
            let hashEquals = false
    
            try {
              // later: Auth fails with `crypto.timingSafeEqual`
              // hashEquals = crypto.timingSafeEqual(generatedHash, providedHmac)
              hashEquals = hmac === encrypted
            } catch (e) {
              hashEquals = false
            }
    
            if (!hashEquals) {
              next({ path: '/error'})}else {
              next('/')}}else {
            next({ path: '/error'})}}}Copy the code

    Vue this verification scheme is also from Github above, specially recorded. The specific address forgot, have need oneself can search. 🤣

conclusion

After a period of familiarity, I also count and master a new thing. At the beginning, the Shopify plugin application development was really a huge pit. Although there was an official documentation process, it was all in English and the basic API was built with GraphQL. Then I tried all kinds of timeout operations by myself, so I abandoned it and used ResfulApi. I thought it was too difficult for me, so I had to go to the official documents to find it. Finally, I got familiar with all the ups and downs until now.

After that, I found that English proficiency is too important. Although the basic content of the development document can be understood, but it is half-guessing, and then translate a wave. (all kinds of inaccuracies), then start to make up English. 🤞

Finally, here are a few official document addresses that Shopify developers often use:

Shopify Partners(Create App View App): vue-composition-api-rfc.netlify.com

Shopify Developers(official developer documentation): developers.shopify.com

Shopify Polaris(official UI framework): developers.shopify.com