Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

sulaimanMisri's avatar

Run code after return in Controller

Hi, I would like to know how can I run my code after the Laravel return something.

I'm building a payment function.

Here's my code.

// 1st : Initialize BillPlz details
$bill = $bill->create(
 'PutUniqueCodeHere',
 $user->email,
 $user->parents->phone_code . $user->parents->contact_number,
 $user->name,
 MYR::given($request->amount * 100),
 url('/parents/invoices'),
 'Payment testing',
 ['redirect_url' => route('parents.invoices.show', ['invoice' => $selectedInvoice->id])]
);

// 2nd : After the user clicks to pay, go to BillPlz payment and redirect to this URL.
return redirect($bill->toArray()['url']);

// 3rd : change invoice status from draft to complete.
 Invoice::where('id', $selectedInvoice->id)->update([
   'status' => 'complete'
 ]);

Right now, If I run this code, the 1st and 2nd flows are okay. But not the 3rd flow.

And If I change the 3rd flow to the 2nd, there will have a problem. Which is if the user decided not to pay after click the button, the invoice status will change from Draft to Complete.

So what I can think right now is to run the code (change Invoice status logic) on the 3rd flow. But I need to use the return statement on 2nd flow.

Any advice?

0 likes
10 replies
Niush's avatar
Niush
Best Answer
Level 50

I haven't use Billplz, but looking at the example, what you could do is, in the redirect_url use new route something like parents.invoices.validate, which will then check and change the status to complete.

If it is not complete show error page, or else redirect to show page normally.

sulaimanMisri's avatar

@Niush You mean whoever redirected to the parents.invoice.validate, the invoice status will be changed automatically?

Niush's avatar

@sulaimanMisri What you want to do here is use the BillPlz Callback URL feature. https://www.billplz.com/api#payment-completion

When, creating bill you are providing /parents/invoices/ as callback url. What you would instead want is a validator url instead (generally a webhook like /parents/invoices/validate).

Then, when the webhook has body with correct id and paid = true, (see the documentation) you can update the invoice status to complete. Then the redirect_url will normally return back to your website, hopefully with webhook already triggered.

1 like
sulaimanMisri's avatar

@Niush Yes, I've done it. Thank you so much for giving me an idea how to solve this :)

kevinbui's avatar

This is a perfect use case for dispatchAfterResponse. You might try something like:

$invoice = Invoice::findOrFail($selectedInvoice->id);

dispatch(function () use ($invoice) {
    $invoice->update(['status' => 'complete']);
})->afterResponse();
1 like
sulaimanMisri's avatar

@kevinbui Very true, I'm learning this function right now. I might change my current code and use this.

Snapey's avatar

you cannot put code after the return statement

you should redirect to the payment provider, and then have a separate endpoint that the payment provider returns the user to. Here you can record the transaction

1 like

Please or to participate in this conversation.