Trouble Implementing Stripe
Hello, I just followed the changes made in this branch to try to implement stripe https://github.com/thedevdojo/wave/compare/main...magarrent:wave:stripe-integration I was going to use paddle but they rejected my application saying they don't support web scraping tools so now I'm attempting to integrate stripe into my application.
I believe I found a proper place for each piece of code, replacing and adding everything except for the changes to wave/src/Http/Controllers/WebhookController.php as this file does not exist anymore and I couldn't find an updated place to make the changes to. I setup my .env to use the new stripe integration but when I click on get started on a plan it shows the "Paddle Vendor ID is not set, please see the docs and learn how to setup billing." still. When I use an account that already has a plan set and try to switch plans, I get the attached error on the SubscriptionController.php. I didn't change that class though.
I know it could be a lot of different problems but I pushed the attempt at the integration to this branch of my repo: https://github.com/TonyWilly/PullNode-Wave/tree/stripe (I'm using tallstack theme) and if anyone has a chance to help me diagnose what may be the issue, I'd appreciate it tons! Thanks
[2023-06-07 20:33:47] local.ERROR: Attempt to read property "subscription_id" on null {"userId":2,"exception":"[object] (ErrorException(code: 0): Attempt to read property \"subscription_id\" on null at E:\\Projects\\PullNode\\PullNode-Wave\\wave\\src\\Http\\Controllers\\SubscriptionController.php:196)
[stacktrace]
#0 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Bootstrap\\HandleExceptions.php(270): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(2, 'Attempt to read...', 'E:\\\\Projects\\\\Pul...', 196)
#1 E:\\Projects\\PullNode\\PullNode-Wave\\wave\\src\\Http\\Controllers\\SubscriptionController.php(196): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}(2, 'Attempt to read...', 'E:\\\\Projects\\\\Pul...', 196)
#2 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Controller.php(54): Wave\\Http\\Controllers\\SubscriptionController->switchPlans(Object(Illuminate\\Http\\Request))
#3 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction('switchPlans', Array)
#4 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php(260): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Wave\\Http\\Controllers\\SubscriptionController), 'switchPlans')
#5 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php(205): Illuminate\\Routing\\Route->runController()
#6 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(798): Illuminate\\Routing\\Route->run()
#7 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#8 E:\\Projects\\PullNode\\PullNode-Wave\\wave\\src\\Http\\Middleware\\InstallMiddleware.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#9 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Wave\\Http\\Middleware\\InstallMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#10 E:\\Projects\\PullNode\\PullNode-Wave\\wave\\src\\Http\\Middleware\\WaveMiddleware.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#11 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Wave\\Http\\Middleware\\WaveMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#12 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Middleware\\SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#13 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#14 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Auth\\Middleware\\Authenticate.php(44): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#15 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Auth\\Middleware\\Authenticate->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#16 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#17 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#18 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\View\\Middleware\\ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#19 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#20 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Session\\Middleware\\StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#21 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Session\\Middleware\\StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest(Object(Illuminate\\Http\\Request), Object(Illuminate\\Session\\Store), Object(Closure))
#22 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#23 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#24 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#25 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Cookie\\Middleware\\EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#26 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#27 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#28 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(799): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#29 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(776): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#30 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(740): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#31 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(729): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#32 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(190): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#33 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#34 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\livewire\\livewire\\src\\DisableBrowserCache.php(19): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#35 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Livewire\\DisableBrowserCache->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#36 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#37 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#38 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#39 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#40 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#41 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#42 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#43 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#44 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#45 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#46 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Http\\Middleware\\HandleCors.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#47 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Http\\Middleware\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#48 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Http\\Middleware\\TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#49 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#50 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#51 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(165): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#52 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(134): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#53 E:\\Projects\\PullNode\\PullNode-Wave\\public\\index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#54 E:\\Projects\\PullNode\\PullNode-Wave\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\resources\\server.php(16): require_once('E:\\\\Projects\\\\Pul...')
#55 {main}
"}
Hi there,
As you are getting the 'Paddle Vendor ID is not set' message this indicates that you've not defined the CASHIER_VENDOR="stripe"
env variable in your .env
file.
I've just tested this with your stripe
branch and it seems to be working as expected after defining the correct Stripe env details:
## NEW STRIPE INTEGRATION
# CASHIER_VENDOR="paddle"
CASHIER_VENDOR="stripe"
CASHIER_STRIPE_CALCULATE_TAXES=FALSE
CASHIER_STRIPE_ALLOW_PROMO_CODES=TRUE
STRIPE_KEY="PUBLIC KEY"
STRIPE_SECRET="PRIVATE KEY"
## END NEW STRIPE INTEGRATION
Also make sure to edit your plans and change the plan ID to your Stripe plan ID.
Let me know how it goes!
Hey Bobby, thanks for your reply. I have my .env configured with this layout:
## NEW STRIPE INTEGRATION
# CASHIER_VENDOR="paddle"
CASHIER_VENDOR="stripe"
CASHIER_STRIPE_CALCULATE_TAXES=FALSE
CASHIER_STRIPE_ALLOW_PROMO_CODES=TRUE
STRIPE_KEY="pk_test_xxxxxx"
STRIPE_SECRET="sk_test_xxxxxx"
## END NEW STRIPE INTEGRATION
PADDLE_VENDOR_ID=
PADDLE_VENDOR_AUTH_CODE=
PADDLE_ENV=sandbox
(Replaced keys with x's) I also tried a re-cache of my config with php artisan config:clear and php artisan config:cache
I set up the plans on stripe and copied the "prod_xxx" ID's from stripe into my wave admin panel "Plan Id"s with no success. Hearing that my stripe integration worked for you is good to hear though. I'm wondering what could be different with my setup however... I just tried to use the live stripe mode with my live keys and products and still get the same "Paddle Vendor ID is not set" error. Maybe I'm copying over the wrong plan IDs? Lastly I tried to remove the
PADDLE_VENDOR_ID=
PADDLE_VENDOR_AUTH_CODE=
PADDLE_ENV=
from my .env incase it was persisting paddle but it didn't fix it so I put it back.
I appreciate the response and would love to hear any more ideas from yourself or anyone who has a suggestion!
Hi there,
The error indicates that you are somewhere still referencing the Paddle vendor, even if you put the wrong Stripe ID, the error should be different and not reference Paddle.
Which page does this happen on? If I try this on /pricing
this works for me as expected without any changes to the code.
Also, can you verify that you are using the Tallstack theme and that it is active via your Voyager admin?
I could suggest deleting the divs that are still referencing the Paddle vendor from your blade views, just to make sure that they are not getting in your way, eg the livewire/settings/plans.blade.php
file and the livewire/settings/subscription.blade.php
file.
Let me know how it goes!
Hey Bobby, I verified the tallstack theme is on and "/pricing" is giving the paddle result. I just bypassed the stripe check with if(true) in the plans.blade.php and subscription.blade.php and got the stripe checkout modal to pop up! So I'm thankful for this progress in debugging but now I just get "Something went wrong Please try again later. If the issue persists, you can contact our support team using the button below." on the stripe checkout modal. I checked my stripe developer logs and I'm not getting any succeeded or failed requests from the site. I'm wondering if this could be due to me not including the changes shown for wave/src/Http/Controllers/WebhookController.php on the stripe integration as wave/src/Http/Controllers/WebhookController.php doesn't exist in the latest version of wave or if it's another issue... Did you by any chance connect a stripe account to test or get to a proper form when checking out?
I'm maybe thinking it could be a .env issue overall and maybe my keys aren't being read properly like with the CASHIER_VENDOR and that's maybe why it wont connect properly..?
Here is the modal that shows for me:
To test the .env theory I replaced env('STRIPE_SECRET')s with just a string of my secret key and env('STRIPE_KEY') with my STRIPE_KEY as a string in the code and no difference.
Hey there!
For some reason, you are still reaching the Paddle checkout modal. As you are not going to be using Paddle, maybe it's best to get rid of all of the Paddle references from your blade views.
Yes, I've linked your codebase with a demo Stripe account that I have and it works out of the box, here is a quick demo:
Is your Wave installation running locally or on a remote server? If it is on a remote server, feel free to give me access to the server and I will be happy to take a look on what might be going on!
Hey Bobby, you are right I didn't even realize that it was a Paddle error showing up in the modal and not Stripe... I was previously testing this on my local development server but I pulled the 'stripe' branch from my repo to my production server to attempt setup and it gave me the same results.
I would appreciate you taking a look at the server and seeing if you could find what might be going on, thanks! I'll private message you log-in credentials shortly
Hey!
Just a quick update after our chat for anyone that might come across this in the future! The odd problem with the env variables was fixed after running:
php artisan optimize:clear
There are still a few more things that need to be polished but the Paddle error is no longer showing!
Yes, massive thanks to Bobby for finding the issue! For anyone who implements Stripe using this method, I also had to do the following to get things running smoothly (many steps also suggested by Bobby): Publish the cashier migrations:
- php artisan vendor:publish
- Scroll down to cashier-migrations and publish them
Remove duplicate database columns:
- Delete 'database/migrations/2019_05_03_000001_create_customer_columns.php' migration as it is not needed as those columns already exist in the users table.
- php atrisan migrate
Then I had to migrate 2 new columns into the user's table for payment type and last 4 digits of payment:
- php artisan make:migration add_pm_columns_to_users_table
- Edit up & down
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('pm_type')->nullable();
$table->string('pm_last_four')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('pm_type');
$table->dropColumn('pm_last_four');
});
}
- php artisan migrate
Next, if using laravel version > 6, '/wave/src/Http/Controllers/StripeController.php' needs to be updated so that any str_slug & str_random (possibly a few more str_) references are replaced with 'Str::', so 'Str::random(30)' for example. Finally, at 'wave/src/Http/Controllers/Auth/RegisterController.php' line 159, you should add a check if the username was set in registration before trying to set it again.
if(setting('auth.username_in_registration') && setting('auth.username_i>
$user->username = $request->username;
this check was already done earlier in the method but it still tries to set $user->username = $request->username; even if the username wasn't passed in the request, causing an error.
With these polishes and the support of Bobby I was able to successfully complete stripe transactions!
















Thank you so much for sharing those extra details here with the community! Happy to hear that it is working for you now!















