Debugging/Testing stripe webhook calls to Laravel Spark - laravel

I am currently testing Stripe webhooks using the latest Laravel Spark. I've got a Stripe account working, meaning that I can add (fake) creditcards and charge subscriptions/single payments. Next, I am using a fake hook endpoint (ultrahook.com) to retrieve webhooks requests from Stripe.
My vanilla route file is from the Spark installation:
$router->post('/webhook/stripe', 'Settings\Billing\StripeWebhookController#handleWebhook');
And should handle all the webhooks fine. To test the webhooks, I checked the StripeWebhookController object and changed a method to log some info:
protected function handleInvoicePaymentSucceeded(array $payload)
{
Log::info('This is some useful handleInvoicePaymentSucceeded.');
}
However, nothing gets logged when I call run a Stripe test webhook of type: invoice.payment_succeeded.
I do see the request coming into the ultrahook console and it gets returned a 200. I can also copy paste the JSON Stripe test webhook and paste it into Postman after which it gets send to http://localhost:80/webhook/stripe ... again a 200 response but nothing logged.
Any advice?

Laravel Cashier instructs you to exclude the webhook routes from VerifyCsrfToken middleware as stated here:
https://laravel.com/docs/5.5/billing#handling-stripe-webhooks
Spark uses Cashier, I'd imagine you need to do the same then.

Well, it appears that I needed to add
CASHIER_ENV=testing
in the env file. Nice to see that in the documentation Laravel... not

stripe webhooks don't call localhost, it should have a domain name to call.
you may use ultrahook gem for that..
it will create a temporary binding url which you can provide in stripe dashboard as callback url
like this
ultrahook stripe 80
which would give you an url that you map it in stripe dashboard
http://stripe.somename.ultrahook.com -> http://localhost:80
NOTE: You can access this url on a browser, it is just a virtual binding

Related

How to register on Jetstream via Postman (API)

First step: I am posting data via Postman on the api/reg
Second step: I am getting perfectly all the sent data
Third step: nothing lol, I can't get to this 3rd step, what to do to send this data to database how Jetstream does?
Somehow I found this CreateNewUser.php and via dd() I found out that my regular blade register information is coming to this point, but from where is it coming, and where is it going after is a mystery, There is no any information on the internet, so I am getting the register data (name,email...) in my Laravel project, somewhere AGAIN in my Laravel project there is some mechanism that upgrades (adds tokens etc...) and sends my data to database, how to connect that two things to each other? Thanks in advance
Jetstream is not intended to be used in this manner, if you want to expose an API you should use something like Laravel Sanctum or Laravel Passport. Sanctum is more lgihtwieght and has simpler workflow, Passport is heavier and provides a full oauth workflow which might be overkill in some scenarios. Both of these solutions use token authentication with Jetstream does not provide out of the box.
That said, to answer you question of how this all works.
Jetstream uses Laravel Fortify as its web authentication provider. It comes with a bunch of routes predefined, all of which you can see using php artisan route:list --compact. The route you're interested in is the POST /register route which is mapped to Laravel\Fortify\Http\Controllers\RegisteredUserController#store. When the registration form is submitted, the data is sent to that controller/method. The method expects two parameters, a Request object and a CreatesNewUsers object, both of which are injected by Laravels IoC service container.
The CreatesNewUsers object that is passed to the store method, is an instance of the CreateNewUser class you've found in App\Actions\Fortify which then performs the action of registering a new user. If you were to modify the structure of your User class, such as adding a phone number for example, you would need to edit CreateNewUser to include that new requirement if it was required when a user registers.
Here is a nice tutorial on how to Build a Restful API in PHP with Laravel Sanctum.

Laravel webhook always returning '401 unauthorized' errors in production environment when receiving events from Stripe

I am setting up a webhook in a Laravel project to receive events from stripe. When I configured stripe to send the webhook events to my local deployment of the website, everything worked fine. The webhook successfully handled all the sent events.
However, in the production environment, after setting up the webhook url in stripe, the url returns a 401 Unauthorized error.
After some testing, it looked like stripe always gets a 401 Unauthorized error no matter the url, even when trying a non-existing one.
I am not using any authentication mechanism for this route, so no auth:api middleware.

How to handle social login? - example flow

