Shopify Storefront API. adding item to cart

Shopify Storefront API. adding item to cart

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?

Solutions/Answers:

Solution 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.

Related:  React relay pendingVariables always null after setVariables

Solution 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()
                        )
                )
        );
    

Related:  graphene graphql dictionary as a type

References