manishkatyan / strapi-stripe

Stripe Plugin for Strapi CMS
66 stars 33 forks source link

webhook url is not called after checkout #62

Closed Kazdan1994 closed 1 year ago

Kazdan1994 commented 1 year ago

Hey,

I'm currently working on a mentoring website. I sell offers inside using strapi-stripe

image

image

When I'm clicking on the button "Acheter", I'm calling this current fonction reimplement createCheckout

In src/api/stripe/controllers/stripe.js

async createCheckoutSession(ctx) {
    try {
      const {id} = ctx.request.body;

      const {stripePriceId, stripeProductId, title} = await strapi
        .query('plugin::strapi-stripe.ss-product')
        .findOne({
          select: ['stripePriceId', 'stripeProductId', 'title'], where: {id}
        });

      const checkoutSessionResponse = await strapi
        .service('api::stripe.stripe')
        .createCheckoutSession({
          stripePriceId,
          customerEmail: ctx.state.user.email,
          productId: stripeProductId,
          productName: title
        });

      ctx.send(checkoutSessionResponse, 200);
    } catch (e) {
      ctx.badRequest(e.message);
    }
  },

And service src/api/stripe/services/stripe.js

'use strict';

/**
 * stripe service.
 */

const {createCoreService} = require('@strapi/strapi').factories;

const Stripe = require('stripe');
const {ApplicationError} = require("@strapi/utils/lib/errors");

module.exports = createCoreService('api::stripe.stripe', ({strapi}) => ({
  async createCheckoutSession({stripePriceId, customerEmail, productId, productName}) {
    try {
      const stripeSettings = await strapi
        .plugin('strapi-stripe')
        .service('stripeService')
        .initialize();

      let stripe;

      if (stripeSettings.isLiveMode) {
        stripe = new Stripe(stripeSettings.stripeLiveSecKey);
      } else {
        stripe = new Stripe(stripeSettings.stripeTestSecKey);
      }

      const priceId = stripePriceId;
      const paymentMode = 'payment';

      return stripe.checkout.sessions.create({
        line_items: [
          {
            // Provide the exact Price ID (for example, pr_1234) of the product you want to sell
            price: priceId,
            quantity: 1,
          },
        ],
        mode: paymentMode,
        customer_email: customerEmail,
        payment_method_types: ['card'],
        success_url: `${stripeSettings.checkoutSuccessUrl}?sessionId={CHECKOUT_SESSION_ID}`,
        cancel_url: `${stripeSettings.checkoutCancelUrl}`,
        metadata: {
          productId: `${productId}`,
          productName: `${productName}`,
        },
      });
    } catch (error) {
      throw new ApplicationError(error.message);
    }
  },
}));

It pretty the same code you have, just change options and get better errors.

After the checkout page, user is redirect but the route I put there image

is not called.

Thank you for helping me. I'm trying now to investigate this error.

nishekh-e-r commented 1 year ago

Hi, @Kazdan1994

Currently, webhook URLs are invoked, whenever the stripe redirects to the Success URL page, we are invoking the savePayment() function, with the help custom script file that will be embedded in the HTML header section of the product list, payment success and payment failure pages.

path: src/plugins/strapi-stripe/server/controllers/stripeController.js

async savePayment(ctx) {
    const {
      txnDate,
      transactionId,
      isTxnSuccessful,
      txnMessage,
      txnAmount,
      customerName,
      customerEmail,
      stripeProduct,
    } = ctx.request.body;

    const savePaymentDetails = await strapi.query('plugin::strapi-stripe.ss-payment').create({
      data: {
        txnDate,
        transactionId,
        isTxnSuccessful,
        txnMessage: JSON.stringify(txnMessage),
        txnAmount,
        customerName,
        customerEmail,
        stripeProduct,
      },
      populate: true,
    });
    await strapi.plugin('strapi-stripe').service('stripeService').sendDataToCallbackUrl(txnMessage);
    return savePaymentDetails;
  },

and the callback URL function is in stripe service

path: src/plugins/strapi-stripe/server/services/stripeService.js
async sendDataToCallbackUrl(session) {
    try {
      const stripeSettings = await this.initialize();
      await axiosInstance.post(stripeSettings.callbackUrl, session);
    } catch (error) {
      throw new ApplicationError(error.message);
    }
  },

I hope this will help.

Kazdan1994 commented 1 year ago

Hey,

Thank you for your answer. Finally I had to reimplement retrieveCheckoutSession to add custom logic.

Have a nice day :)