calcom / cal.com

Scheduling infrastructure for absolutely everyone.
https://cal.com
Other
31.73k stars 7.72k forks source link

On Self-Hosted: Paid Booking Confirmation Email Not Received and Booking Status Not Updated #15294

Open safwanghamrawi opened 4 months ago

safwanghamrawi commented 4 months ago

I am using a self-hosted instance of Cal.com running on Vercel. The system works perfectly for free bookings, where I can book, update, and reschedule events, and I receive the confirmation email without any issues.

However, I am experiencing problems with paid bookings. Here is what happens:

I arrive at the payment page. I enter all the necessary payment information. I am redirected to the confirmation page. Despite this, I encounter two major issues:

I do not receive the confirmation email. The booking status is not marked as "paid" in the database. This issue does not occur with free bookings, which makes me think it might be related to the payment process or configuration.

Additional Information:

Cal.com version: 817a3dec

Hosting platform: Vercel

Payment provider: With Stripe

Questions:

What could be causing the confirmation email to not be sent for paid bookings? Why is the booking status not updated to "paid" in Cal.com? Are there any specific logs or settings I should check to diagnose this issue? Any help or guidance would be greatly appreciated. Thank you!

Checked the email settings to ensure they are correctly configured. Verified that the payment integration is correctly set up and processes payments successfully. Reviewed the Cal.com documentation for any additional steps or configurations needed for paid bookings. Checked my spam/junk folders to ensure the emails are not being filtered out. Compared the settings for free and paid event types to look for discrepancies. Install Sendgrid and Twilio for workflows

dosubot[bot] commented 4 months ago

Hey @safwanghamrawi! I'm here to help you with any bugs, questions, or contributions you might have. Let's work together to solve this issue.

The issues you're experiencing with paid bookings in your self-hosted instance of Cal.com running on Vercel with Stripe as the payment provider could be due to several factors. Here are some potential causes and steps to diagnose and resolve the problem:

  1. Payment Not Found: Ensure that the payment exists in the database and has a valid bookingId. The handleStripePaymentSuccess function checks for this and logs an error if the payment is not found.

    if (!payment?.bookingId) {
        log.error("Stripe: Payment Not Found", safeStringify(paymentIntent), safeStringify(payment));
        throw new HttpCode({ statusCode: 204, message: "Payment not found" });
    }
  2. Missing Stripe Signature: Verify that the stripe-signature header is included in the webhook request. If it is missing, the webhook handler will throw an HTTP 400 error.

    const sig = req.headers["stripe-signature"];
    if (!sig) {
        throw new HttpCode({ statusCode: 400, message: "Missing stripe-signature" });
    }
  3. Missing Stripe Webhook Secret: Ensure that the STRIPE_WEBHOOK_SECRET environment variable is set correctly. If it is missing, the webhook handler will throw an HTTP 500 error.

    if (!process.env.STRIPE_WEBHOOK_SECRET) {
        throw new HttpCode({ statusCode: 500, message: "Missing process.env.STRIPE_WEBHOOK_SECRET" });
    }
  4. Unhandled Stripe Webhook Event Type: Check if the webhook event type is handled by the webhookHandlers object. If not, it will throw an HTTP 202 error.

    const handler = webhookHandlers[event.type];
    if (handler) {
        await handler(event);
    } else {
        throw new HttpCode({
            statusCode: 202,
            message: `Unhandled Stripe Webhook event type ${event.type}`,
        });
    }
  5. Error Handling: Any other errors during the webhook processing are caught and logged. Ensure that no other errors are occurring.

    } catch (_err) {
        const err = getErrorFromUnknown(_err);
        console.error(`Webhook Error: ${err.message}`);
        res.status(err.statusCode ?? 500).send({
            message: err.message,
            stack: IS_PRODUCTION ? undefined : err.stack,
        });
        return;
    }

Additionally, the handlePaymentSuccess function in packages/lib/payment/handlePaymentSuccess.ts is responsible for updating the booking status and sending confirmation emails. Here are some potential issues related to this function:

  1. Booking Status Update: The function updates the booking status to "ACCEPTED" and marks it as paid.

    const bookingData: Prisma.BookingUpdateInput = {
        paid: true,
        status: BookingStatus.ACCEPTED,
    };
  2. Confirmation Handling: If the booking requires confirmation, the status update is skipped.

    const requiresConfirmation = doesBookingRequireConfirmation({
        booking: {
            ...booking,
            eventType,
        },
    });
    
    if (requiresConfirmation) {
        delete bookingData.status;
    }
  3. Transaction Handling: Ensure that both the payment and booking updates are performed in a single transaction.

    await prisma.$transaction([paymentUpdate, bookingUpdate]);
  4. Email Sending Logic: The function sends scheduled emails if the booking is confirmed.

    if (!isConfirmed) {
        if (!requiresConfirmation) {
            await handleConfirmation({
                user: userWithCredentials,
                evt,
                prisma,
                bookingId: booking.id,
                booking,
                paid: true,
            });
        } else {
            await handleBookingRequested({
                evt,
                booking,
            });
            log.debug(`handling booking request for eventId ${eventType.id}`);
        }
    } else {
        await sendScheduledEmails({ ...evt });
    }

To resolve the issue, ensure that:

If all these conditions are met and the issue persists, further debugging may be required to identify any other potential issues in the webhook handling or confirmation logic [1][2][3].

To continue talking to Dosu, mention @dosu.

safwanghamrawi commented 4 months ago

@dosu Thanks a lot for all those informations, I will have a look and see if it works.

dosubot[bot] commented 4 months ago

You're welcome! If you run into any more issues or need further assistance, feel free to reach out. Good luck with your debugging!

To continue talking to Dosu, mention @dosu.

Deyvi-dev commented 2 months ago

@dosu I'm experiencing the same issue. The Stripe console doesn't show any payment_intents events on the host account. I noticed that in "cal.com/packages/app-store/stripepayment/lib/PaymentService.ts", when the code executes: const paymentIntent = await this.stripe.paymentIntents.create(params, { stripeAccount: this.credentials.stripe_user_id, }); The payment is created, but the payment_intents event doesn't occur on the host account. Instead, it happens on the user's account who installed the app through the Cal platform, so the webhook is not triggered.

Deyvi-dev commented 2 months ago

@safwanghamrawi Did you manage to solve the problem?