Creating (guest)checkout sessions with TRPC/Stripe/Zustand.

Hi! Just asking to see if this is a correct approach

I am managing carts using Zustand since it is just a simple side feature of the website where they sell some merchandising. Since customers can order as a guest, I am creating a public createCheckout link function in my stripeRouter. If users have a account I will link the order to the user.

  createGuestCheckoutSession: publicProcedure
    .input(
      z.object({
        cart: z.array(
          z.object({
            id: z.string(),
            price: z.number(),
            image: z.string(),
            quantity: z.number().optional(),
          })
        ),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const { stripe, req } = ctx;

      const lineItems = input.cart.map((product) => ({
        price: product.id,
        quantity: product.quantity ?? 1,
      }));

      const checkoutSession = await stripe.checkout.sessions.create({
        payment_method_types: ["card"],
        mode: "payment",
        line_items: lineItems,
        success_url: `${baseUrl}/shop?checkoutSuccess=true`,
        cancel_url: `${baseUrl}/shop?checkoutCanceled=true`,
      });

      if (!checkoutSession) {
        throw new Error("Could not create checkout session");
      }

      return { checkoutUrl: checkoutSession.url };
    }),
});


And then my checkoutButton creates the checkoutUrl:

const CheckoutButton = () => {
  const { mutateAsync: createCheckoutSession } =
    api.stripe.createGuestCheckoutSession.useMutation();
  const { push } = useRouter();
  const cart = useFromStore(useCartStore, (state) => state.cart);

  return (
    <button
      onClick={async () => {
        if (!cart) return;
        const { checkoutUrl } = await createCheckoutSession({ cart });

        if (checkoutUrl) {
          void push(checkoutUrl);
        }
      }}
    >
      Go to checkout
    </button>
  );
};


Is this fine?
Was this page helpful?