fix: finalize payments and clear cart after Paybox success
This captures the Paybox verification flow, duplicate-payment guard, and cart cleanup.
This commit is contained in:
@@ -3,13 +3,19 @@
|
||||
namespace App\Http\Controllers\Shop;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Repositories\Core\User\ShopCart;
|
||||
use App\Repositories\Shop\Paybox as PayboxGateway;
|
||||
use App\Repositories\Shop\Contents;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
|
||||
class PayboxController extends Controller
|
||||
{
|
||||
public function accepted()
|
||||
{
|
||||
ShopCart::clear();
|
||||
|
||||
return view('paybox.paybox', ['content' => Contents::getPayboxConfirmedContent()]);
|
||||
}
|
||||
|
||||
@@ -30,8 +36,20 @@ class PayboxController extends Controller
|
||||
|
||||
public function process(Request $request)
|
||||
{
|
||||
$data = $request->all();
|
||||
$invoiceId = $request->input('order_number');
|
||||
|
||||
return view('paybox.send', $data);
|
||||
if (! $invoiceId) {
|
||||
Log::warning('Paybox callback missing order_number', ['payload' => $request->all()]);
|
||||
|
||||
return response('Missing order_number', 400);
|
||||
}
|
||||
|
||||
$success = PayboxGateway::verifyPayment($invoiceId);
|
||||
|
||||
if (! $success) {
|
||||
return response('KO', 400);
|
||||
}
|
||||
|
||||
return response('OK');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
namespace App\Repositories\Shop;
|
||||
|
||||
use App\Models\Shop\Invoice;
|
||||
use App\Models\Shop\InvoicePayment;
|
||||
use App\Repositories\Core\DateTime;
|
||||
use Bnb\PayboxGateway\Requests\Paybox\AuthorizationWithCapture;
|
||||
use Bnb\PayboxGateway\Requests\PayboxDirect\Capture;
|
||||
use Bnb\PayboxGateway\Responses\Exceptions\InvalidSignature;
|
||||
use Bnb\PayboxGateway\Responses\Paybox\Verify;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Paybox
|
||||
@@ -23,17 +26,141 @@ class Paybox
|
||||
|
||||
public static function verifyPayment($invoiceId)
|
||||
{
|
||||
$invoice = Invoices::get($invoiceId);
|
||||
$invoice = Invoices::get($invoiceId, ['order']);
|
||||
|
||||
if (! $invoice) {
|
||||
Log::warning('Paybox callback received for unknown invoice', [
|
||||
'invoice_id' => $invoiceId,
|
||||
'payload' => request()->all(),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$payboxVerify = App::make(Verify::class);
|
||||
|
||||
try {
|
||||
$success = $payboxVerify->isSuccess($invoice->total_shipped);
|
||||
if ($success) {
|
||||
// process order here after making sure it was real payment
|
||||
}
|
||||
echo 'OK';
|
||||
$isSuccessful = $payboxVerify->isSuccess($invoice->total_shipped);
|
||||
} catch (InvalidSignature $e) {
|
||||
Log::alert('Invalid payment signature detected');
|
||||
Log::alert('Invalid payment signature detected', [
|
||||
'invoice_id' => $invoiceId,
|
||||
'payload' => request()->except('signature'),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $isSuccessful) {
|
||||
Log::warning('Paybox payment verification failed', [
|
||||
'invoice_id' => $invoiceId,
|
||||
'response_code' => $payboxVerify->getResponseCode(),
|
||||
'payload' => request()->except('signature'),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::finalizeInvoicePayment($invoice);
|
||||
}
|
||||
|
||||
protected static function finalizeInvoicePayment(Invoice $invoice)
|
||||
{
|
||||
$order = $invoice->order;
|
||||
|
||||
if (! $order) {
|
||||
Log::error('Paybox payment cannot be finalized: missing related order', [
|
||||
'invoice_id' => $invoice->id,
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$request = request();
|
||||
$referenceParts = array_filter([
|
||||
$request->input('call_number'),
|
||||
$request->input('transaction_number'),
|
||||
]);
|
||||
$reference = $referenceParts ? implode('-', $referenceParts) : $request->input('authorization_number');
|
||||
if (! $reference) {
|
||||
$reference = 'paybox-'.$invoice->id;
|
||||
}
|
||||
|
||||
$payload = $request->except('signature');
|
||||
$existingPayment = InvoicePayment::where('invoice_id', $invoice->id)
|
||||
->where('reference', $reference)
|
||||
->first();
|
||||
$shouldNotify = false;
|
||||
$validatedTotal = InvoicePayment::where('invoice_id', $invoice->id)
|
||||
->validated()
|
||||
->sum('amount');
|
||||
|
||||
if (! $existingPayment && (float) $validatedTotal >= (float) $invoice->total_shipped) {
|
||||
Log::info('Paybox payment ignored: invoice already fully settled', [
|
||||
'invoice_id' => $invoice->id,
|
||||
'order_id' => $order->id,
|
||||
'reference' => $reference,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($invoice, $order, $reference, $payload, $existingPayment, &$shouldNotify) {
|
||||
$attributes = [
|
||||
'payment_type' => 1,
|
||||
'amount' => $invoice->total_shipped,
|
||||
'date' => DateTime::getDate(),
|
||||
'data' => json_encode($payload, JSON_UNESCAPED_UNICODE),
|
||||
'validated' => 1,
|
||||
];
|
||||
|
||||
if ($existingPayment) {
|
||||
$previousValidationState = (int) ($existingPayment->validated ?? 0);
|
||||
$existingPayment->fill($attributes);
|
||||
|
||||
if ($existingPayment->isDirty()) {
|
||||
$existingPayment->save();
|
||||
}
|
||||
|
||||
if ($previousValidationState !== 1 && (int) $existingPayment->validated === 1) {
|
||||
$shouldNotify = true;
|
||||
}
|
||||
} else {
|
||||
InvoicePayment::create($attributes + [
|
||||
'invoice_id' => $invoice->id,
|
||||
'reference' => $reference,
|
||||
]);
|
||||
$shouldNotify = true;
|
||||
}
|
||||
|
||||
Invoices::checkPayments($invoice->id);
|
||||
|
||||
$paidStatus = Orders::getStatusByName('Préparation');
|
||||
if ($paidStatus !== '' && (int) $order->status !== (int) $paidStatus) {
|
||||
$order->status = $paidStatus;
|
||||
$order->save();
|
||||
}
|
||||
});
|
||||
|
||||
if ($shouldNotify) {
|
||||
try {
|
||||
OrderMails::sendOrderConfirmed($order->id);
|
||||
} catch (\Throwable $exception) {
|
||||
Log::error('Unable to send order confirmation email after Paybox payment', [
|
||||
'order_id' => $order->id,
|
||||
'invoice_id' => $invoice->id,
|
||||
'exception' => $exception->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Log::info('Paybox payment finalized successfully', [
|
||||
'invoice_id' => $invoice->id,
|
||||
'order_id' => $order->id,
|
||||
'reference' => $reference,
|
||||
'notified' => $shouldNotify,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getPreviousAuthorizedRequest($request)
|
||||
|
||||
Reference in New Issue
Block a user