Reputation: 664
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?
Upvotes: 6
Views: 8324
Reputation: 440
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.
Upvotes: 0
Reputation: 776
I have implemented the shopify shop and cart using GraphQL provided by shopify . Follow these steps -
Storefront.CheckoutLineItemInput(quantity,new ID(productVariantId));
Don't be confused with productId with productVariantID . You need to use productVariantId hereNow 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()
)
)
)
)
);
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()
)
)
)
)
);
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()
)
)
)
);
Get the cardVaultURL -
Storefront.QueryRootQuery query = Storefront.query(rootQueryBuilder ->
rootQueryBuilder
.shop(shopQueryBuilder ->
shopQueryBuilder
.paymentSettings(paymentQueryBuilder -> paymentQueryBuilder
.cardVaultUrl()
)
)
);
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());
}
});
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()
)
)
);
Upvotes: 8
Reputation: 2395
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.
Upvotes: 9