I have more conteptual question, how exactly should I handle social login in my project.
The use case is that I would like to allow user to login with Facebook, and keep on my backend information about this user (email, firstname, lastname)
I have some proposal Flow, but I'm not sure if it's a proper approach.
Let's say that I have application architecture as above. Now I would like to explain step-by-step full success flow.
Client (Vue application) make a call to AuthProvider (Facebook)
AuthProvider returns access_token
Client after reciving access_token make a call to backend endpoint like /fb_profile with access_token and userID (?)
Backend make a call to AuthProvider to check if given by client access_token is valid or not.
AuthProvider returns information about user. Backend after getting information about user, save it to database and generate new JWT token
Backend returns generated token to user
Now my question is - Is this good approach? Or should i handle it in other way? Like keep more logic to backend part? Instead of make a call to Facebook from Client, maybe should I make a call to backend, and backend make a call to Facebook?
You seem to be on right track. There could me many ways to do the same thing, here is the way which is working for me using vue/laravel/passport/socialite/github.
Trigger redirect in controller from frontend,
Provider(here github app) is triggered in browser with its url using client id/app name saved in back end config/env. Fill out your login details
It will redirect as created in provider and configured in backend-> show it on frontend, in my case its
http://localhost:8080/authorize/github/callback
From frontend now trigger callback in controller, it will check if user details already exist and will insert if its first time user as per logic. Then it will send back access_token to frontend which can be used in frontend for all the operations
DB
The above will be the sequence of the request flow ( same as yours ).
This would be the standard practice we used to integrate with Facebook. In this case, I strictly advise you to use the JavaScript SDK for Facebook.
Refer below link in case if you run into the following issue:
Vuejs component wait for facebook sdk to load

Redirecting to local post route

Short version
Do we need GuzzleHttp to redirect to local POST route? Can't we do this directly using redirect()?
Long version
Following this Laravel tutorial about using Passport authentication, the presenter talks about a way of hiding client_id to increase security (check at around 11:45 in the video).
The idea is to expose a new wrapper route that accepts only username and password fields and then the controller injects client_id on the server-side and makes a new call to Passport's original login route. This call is made using GuzzleHttp client. Response of the call is then returned by the wrapper route to the caller.
My question is: Do we really need to install and use Guzzle? Can't we redirect to Passport's login route using redirect() or some other built-in Laravel function?
You need Guzzle to make a HTTP request so that you can modify the response before sending it.
You will not be able to hide any data using redirect() because it will just tell the browser (client) to use the passport route directly.
To avoid making the HTTP a call you could get your route to run the code that the passport route runs and then modify the response that is generated. Making a local HTTP call should not be a problem though.

Laravel 5.4: how to protect api routes

I have a react app that fetch datas from laravel api defined like so in routes/api.php:
// this is default route provided by laravel out of the box
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
// ItemController provides an index methods that list items with json
Route::resource('items', 'Api\ItemController', array('except' => array('create','edit')));
// this is to store new users
Route::resource('users', 'Api\UserController', array('only' => array('store')));
for example http://example.com/api/items returns the data as intended but it's really insecure since anyone could access it through postman.
How to make those routes only accessible inside the app?
As I'm new to it I don't understand if I need to set up api_token and how?
Do I need to setup Passport?
Is is related to auth:api middleware?
It may sounds really basic but any help or tutorial suggestions would be greatly appreciated
EDIT
End up with a classic session auth. Moved routes inside web.php. Pass csrf token in ajax request. Actually i didn't need a RESTful API. You only need token auth when your API is stateless.
As you are using Laravel 5.4 you can use Passport, but I haven't implemented yet, but i implemented lucadegasperi/oauth2-server-laravel for one of my laravel projects and it was developed in Laravel 5.1
Here is the link to github repository
lucadegasperi/oauth2-server-laravel
Here is the link to the documentation Exrensive Documentation
Just add the package to the composer json and run composer update,the package will get installed to your application , once installed add the providers array class and aliases array class as mentioned in the Laravel 5 installation part of the documentation,
you have to do a small tweak in order to work perfectly cut csrf from $middleware array and paste it into $routeMiddleware array and again run php artisan vendor:publish after publishing the migrations will be created and run the migration php artisan migrate
if you only want to secure api routes for each client like ios, android and web you can implement Client Credentials Grant, or if you need to every user with oauth the you can implement Authorization Server with the Password Grant or some other.,
Never use the client id or other credentials, generating access token in the form, but add it some where in helper and attach it in the request to the api,
Hope this answer helps you.
You could use JWT it's pretty easy to get it to work. You basically generate a token by requesting Username/Password and passing that token in every request that requires authentication, your URL would look like http://example.com/api/items?token=SOME-TOKEN. without a proper token, he doesn't have access do this endpoint.
As for
How to make those routes only accessible inside the app?
If you mean only your app can use these requests, you can't. Basically the API doesn't know who is sending these requests, he can only check if what you are giving is correct and proceed with it if everything is in order. I'd suggest you to have a look at this question

Resources