Cashier-stripe: Extended methods not recognized by method_exists()

Created on 13 Mar 2017  路  7Comments  路  Source: laravel/cashier-stripe

I'm working with Cashier to create custom web hook listeners for Stripe. Following the documentation example:

 namespace App\Http\Controllers;

  use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;

 class WebhookController extends CashierController
 {
    /**
    * Handle a Stripe webhook.
    *
    * @param  array  $payload
    * @return Response
    */
     public function handleInvoicePaymentSucceeded($payload)
     {
         // Handle The Event
     }
 }

the handleInvoicePaymentSucceeded method is failing at this statement.

 if (method_exists($this, $method)) {
             return $this->{$method}($payload);
         } else {
             return $this->missingMethod();
         }

A user on Laracasts also detailed finding this: https://laracasts.com/discuss/channels/general-discussion/laravel-cashier-webhook-additional-functionality?page=0

I am using version 5.3, and Cashier is 7.0.7.

Most helpful comment

i have also had the same issue.

  1. Make sure you have used YOUR controller instead of default controller mentioned in docs.
Route::post(
    'stripe/webhook',
    // your controller here and NOT \Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook
    'WebhookController@handleWebhook'
);
  1. Add CASHIER_ENV=testing if you are on the stripe test environment

  2. if you are caching the config, clear the config and try by using artisan command php artisan config:clear

i was stuck on the 3rd one i had to clear the cache again. it is working now.

hope that helps.

All 7 comments

@christopherarter Where is your route pointed to for the webhook? You will need to make sure the route is pointed to YOUR controller and not the default stated in the docs. Your controller should extend the base.

With that said though, the first IF statement in that function makes it impossible to test webhooks when Stripe is in test mode. You can add the ENV var to get past the first check, but that second check will always fail with Stripe in test mode. The ID it's checking for is not real when you manually run a webhook test in the Stripe dashboard, so that comparison fails.

I ended up just overwriting this function in my own Controller to allow me to run those tests. That check may need to look for your key in the id as well as the 00000000000000 returned when running a manual webhook test. Not sure I would classify this as a bug, but more of a pain when testing via the dashboard.

@magnetion

Sorry, I should've mentioned that I used my own class to extend the base, I just referenced that portion of the docs to show what I was doing. As for the ENV setting, it's set correctly to "testing".

It's actually passing this statement just fine:

    $payload = json_decode($request->getContent(), true);
    if (! $this->isInTestingEnvironment() && ! $this->eventExistsOnStripe($payload['id'])) {
        return;
    }

But the method extension isn't working. It's not seeing the extended class and not passing the method_exists() statement. It fails here:

    if (method_exists($this, $method)) {
        return $this->{$method}($payload);
    } else {
        return $this->missingMethod();
    }

I ended up just stealing the method below used to parse the web hook name and send to appropriate method and created my own controller. Works great, but feels like a hack.

   public function handleWebHook(Request $request)
      {

          $method = 'handle'.studly_case(str_replace('.', '_', $request['type']));

          return $this->{$method}($request);
      }

i have also had the same issue.

  1. Make sure you have used YOUR controller instead of default controller mentioned in docs.
Route::post(
    'stripe/webhook',
    // your controller here and NOT \Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook
    'WebhookController@handleWebhook'
);
  1. Add CASHIER_ENV=testing if you are on the stripe test environment

  2. if you are caching the config, clear the config and try by using artisan command php artisan config:clear

i was stuck on the 3rd one i had to clear the cache again. it is working now.

hope that helps.

@shakee93

Thanks for your response. The method name was different, I just included the section of the docs to show what I was working on. In my code, it is indeed a different name. The ENV variable CASHIER_ENV is also set to testing. And, the config:clear was run to no effect.

The issue remains method_exists() returning false.

Its work great! @shakee93 Thanks

Thanks @shakee93 , finally beat my head through that wall with your env comment!

Yeah, you need to use your own controller instead.

Was this page helpful?
0 / 5 - 0 ratings