Laravel mail automation - laravel

I'm developing an invoicing system in order to collect payments from customers. Once I create an invoice, an email including invoice details will be sent to the customers with payment link. I want to re-generate payment token(once it expires) and send renewed payment link to the customers, and want to automate the process.
I created a Job called renewingInvoiceLinks and inside the handle method, I wrote code to retrieve all invoices with expired links and create new token and send new link. In App->Console->Kernel.php scheduled the job as following. I referred Laravel Docs but did not get the flow properly to dispatch the Job.
protected function schedule(Schedule $schedule)
{
$schedule->job(new renewingInvoiceLinks, 'renewingInvoiceLinks')->daily();
}
Things I want to get clear.
Whether using Job to do the requirement is correct or not? If not what is the perfect way to do it.
How to dispatch the Job? (Where I need to call the dispatch method?)

I think the question is quite subjective and opinionated, but here is how I'd do it:
Whenever the payment link is updated, I would fire a custom PaymentLinkUpdated event. You can either fire this event in the place(s) where you update the link, or you listen for the saving event on the affected model and fire the PaymentLinkUpdated event only when the original value is different from the updated one.
A custom event listener will listen for the update of payment links and will send out the email containing the payment details and link. This event listener should be a queued one so that emails are sent in the background and do not block the UI.
A scheduled job will check for expired payment links and will update the affected records, casting a PaymentLinkUpdated event where necessary. This will trigger step 2 (which is automatically queued again).
This way, you'd have all the logic implemented only once and sending mails would not be duplicated. If you have to send a different mail when the payment link is renewed, you can either do so in the event listener or you have to change your strategy entirely.

Related

Save data through the controller after an event has been fired in laravel

I'm allowing a user to upload a post which includes an image and some related information as well as select the promotion fee[bronze,silver or gold].In my /post controller i'm validating the request and then sending a request to another API[third party api for performing payments].The API takes the user phone number and the promotion fee selected and does the payment transaction.So i made the Transaction model[used to save details concerning the completed transaction]to dispatch a created event since i want to save the other post related information only if the payment is successful.
I've tried to create the listener for the TransactionCreatedEvent but i can't find a way to pass the post related data into the listener in order to save them. I also tried to use the closure by calling the listen method on the Event Facade inside the post controller to no avail.
Mh, i'm not quite sure if i undestood you question correctly, but in you case, you could either relate the Transaction with the post, or pass the Transaction and the Post Model to any event or to a job, and then do whatever you want with the data in the event handler or job

Laravel Cashier (Stripe) - Checkout - invoice.paid & invoice.payment_failed events (webhooks)

When using Checkout Subscriptions, the Stripe documentation states that the minimum event types to monitor are:
checkout.session.completed - When you receive a checkout.session.completed event, you can provision the subscription.
invoice.paid - Sent each billing interval when a payment succeeds.
invoice.payment_failed -Sent each billing interval if there is an issue with your customer’s payment method.
When you receive a checkout.session.completed event, you can provision the subscription. Continue to provision each month (if billing monthly) as you receive invoice.paid events. If you receive an invoice.payment_failed event, notify your customer and send them to the customer portal to update their payment method.
https://stripe.com/docs/billing/subscriptions/checkout#provision-and-monitor
However, I am still confused about invoice.paid and invoice.payment_failed events and Laravel Cashier:
Do I need to make handlers for these two events?
I'm asking this because Cashier already handles customer.subscription.updated and customer.subscription.deleted events and, if I understood well (correct me if I'm wrong):
if the payment (for renewal of the subscription) is successful next month, then I will receive customer.subscription.updated and the subscription will continue being 'active': $user->subscribed('default') will be true (in subscriptions table stripe_status will remain active).
However, if the payment fails next month (for example, due to insufficient funds) - then customer.subscription.updated event will be triggered/sent and Cashier will change the subscription's status (to canceled or incomplete?) and $user->subscribed('default') will be false, right?
If so, then I see no reason why I should make handlers for invoice.paid and invoice.payment_failed events. I will know if the payment (renewal of the subscription) was successful because customer.subscription.updated event will be triggered/sent and Cashier will update thestripe_status in subscriptions table.
Or I'm wrong and it won’t work that way? If I didn't understand well, then I guess that customer.subscription.updated event will not be triggered/sent at all, or it will but it will not contain information if the payment (renewal of the subscription) was successful or not (and if it failed, then in handler method for the invoice.payment_failed event I will have to update the stripe_status (in subscriptions table) to canceled or incomplete?
Whether the subscription gets deleted or not after a failed invoice payment is up to your subscription settings: https://dashboard.stripe.com/settings/billing/automatic
As such it's possible to get a invoice.payment_failed event and not have the subscription be cancelled.
Since those events are very different it's safest to listen to all of them and handle accordingly. customer.subscription.updated and invoice.paid are also very different, the former will fire whenever any update to the subscription is made (e.g. if you update the metadata) whereas the latter will only fire specifically when an invoice payment succeeds.
It's ultimately up to you, but to ensure that you don't miss any important events you should consider listening to all the aforementioned events.

Facing issue with stripe failed payment webhook

I managing the failed payment webhook in my website but I am facing issue that invoice.payment_failed gets received before invoice.created which creating issue. Because on failed payment the system is updating the status of invoice but the invoice havnt been created becasue the invoice.created havent been called. I dont know what am I missing. I am using laravel ans spark for stripe management
Given the order of delivery for webhook events is not guaranteed, you have a couple options.
Create the record of the invoice in your system a soon as you receive a webhook notification for any new invoice ID.
When you receive a webhook notification, add it to a queue for processing, and process the queue in priority order where invoice.created events are processed first. You'll likely want to build in some sort of delay.

How to minimize axios posts with controller actions

I am creating an application with Laravel and VueJs. In this application a user can create an event. These events have participants. In my application the user fills out all of the event information and participants information and then clicks submit.
What I am looking for guidance on is how to best structure this in the backend. What I need to accomplish is the following:
create an event to the database
create participants
do an action based on the participants in the event (would happen in the event controller)
right now the way I have structured this is:
Send an axios post to create the event (EventController)
then send an axios post to create participants (ParticipantController)
then send another axios post to the event controller to do the last action (EventController)
this to me feels like way too many axios post calls, but I don't want to just put everything in one controller. Is there a better way to do what I am wanting to do while minimizing the number of axios calls?
if you need to create participants and perform particular action after event create then you can use laravel observers you can use it's created function to perform any action like after createing an event you have to make some enteries on participant table so you can perform those actions in that observer function.

Specifiy Stripe subscription start date using Laravel Cashier

I'm developing an application that uses Stripe, through Laravel Cashier to handle user subscriptions. When the user account is made, It has to be manually verified (has to be done this way due to the business logic) however the subscription starts immediately. Is there a way to pause the subscription, and only start it once each account has been verified? I'm using Laravel 5.
I think something like the following could work:
Create a boolean variable in your "users" table that you could call something like "verify_subscription".
Whenever a new user account is created, set "verify_subscription" to false.
Don't send the subscription off to Stripe (which will pause the subscription) while a new user has their "verify_subscription" set to false.
I can think of two different options at this point: Either create a confirmation email that gets sent to you (instead of or in addition to the user) where when you are ready to unpause the subscription you can click on that link for that particular user which will send the subscription off to Stripe and "unpause" their subscription OR you could create a route with a form where you can look up the user who you would like to unpause and simply search for that user, submit a form that gets processed which does the same thing (unpause the user by sending the subscription off to Stripe).
Hope that gives you some ideas to work with if you haven't already solved this issue!

Resources