medusajs / nextjs-starter-medusa

A performant frontend ecommerce starter template with Next.js 14 and Medusa.
https://next.medusajs.com/
MIT License
1.61k stars 431 forks source link

checkout breaks when Paystack is the only payment provider #278

Open nathaniel1616 opened 6 months ago

nathaniel1616 commented 6 months ago

I am using medusa-paystack plugin at medusa. https://medusajs.com/plugins/medusa-payment-paystack

Checkout page works fine when there are two payment provider. When I select , paystack only as the only payment provider , I get this error at the backend

error: Error from Paystack API with status code 400: Invalid Email Address Passed Error: Error from Paystack API with status code 400: Invalid Email Address Passed at Paystack. (C:\Users\nat\medusa\my-medusa-store\node_modules\medusa-payment-paystack\dist\lib\paystack.js:121:35) at step (C:\Users\nat\medusa\my-medusa-store\node_modules\medusa-payment-paystack\dist\lib\paystack.js:33:23)

I found a similar issue solved on Stripe on issue here #261

I would like to see an implementation with paystack.

VariableVic commented 6 months ago

I don't know the specifics of your setup, but it looks like you're trying to initiate a Paystack payment when there's no email address available yet.

The solution will be similar to my Stripe example you mentioned.

When you have only one payment provider active, Medusa will select it by default when you check out. Make sure you're not trying to initiate e.g. PaystackPop.setup before the customer email and order amount are available. You might want to add specific conditions to the checkout flow to fit your use case.

ta4h1r commented 1 month ago

I have the same problem. createPaymentSessions() fails whenever Paystack is the only provider. I'm not sure why this is the case... it seems like a bug in the medusa-payment-paystack plugin? To workaround, I did the following in src/modules/checkout/templates/checkout-form/index.tsx

  // create payment sessions and get cart
  let cart = (await createPaymentSessions(cartId).then(
    (cart) => cart
  )) as CartWithCheckoutStep

  if (!cart) {
    // NB: If Paystack is the only provider, then payment session
    // will fail whenever the email is not provided.
    // Hence we get the cart without the payment session, 
    // which is to be created in a later render -
    // as soon as the email is available (e.g., when rendering 
    // the delivery checkout step).
    cart = (await getCart(cartId)) as CartWithCheckoutStep
    if (!cart) return null

It is clear that the bad request made to Paystack third-party, as reported by @nathaniel1616, causes createPaymentSessions() to fail.

In the API documentation, it is mentioned that

If there's only one payment session created, it will be selected by default. The creation of the payment session uses the payment provider and may require sending requests to third-party services.

However, it is not clear to me why the foregoing request to third-party only occurs when there is one provider and not when there are more providers. Is this what it means to "select by default"? @VariableVic is there any reasonable way to disable this default selection? Perhaps understanding this would make for a better fix than what I have provided.