I have a controller with functions to create and finish a Mollie payment. But I've got the idea that those functions are too big and do too many things. What I understand is that a function should do only 1 thing.
Any tips on how I can tidy this further up? Is it maybe a good moment to use events? Or are there any better solutions?
Note: creditBundles()
returns an array with possible packages/bundles which are currently for sale.
public function __construct()
{
$this->payment = Mollie::api()->payments();
}
public function createPayment(Request $request, $bundle)
{
$bundles = $this->creditBundles();
if (!array_key_exists($bundle, $bundles)) {
return redirect()->route('order.credits');
}
$order_id = time();
$bundle = $bundles[$bundle];
$payment = $this->payment->create([
"amount" => $bundle['price'],
"description" => $bundle['credits'] . " credits",
"redirectUrl" => route('order.credits.finish', ['order_id' => $order_id]),
"webhookUrl" => route('order.credits.webhook'),
"metadata" => ['order' => 'credits', 'order_id' => $order_id],
]);
CreditOrder::create([
'user_id' => auth()->user()->id,
'order_id' => $order_id,
'payment_id' => $payment->id,
'payment_status' => $payment->status,
'credits' => $bundle['credits'],
]);
return redirect($payment->getPaymentUrl());
}
public function finish(CreditOrder $order)
{
$user = auth()->user();
if ($order->user_id !== $user->id) {
return redirect()->route('order.credits');
}
$payment = $this->payment->get($order->payment_id);
if (!$payment->isPaid() || $order->payout) {
return view('order_status', [
'payment' => $payment,
'order' => $order,
]);
}
$user->increment('credits', $order->credits);
$order->payout = true;
$order->save();
notify()->flash('Thanks ' . escape($user->first_name) . '!', 'success', [
'text' => 'We received your payment and added ' . $order->credits . ' credits to your account!'
]);
return redirect()->route('home');
}