Shopify / js-buy-sdk

The JS Buy SDK is a lightweight library that allows you to build ecommerce into any website. It is based on Shopify's API and provides the ability to retrieve products and collections from your shop, add products to a cart, and checkout.
https://shopify.github.io/js-buy-sdk
MIT License
985 stars 261 forks source link

Subscriptions Api #854

Open MuhammadHadiofficial opened 3 years ago

MuhammadHadiofficial commented 3 years ago

Is there any update on subscriptions integration with js Buy SDK?

dkhole commented 2 years ago

Would also like to know this

arobbins commented 2 years ago

Need this as well!

arobbins commented 2 years ago

Hey everyone,

I figured this out using the Recharge Shopify app. https://apps.shopify.com/subscription-payments It requires a few steps, but it's working nicely for me.

For 3 years now I've been using the JS SDK to manage the cart in my headless setup (which has worked great). However I haven't been able to add subscription products. I'm guessing this is because the SDK is out of date. The workaround I found today is using the Storefront API directly. Specifically the Cart endpoint: https://shopify.dev/api/storefront/reference/cart/cart#fields-2021-10

Here's how it works:

First, you need to find your selling_plan_id from Recharge. This is the ID that represents a Recharge subscription. I'm finding this value by making a call to the /selling_plan_groups endpoint on the Recharge API https://developer.rechargepayments.com/v1-shopify#list-selling-plan-groups

public function get_products($request) {

    $api_domain = 'https://api.rechargeapps.com';
    $api_endpoint = '/selling_plan_groups';
    $token = 'your_recharge_token_goes_here';

    $response = wp_remote_request($api_domain . '/selling_plan_groups', [
        'headers' => [
            'X-Recharge-Access-Token' => $token
        ]
    ]);

    if (is_wp_error($response)) {
        return $response;
    }

    $body = wp_remote_retrieve_body($response);

    return json_decode($body)->selling_plan_groups;

}

This will return an array of "selling plan groups" which you'll need to loop through to find the selling_plan_id. I should also note that you'll need a Recharge API token before this will work. You can generate one within your Shopify Recharge app.

Once you have the selling_plan_id you'll need to hit the cartCreate mutation on the Storefront API. https://shopify.dev/api/storefront/reference/cart/cartcreate This basically mimics what we're doing using the JS SDK. Here's what my code looks like:

public function graph_query_create_cart() {
      return [
         "query" => 'mutation cartCreateMutation($cartInput: CartInput) {
            cartCreate(input: $cartInput) {
              cart {
                id
                checkoutUrl
                lines(first:10) {
                  edges {
                     node {
                        quantity
                        merchandise {
                          __typename
                          ... on ProductVariant {
                            id
                          }
                        }
                        sellingPlanAllocation {
                          sellingPlan {
                            id
                            name
                          }
                          priceAdjustments {
                            price {
                              amount
                            }
                            compareAtPrice {
                              amount
                            }
                            perDeliveryPrice {
                              amount
                            }
                          }
                        }                       
                     }
                   }
                }
              }
            }
          }',
         "variables" => [
            'cartInput' => [
               "lines" => [
                  [
                     "quantity" => 1,
                     "merchandiseId" => "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yMjIyMTk1MDgxMjIwOA==",
                     "sellingPlanId" => "Z2lkOi8vc2hvcGlmeS9TZWxsaW5nUGxhbi80NDc3MDkyMzI="
                  ]
               ]
            ]
         ]
      ];
   }

Shopify has a guide for doing this here: https://shopify.dev/custom-storefronts/products/subscriptions#create-a-cart-and-a-subscription-line-item

Within the query variables I'm passing the selling_plan_id as sellingPlanId. It looks different here compared to what's returned from Recharge because you need to format the value into a Storefront ID.

To do this, take your selling_plan_id and append it to this string: gid://shopify/SellingPlan/. It should look something like this:

gid://shopify/SellingPlan/447709232

Then, base64 encode it... which comes to: Z2lkOi8vc2hvcGlmeS9TZWxsaW5nUGxhbi80NDc3MDkyMzI=

The merchandiseId value is just the Shopify variantId base64 encoded in this format:

gid://shopify/ProductVariant/22221950812208

Once you make the cartCreate mutation you'll receive back a response with a checkoutUrl -- just like the JS SDK.

Boom you're done. This is using Shopify's native checkout page as well which is super cool.

MuhammadHadiofficial commented 2 years ago

@arobbins Will surely be giving it a go and get back on the discussion. Appreciate your detailed answer mate.

andruschka commented 2 years ago

Hey @arobbins - maybe you can help us out. We are currently moving our online shop from Shopify to NextJS + Storefront API and we have the problem that the recharge checkout does not work. We are about to try your solution but can not find the sellingPlan... Do you need to first add it somwhere through recharge or in shopify? I would really appreciate your help! Thanks in advance

raRaRa commented 2 years ago

Now that Shopify supports subscriptions (partly), can't we just query it directly with the storefront API:

{
  productByHandle(handle: "handle") {
    title
    sellingPlanGroups(first: 1) {
      edges {
        node {
          name
          sellingPlans(first: 3){
            edges {
              node {
                id
                name
                description
              }
            }
          }
        }
      }
    }
  }
}

What happens if we use the selling plan id as variant id, when adding item to the cart with the JS Buy SDK? E.g.:

    await storefrontClient.checkout.addLineItems(
          checkoutId,
          [
            {
              variantId,
              quantity,
            },
          ]
        );
varanshu-agrawal commented 2 years ago

My project is based on the technology Gatsby js + React js and using Shopify-buy to add products to cart. Can any anyone please let me know on how can I override the Shopify libraries to create graphql api for subscription functionality

hammadsaeedtp commented 2 years ago

Any leads on this, we cant do this directly from a frotend can we ?