From f9644fecefa73229a5384ee70f86499be48ff3fa Mon Sep 17 00:00:00 2001 From: cond0r Date: Fri, 24 Sep 2021 22:55:46 +0300 Subject: [PATCH] Shopify: create checkout on add to cart (#432) * Create checkout on add to cart * Checkout changes * Revert files * Fix checkout --- framework/bigcommerce/cart/use-add-item.tsx | 2 +- framework/shopify/cart/use-add-item.tsx | 61 ++++++++++-------- framework/shopify/cart/use-cart.tsx | 71 +++++++++++---------- framework/shopify/commerce.config.json | 3 +- framework/shopify/utils/checkout-create.ts | 28 +++++--- framework/shopify/utils/checkout-to-cart.ts | 5 +- 6 files changed, 97 insertions(+), 73 deletions(-) diff --git a/framework/bigcommerce/cart/use-add-item.tsx b/framework/bigcommerce/cart/use-add-item.tsx index 1ac6ac6f8..441d32775 100644 --- a/framework/bigcommerce/cart/use-add-item.tsx +++ b/framework/bigcommerce/cart/use-add-item.tsx @@ -41,4 +41,4 @@ export const handler: MutationHook = { [fetch, mutate] ) }, -} +} \ No newline at end of file diff --git a/framework/shopify/cart/use-add-item.tsx b/framework/shopify/cart/use-add-item.tsx index 5f0809d01..367f90e24 100644 --- a/framework/shopify/cart/use-add-item.tsx +++ b/framework/shopify/cart/use-add-item.tsx @@ -9,6 +9,7 @@ import { checkoutLineItemAddMutation, getCheckoutId, checkoutToCart, + checkoutCreate, } from '../utils' import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' @@ -28,34 +29,42 @@ export const handler: MutationHook = { }) } - const { checkoutLineItemsAdd } = await fetch< - Mutation, - MutationCheckoutLineItemsAddArgs - >({ - ...options, - variables: { - checkoutId: getCheckoutId(), - lineItems: [ - { - variantId: item.variantId, - quantity: item.quantity ?? 1, - }, - ], + const lineItems = [ + { + variantId: item.variantId, + quantity: item.quantity ?? 1, }, - }) + ] - return checkoutToCart(checkoutLineItemsAdd) - }, - useHook: ({ fetch }) => () => { - const { mutate } = useCart() + let checkoutId = getCheckoutId() - return useCallback( - async function addItem(input) { - const data = await fetch({ input }) - await mutate(data, false) - return data - }, - [fetch, mutate] - ) + if (!checkoutId) { + return checkoutToCart(await checkoutCreate(fetch, lineItems)) + } else { + const { checkoutLineItemsAdd } = await fetch< + Mutation, + MutationCheckoutLineItemsAddArgs + >({ + ...options, + variables: { + checkoutId, + lineItems, + }, + }) + return checkoutToCart(checkoutLineItemsAdd) + } }, + useHook: + ({ fetch }) => + () => { + const { mutate } = useCart() + return useCallback( + async function addItem(input) { + const data = await fetch({ input }) + await mutate(data, false) + return data + }, + [fetch, mutate] + ) + }, } diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index d920d058a..0b8c6657b 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -2,15 +2,15 @@ import { useMemo } from 'react' import useCommerceCart, { UseCart } from '@commerce/cart/use-cart' import { SWRHook } from '@commerce/utils/types' -import { checkoutCreate, checkoutToCart } from '../utils' +import { checkoutToCart } from '../utils' import getCheckoutQuery from '../utils/queries/get-checkout-query' import { GetCartHook } from '../types/cart' +import Cookies from 'js-cookie' import { - GetCheckoutQuery, - GetCheckoutQueryVariables, - CheckoutDetailsFragment, -} from '../schema' + SHOPIFY_CHECKOUT_ID_COOKIE, + SHOPIFY_CHECKOUT_URL_COOKIE, +} from '../const' export default useCommerceCart as UseCart @@ -18,40 +18,43 @@ export const handler: SWRHook = { fetchOptions: { query: getCheckoutQuery, }, - async fetcher({ input: { cartId: checkoutId }, options, fetch }) { - let checkout - - if (checkoutId) { - const data = await fetch({ + async fetcher({ input: { cartId }, options, fetch }) { + if (cartId) { + const { node: checkout } = await fetch({ ...options, variables: { - checkoutId: checkoutId, + checkoutId: cartId, }, }) - checkout = data.node + if (checkout?.completedAt) { + Cookies.remove(SHOPIFY_CHECKOUT_ID_COOKIE) + Cookies.remove(SHOPIFY_CHECKOUT_URL_COOKIE) + return null + } else { + return checkoutToCart({ + checkout, + }) + } } - - if (checkout?.completedAt || !checkoutId) { - checkout = await checkoutCreate(fetch) - } - - return checkoutToCart({ checkout }) + return null }, - useHook: ({ useData }) => (input) => { - const response = useData({ - swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, - }) - return useMemo( - () => - Object.create(response, { - isEmpty: { - get() { - return (response.data?.lineItems.length ?? 0) <= 0 + useHook: + ({ useData }) => + (input) => { + const response = useData({ + swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, + }) + return useMemo( + () => + Object.create(response, { + isEmpty: { + get() { + return (response.data?.lineItems.length ?? 0) <= 0 + }, + enumerable: true, }, - enumerable: true, - }, - }), - [response] - ) - }, + }), + [response] + ) + }, } diff --git a/framework/shopify/commerce.config.json b/framework/shopify/commerce.config.json index b30ab39d9..b194b629c 100644 --- a/framework/shopify/commerce.config.json +++ b/framework/shopify/commerce.config.json @@ -1,6 +1,7 @@ { "provider": "shopify", "features": { - "wishlist": false + "wishlist": false, + "customerAuth": true } } diff --git a/framework/shopify/utils/checkout-create.ts b/framework/shopify/utils/checkout-create.ts index 359d16315..36624ed05 100644 --- a/framework/shopify/utils/checkout-create.ts +++ b/framework/shopify/utils/checkout-create.ts @@ -7,27 +7,39 @@ import { } from '../const' import checkoutCreateMutation from './mutations/checkout-create' -import { CheckoutCreatePayload } from '../schema' +import { + CheckoutCreatePayload, + CheckoutLineItemInput, + Mutation, + MutationCheckoutCreateArgs, +} from '../schema' +import { FetcherOptions } from '@commerce/utils/types' export const checkoutCreate = async ( - fetch: any + fetch: (options: FetcherOptions) => Promise, + lineItems: CheckoutLineItemInput[] ): Promise => { - const data = await fetch({ + const { checkoutCreate } = await fetch({ query: checkoutCreateMutation, + variables: { + input: { lineItems }, + }, }) - const checkout = data.checkoutCreate?.checkout - const checkoutId = checkout?.id + const checkout = checkoutCreate?.checkout - if (checkoutId) { + if (checkout) { + const checkoutId = checkout?.id const options = { expires: SHOPIFY_COOKIE_EXPIRE, } Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) - Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout.webUrl, options) + if (checkout?.webUrl) { + Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout.webUrl, options) + } } - return checkout + return checkoutCreate! } export default checkoutCreate diff --git a/framework/shopify/utils/checkout-to-cart.ts b/framework/shopify/utils/checkout-to-cart.ts index e2531cc78..159cf0d7d 100644 --- a/framework/shopify/utils/checkout-to-cart.ts +++ b/framework/shopify/utils/checkout-to-cart.ts @@ -27,16 +27,15 @@ export type CheckoutPayload = | CheckoutQuery const checkoutToCart = (checkoutPayload?: Maybe): Cart => { - const checkout = checkoutPayload?.checkout throwUserErrors(checkoutPayload?.checkoutUserErrors) - if (!checkout) { + if (!checkoutPayload?.checkout) { throw new CommerceError({ message: 'Missing checkout object from response', }) } - return normalizeCart(checkout) + return normalizeCart(checkoutPayload?.checkout) } export default checkoutToCart