Problem/Motivation

The code in StripeWebformEventSubscriber::handleStripeWebhook is all broken, because it has stuff like this:

if (!empty($stripe_event['data']['object']['metadata']['webform_submission_id'])) {

But the event and $stripe_event->data are a StripeObject, not an array.

It should be

if (!empty($stripe_event->data->object->metadata->webform_submission_id)) {

$metadata is a StripeObject as well. So basically the whole function is broken.

See https://stripe.com/docs/webhooks#webhook-endpoint-integration

Steps to reproduce

Trigger stripe webhook events using Stripe CLI.

curl -s https://packages.stripe.dev/api/security/keypair/stripe-cli-gpg/public | gpg --dearmor | sudo tee /usr/share/keyrings/stripe.gpg
echo "deb [signed-by=/usr/share/keyrings/stripe.gpg] https://packages.stripe.dev/stripe-cli-debian-local stable main" | sudo tee -a /etc/apt/sources.list.d/stripe.list
sudo apt update
sudo apt install stripe
stripe login
stripe listen --forward-to mysite.example.com/stripe/webhook

In another bash window, run this:

stripe trigger checkout.session.completed

Proposed resolution

  public function handleStripeWebhook(StripeWebhookEvent $event) {
    $uuid = $this->config_factory->get('system.site')->get('uuid');
    $stripe_event = $event->getEvent();

    if (!empty($stripe_event->data->object->metadata->webform_submission_id)) {
      $metadata = $stripe_event->data->object->metadata;
    }
    elseif (!empty($stripe_event->data->object->customer)) {
      $customer = $stripe_event->data->object->customer;
      try {
        $customer = Customer::retrieve($customer);

        if (isset($customer->metadata->webform_submission_id)) {
          $metadata = $customer->metadata;
        }
      }
      catch (ApiErrorException $e) {
        $this->logger->error('Stripe API Error: ' . $e->getMessage());
      }
    }

    if (!empty($metadata) && !empty($metadata->uuid) && $metadata->uuid == $uuid) {
      $webform_submission_id = $metadata->webform_submission_id;

      $webform_submission = $this->entity_type_manager
        ->getStorage('webform_submission')->load($webform_submission_id);
      if ($webform_submission) {
        $webhook_event = new StripeWebformWebhookEvent($stripe_event->type, $webform_submission, $stripe_event);
        $this->event_dispatcher
          ->dispatch(StripeWebformWebhookEvent::EVENT_NAME, $webhook_event);
      }
    }

Remaining tasks

User interface changes

API changes

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

solideogloria created an issue. See original summary.

solideogloria’s picture

Issue summary: View changes
solideogloria’s picture

Issue summary: View changes
solideogloria’s picture

Issue summary: View changes
solideogloria’s picture

Issue summary: View changes
solideogloria’s picture

Issue summary: View changes

solideogloria’s picture

Status: Active » Needs review
solideogloria’s picture

Issue summary: View changes
solideogloria’s picture

Status: Needs review » Needs work

I'm setting this to Needs Work, because according to Stripe's support team, Checkout Sessions don't actually use the metadata property, so any metadata set there during creation will not appear in the dashboard or response.

I do not intend to do more work on this as I'm not using this module.

heddn made their first commit to this issue’s fork.

  • heddn committed de7263fd on 2.x authored by solideogloria
    Issue #3346325 by solideogloria, heddn: handleStripeWebhook broken code
    
heddn’s picture

Status: Needs work » Fixed

Let's merge it anyway. Even slightly less broken code is better then completely broken code.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.