medusajs / medusa

The world's most flexible commerce platform.
https://medusajs.com
MIT License
26.08k stars 2.62k forks source link

Bug: payment.webhook_received unable to match payment_provider pp_stripe #9494

Open 420coupe opened 1 month ago

420coupe commented 1 month ago

Bug report

Describe the bug

The endpoint payment.webhook_received is failing to match payment provider with id pp_stripe. Order is still placed and considered successful, payment is captured in stripe however the webhook fails because it doesn't match pp_stripe to any provider.

System information

Medusa version (including plugins):@medusajs/medusa@2.0.0-rc-20241003153304 Node.js version: v21.7.1 Database: Supabase (postgres) Operating system: Ubuntu 22.04.4 Browser (if relevant):

Steps to reproduce the behavior

  1. Stand up new medusa backend with latest dev code (RC)
  2. create an order
  3. order goes through successfully, however stripe has 2 attempts to capture the same payment_intent and payment.webhook_received fails which is file packges/modules/payment/src/services/payment-provider
  4. See error

Expected behavior

Submit an order and correctly match to payment provider which i believe should be pp_stripe_stripe instead of pp_stripe

Screenshots

image image image

Code snippets

medusa-config.js

const { loadEnv, defineConfig, Modules } = require("@medusajs/framework/utils");

loadEnv(process.env.NODE_ENV, process.cwd());

module.exports = defineConfig({
  projectConfig: {
    databaseUrl: process.env.DATABASE_URL,
    http: {
      storeCors: process.env.STORE_CORS,
      adminCors: process.env.ADMIN_CORS,
      authCors: process.env.AUTH_CORS,
      jwtSecret: process.env.JWT_SECRET || "supersecret",
      cookieSecret: process.env.COOKIE_SECRET || "supersecret",
    },
  },
admin: {
    backendUrl: process.env.MEDUSA_BACKEND_URL,
    path: process.env.MEDUSA_ADMIN_PATH,
    },
  modules: {
    digitalProductModuleService: {
      resolve: "./modules/digital-product",
    },
    [Modules.FULFILLMENT]: {
      resolve: "@medusajs/medusa/fulfillment",
      options: {
        providers: [
          {
            resolve: "@medusajs/medusa/fulfillment-manual",
            id: "manual",
          },
          {
            resolve: "./modules/digital-product-fulfillment",
            id: "digital",
          },
        ],
      },
    },
    [Modules.NOTIFICATION]: {
      resolve: "@medusajs/medusa/notification",
      options: {
        providers: [
          {
            resolve: "@medusajs/medusa/notification-sendgrid",
            id: "sendgrid",
            options: {
              channels: ["email"],
              api_key: process.env.SENDGRID_API_KEY,
              from: process.env.SENDGRID_FROM,
            },
          },
        ],
      },
    },
    [Modules.PAYMENT]: {
      resolve: "@medusajs/medusa/payment",
      options: {
        providers: [
          {
            resolve: "@medusajs/medusa/payment-stripe",
            id: "stripe",
            options: {
              apiKey: process.env.STRIPE_API_KEY,
              automatic_payment_methods: true,
              capture: true,
            },
          },
        ],
      },
    },
    [Modules.FILE]: {
      resolve: "@medusajs/medusa/file",
      options: {
        providers: [
          {
            resolve: "@medusajs/medusa/file-s3",
            id: "s3",
            options: {
              file_url: process.env.SUPABASE_S3_FILE_URL,
              access_key_id: process.env.SUPABASE_S3_ACCESS_KEY,
              secret_access_key: process.env.SUPABASE_S3_SECRET_KEY,
              region: process.env.SUPABASE_S3_REGION,
              bucket: process.env.SUPABASE_S3_BUCKET,
              endpoint: process.env.SUPABASE_S3_ENDPOINT,
              prefix: process.env.SUPABASE_S3_PREFIX,
              additional_client_config: {
                forcePathStyle: true,
              },
            },
          },
        ],
      },
    },
  },
});
olivermrbl commented 1 month ago

@420coupe can you let me know what the provider ID of the payment is? As you say, this should be pp_stripe_stripe since you are using the standard credit card method.

CleanShot 2024-10-08 at 09 33 52

420coupe commented 1 month ago

@420coupe can you let me know what the provider ID of the payment is? As you say, this should be pp_stripe_stripe since you are using the standard credit card method.

CleanShot 2024-10-08 at 09 33 52

provider id in the db is pp_stripe_stripe image

I have also tried paymentElement vs CardElement and still getting the same results, two capture attempts and error matching coming back to the payment.webhook_received

420coupe commented 1 month ago

also something else i just noticed while digging in the db, status is never updated from authorized to capture in payment_collections nor payment_sessions

to add on this payment_session.data.status is never updated either, not sure if this is handled by the stripe_webhook return since i've never got it working.

renequez commented 2 weeks ago

@420coupe did you manage to figure out what's causing this? Or a workaround? I have the same problem and the order remains with an outstanding amount, even if the payment shows as captured.

420coupe commented 2 weeks ago

@420coupe did you manage to figure out what's causing this? Or a workaround? I have the same problem and the order remains with an outstanding amount, even if the payment shows as captured.

I did not, figured core team was on it from oliver responding.

RATIU5 commented 2 weeks ago

I've targeted the problem, going to try some things and create a PR if successful.

RATIU5 commented 2 weeks ago

The issue lies in this line of code (I think). For me, I changed it to this:

const providerId = `pp_${eventData.provider}_${eventData.provider.split("_")[0]}`;

And it works great. I forcefully changed the node_module file to the above line to fix, so it is a temporary fix. I am unsure if this breaks other code as I have not been able to test it fully yet.

MiguelFranken commented 2 weeks ago

I think this line might be correct as payment provider's providerid is defined as `pp{identifier}_{id}, where{id}is the provider'sidproperty in themedusa-config.ts`. See https://github.com/medusajs/medusa/blob/92bbd7953bf3413c649ad605960eac38dac6ee34/packages/core/utils/src/payment/abstract-payment-provider.ts#L113

I had similar issues today and I found out that you need to use the webhook AP Iroute localhost:9000/hooks/payment/stripe_stripe when you use the default "card" stripe provder service.

renequez commented 2 weeks ago

I can confirm changing the webhook url to {medusaUrl}/hooks/payment/stripe_stripe works fine 👌

420coupe commented 2 weeks ago

I can confirm changing the webhook url to {medusaUrl}/hooks/payment/stripe_stripe works fine 👌

so even with changing webhook to this, still get this error below when it tries to process.

info:    Processing payment.webhook_received which has 1 subscribers
error:   An error occurred while processing payment.webhook_received: TypeError [ERR_INVALID_ARG_TYPE]: The "key" argument must be of type string or an instance of ArrayBuffer, Buffer, TypedArray, DataView, KeyObject, or CryptoKey. Received undefined
http:    POST /hooks/payment/stripe_stripe ← - (200) - 4.817 ms 

edit: also there's still two capture attempts i can see in the stripe logs, still want to know what's causing this to try to collect twice on the payment_intent

420coupe commented 23 hours ago

Bump to get a resolution for this.