skip to Main Content

Im using the Shopify storefront API to query for a list of products and add a selected item to the cart.

I am able to use API to list all the products, and returns the variantID for the product found

Here is the GraphQL query to return a product

{
  shop {
    name
    products(first: 1, query:"title=configurable-handmade-concrete-ball") {
      edges {
        cursor
        node {
          id
          title
          handle
          variants(first:1) {
            edges {
              node {
                id
                title
              }
            }
          }
        }
      }
    }
  }
}

and the result

{
  "data": {
    "shop": {
      "name": "VonageTest",
      "products": {
        "edges": [
          {
            "cursor": "eyJvZmZzZXQiOjF9",
            "node": {
              "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzEwNTU2MjYxNTE4",
              "title": "Configurable Handmade Concrete Ball",
              "handle": "configurable-handmade-concrete-ball",
              "variants": {
                "edges": [
                  {
                    "node": {
                      "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC80MDIwOTc1NjQzMA==",
                      "title": "Default Title"
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
}

In order to add items to the cart, you can make a POST request that contains the following

https://{store_name}.myshopify.com/cart/{variant_id}

performing this call using the variant_id from the graphQL response returns a 404. But if you get the variant_id from the page, you can inspect the xml page and use the variant_id there
This shows how that is done
https://help.shopify.com/themes/customization/cart/use-permalinks-to-preload-cart

so why does the variant_id from the storefront API different from the variant_id on the page?

3

Answers


  1. I just encountered the same problem and was finally able to track down the answer in the Shopify GraphQL docs – https://help.shopify.com/api/storefront-api/reference/scalar/id

    Basically, the id returned in Shopify GraphQL responses is a base64-encoded representation of the actual Shopify id. So if you base64-decode the variant id from the result you posted, the value is gid://shopify/ProductVariant/40209756430

    You would need to parse the numerical id from the end of that value and that would be the id that Shopify uses for all other APIs.

    Login or Signup to reply.
  2. I have implemented the shopify shop and cart using GraphQL provided by shopify . Follow these steps –

    1. Create Storefront.CheckoutCreateInput() object.
    2. Add lineItems to it – Storefront.CheckoutLineItemInput(quantity,new ID(productVariantId)); Don’t be confused with productId with productVariantID . You need to use productVariantId here
    3. Now you need to mutate line items on CheckoutCreateInput object –

      Storefront.MutationQuery query = Storefront.mutation(mutationQuery -> mutationQuery
              .checkoutCreate(checkoutCreateInputObject, createPayloadQuery -> createPayloadQuery
                      .checkout(checkoutQuery -> checkoutQuery
                              .webUrl()
                      )
                      .userErrors(userErrorQuery -> userErrorQuery
                              .field()
                              .message()
                      )
              )
      );
      

    You will get a checkout Id here , save it .

    4.Now you need to create Storefront.MailingAddressInput() , taking inputs from user (city , state , email , name etc).Then you need to update this mailing address on CheckoutCreateInput() object like this checkoutCreateInputObj.setShippingAddress() .

    5.Now you need to fetch Shipping Rates –

                Storefront.QueryRootQuery query = Storefront.query(rootQuery -> rootQuery
                .node(checkoutId, nodeQuery -> nodeQuery
                        .onCheckout(checkoutQuery -> checkoutQuery
                                .availableShippingRates(availableShippingRatesQuery -> availableShippingRatesQuery
                                        .ready()
                                        .shippingRates(shippingRateQuery -> shippingRateQuery
                                                .handle()
                                                .price()
                                                .title()
                                        )
                                )
                        )
                )
        );
    
    1. Fetch the total price user need to pay –

      Storefront.QueryRootQuery query = Storefront.query(rootQuery -> rootQuery
              .node(checkoutId, nodeQuery -> nodeQuery
                      .onCheckout(checkoutQuery -> checkoutQuery
                              .subtotalPrice()
                              .totalPrice()
                              .availableShippingRates(availableShippingRateQuery -> availableShippingRateQuery
                                  .ready()
                                      .shippingRates(shippingRateQuery -> shippingRateQuery
                                              .price()
                                      )
                              )
                      )
              )
      );
      
    2. Apply coupons if any –

      Storefront.MutationQuery query = Storefront.mutation(mutationQuery -> mutationQuery
              .checkoutDiscountCodeApply(couponCode,checkoutId,discountQuery -> discountQuery
                      .userErrors(userErrorQuery -> userErrorQuery
                              .message()
                              .field()
                      )
                      .checkout(checkoutQuery -> checkoutQuery
                              .webUrl()
                              .totalPrice()
                              .appliedGiftCards(giftCardQuery -> giftCardQuery
                                  .amountUsed()
                                      .balance()
                              )
                      )
              )
      );
      
    3. Get the cardVaultURL –

      Storefront.QueryRootQuery query = Storefront.query(rootQueryBuilder ->
              rootQueryBuilder
                      .shop(shopQueryBuilder ->
                              shopQueryBuilder
                                      .paymentSettings(paymentQueryBuilder -> paymentQueryBuilder
                                              .cardVaultUrl()
                                      )
                      )
      );
      
    4. Get the payment token –

      CardClient cardClient = new CardClient();
      CreditCard creditCard = CreditCard.builder()
              .firstName(firstName)
              .lastName(lastName)
              .number(cardNumber)
              .expireMonth(expiryMonth)
              .expireYear(expiryYear)
              .verificationCode(cvv)
              .build();
      

      cardClient.vault(creditCard, cardVaultURL).enqueue(new CreditCardVaultCall.Callback() {
      @Override public void onResponse(@NonNull String token) {
      // proceed to complete checkout with token
      paymentToken = token;
      }

          @Override public void onFailure(@NonNull IOException error) {
              // handle error
              Log.d("error occured are just ",error.toString());
          }
      });
      
    5. Charge amount –

      String idempotencyKey = UUID.randomUUID().toString();
          Storefront.CreditCardPaymentInput input = new Storefront.CreditCardPaymentInput(amount, idempotencyKey, billingAddress,
                  paymentToken);
      
      
      
          Storefront.MutationQuery query = Storefront.mutation(mutationQuery -> mutationQuery
                  .checkoutCompleteWithCreditCard(shopifyHandler.checkoutId, input, payloadQuery -> payloadQuery
                          .payment(paymentQuery -> paymentQuery
                                  .ready()
                                  .errorMessage()
                          )
                          .checkout(checkoutQuery -> checkoutQuery
                                  .ready()
                          )
                          .userErrors(userErrorQuery -> userErrorQuery
                                  .field()
                                  .message()
                          )
                  )
          );
      
    Login or Signup to reply.
  3. I have two utility functions that I’ve been using to flip back and forth between the gid and rest id:

    export const getRestIdFromGid = (gid) => {
      return gid.split("/")[gid.split("/").length - 1];
    }
    
    export const getGidFromRestId = (id, type) => {
      return `gid://shopify/${type}/${id}`
    }
    

    like previous posts mentioned your response is a base64 encoded version of the gid://shopify/ProductVariant/${id} so you’d have to add that decoding/encoding into these, I think the GraphQL library I’m using automatically decodes ids.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search