Problem with POST and REST-API

Highlighted
Tourist
9 1 4

Hello,

my name is Michael and I'm new here in this forum and new to Shopify and I'm having problems with any kind of POST to create, for example a new customer or an address, using the REST-API.

 

First I created a private App und the Apps section in the Shopify admin area. This gave me an API key, a password and a shared secret. Then I set the admin api permissions for 'Customer details and customer groups' to 'Read and Write'.

 

Next I wrote a javascript function to create a customer like this:

function createEntity(url, json) {
      fetch(url, {
        method: "POST",
        body: json,
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
      }).then(response => {
        if(!response.ok) {
          throw new Error('Network response was not ok.');
        }
        return response.text();
      })
      .then(data => {
        console.dir(data);
      })
      .catch(error => {
        console.error('There has been a problem with your fetch operation:', error);
      });
    }

where the url is 'https://{API key}:{Password}/admin/api/2020-04/customers.json and the payload is 

 

function createEmptyCustomerJson() {
      const customer = {
        "customer": {
          "first_name": "Steve",
          "last_name": "Lastnameson",
          "email": "steve.lastnameson@example.com",
          "phone": "+15142546011",
          "verified_email": true,
          "addresses": [
            {
              "address1": "123 Oak St",
              "city": "Ottawa",
              "province": "ON",
              "phone": "555-1212",
              "zip": "123 ABC",
              "last_name": "Lastnameson",
              "first_name": "Mother",
              "country": "CA"
            }
          ],
          "metafields": [
            {
              "key": "new",
              "value": "newvalue",
              "value_type": "string",
              "namespace": "global"
            }
          ]
        }
      }
      return JSON.stringify(customer);
    }

and as result I get:

 

There has been a problem with your fetch operation: TypeError: Failed to execute 'fetch' on 'Window': Request cannot be constructed from a URL that includes credentials: 

Then I removed the credentials from the url and moved them in the Authorization header like this:

function createCustomer() {
      const json = createEmptyCustomerJson();
      const url = "/admin/api/2020-04/customers.json";
      const base = btoa(key+":"+pw);
      createEntity(url, json, base);
    }

    function createEntity(url, json, base) {
      fetch(url, {
        method: "POST",
        body: json,
        headers: {
          'Authorization': 'Basic ' + base,
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
      }).then(response => {
        if(!response.ok) {
          throw new Error('Network response was not ok.');
        }
        return response.text();
      })
      .then(data => {
        console.dir(data);
      })
      .catch(error => {
        console.error('There has been a problem with your fetch operation:', error);
      });
    }

and the result in firefox is:

 

Angefragte Adresse:https://mircotestings.myshopify.com/admin/api/2020-04/customers.json
Anfragemethode:POST
Externe Adresse:23.227.38.64:443
Status-Code:
301
Version:HTTP/2
Referrer Policy:no-referrer-when-downgrade

Maybe someone knows what to do here, any help is appreciated.

Thanks in advance,

 

Michael

0 Likes
Highlighted
Shopify Partner
1166 32 213

@MichiBLN are you sending this POST from backend ?  Here is a similar thread https://community.shopify.com/c/Shopify-APIs-SDKs/Using-APIs-from-a-different-origin-domain/m-p/6056...

- Was my reply helpful? Click Like to let me know!
- Was your question answered? Click Accept as Solution
- Available for hiring. lixon@ecommercestudio.in
1 Like
Highlighted
Tourist
9 1 4

Hi @Lixon_Louis, thanks for your answer! You are right, I made the calls from the front end and I was wondering where to hide my credentials, but in the context of Shopify I don't know what the backend is.

 

Right now I just wrote a javascript file and referenced this in theme.liquid.

Is there a tutorial or something like this how to communicate between frontend and backend? And where can I find the backend?

 

Sorry I'm absolute beginner with Shopify.

0 Likes
Highlighted
Shopify Partner
1166 32 213

@MichiBLN  Refer https://shopify.dev/tutorials/build-a-shopify-app-with-node-and-express . Although deprecated, it gives you a rough idea on how to make API calls . Also refer https://shopify.dev/tutorials/authenticate-a-private-app-with-shopify-admin , because the private apps are already installed; there is a difference in authentication specified in step 5

 

Private apps can authenticate with Shopify by including the request header X-Shopify-Access-Token: {access_token}, where {access_token} is replaced by your private app's Admin API password.

 

- Was my reply helpful? Click Like to let me know!
- Was your question answered? Click Accept as Solution
- Available for hiring. lixon@ecommercestudio.in
1 Like
Highlighted
Tourist
9 1 4

Hello,

I made this https://shopify.dev/tutorials/build-a-shopify-app-with-node-and-express tutorial now and everything is working fine. I was also able to change the scope of the app to 

write_products,write_customers
and when I install the app it's shown in the confirmation dialog.
 
Like explained in the tutorial I can now make a request to 
https://5db43d41.ngrok.io/shopify?shop=<MYSHOP>
and it calls the App URL and the Whitelisted redirection URL and in the callback i can make one authenticated request to the REST admin API out of the callback.
 
But I'm still stuck here, because in my case i need to do more than just one request. so i tried to make another endpoint in my backend, which I call from postman with https://5db43d41.ngrok.io/shopify/get/customer?shop=<MYSHOP>.myshopify.com
 
app.get('/shopify/get/customer', (req, res) => {
    const shop = req.query.shop;
    console.log("received request for ", shop);
    const shopRequestUrl = 'https://' + shop + '/admin/api/2020-04/customers.json?updated_at_min=2020-04-05 14:35:21';
    const shopRequestHeaders = {
        'X-Shopify-Access-Token': accessToken,
    };
    console.log(accessToken);
    request.get(shopRequestUrl, { headers: shopRequestHeaders })
    .then((shopResponse) => {
        console.log('reponse', shopResponse);
        res.end(shopResponse);
    })
    .catch((error) => {
        console.log('erroe', error);
        res.status(error.statusCode).send(error);
    });
  });

where the accessToken looks like this:

{access_token: 'shpca_<SECRET>', scope: 'write_products,write_customers'}

and it's the same access token which i got from the callback, but in this case i always get a 401

StatusCodeError: 401 - "{\"errors\":\"[API] Invalid API key or access token (unrecognized login or wrong password)\"}"

I also tried it with:

https://www.npmjs.com/package/shopify-node-api 

and

https://www.npmjs.com/package/shopify-api-node 

 

but always the same error.

Having the access token it should be possible to make authenticated requests from the backend or am I wrong?

 

Thanks,

Michael

 

 

 

0 Likes
Highlighted
Shopify Partner
1166 32 213

Is that a private or custom app ? @MichiBLN 

 

Because for me private app's X-Shopify-Access-Token starts with shppa_  and shpss_ for custom apps. 

 

API secret key for custom apps and API password for Private apps. 

 

screenshot-nichegeek.myshopify.com-2020.05.20-12_27_51.pngscreenshot-partners.shopify.com-2020.05.20-12_26_39.png

 
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Click Accept as Solution
- Available for hiring. lixon@ecommercestudio.in
0 Likes
Highlighted
Tourist
9 1 4

@Lixon_Louis yes it's a custom app, sorry i forgot to mention it.

Right now i found a solution with several Whitelisted redirection URL(s) and redirecting to the appropriate Whitelisted redirection URL from the App URL, so I can handle different authenticated calls to the REST API now.

 

I'm not sure if that's the recommended way to go, but at least it works now.

0 Likes