221 lines
7.7 KiB
PHP
221 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\PaymentTransaction;
|
|
use App\Models\ShoppingOrder;
|
|
use App\Models\ShoppingPayment;
|
|
use App\Services\MyLog;
|
|
use App\Services\Payment;
|
|
use App\Services\ShoppingUserService;
|
|
use App\Services\Util;
|
|
|
|
class PayoneController extends Controller
|
|
{
|
|
public function __construct() {}
|
|
|
|
public function paymentStatus()
|
|
{
|
|
|
|
$data = \Request::all();
|
|
// test para
|
|
|
|
/* $data = [
|
|
'key' => '698fb2555f8b2efc74f60b2121421f45',
|
|
'txaction' => 'paid',
|
|
'clearingtype' => 'wlt',
|
|
'userid' => '158723953',
|
|
'txid' => '321623031',
|
|
'price' => '89.00',
|
|
'param' => '1', //$this->shopping_order->id,
|
|
'reference' => '15c83aee2766c3',
|
|
];
|
|
|
|
*/
|
|
|
|
if (! isset($data['key']) || ! isset($data['param']) || ! isset($data['userid']) || ! isset($data['txid']) || ! isset($data['reference']) || ! isset($data['price'])) {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2001 App\Http\Controllers\Api\PayoneController::paymentStatus parameter incomplete',
|
|
$data
|
|
);
|
|
echo 'TSOK';
|
|
exit;
|
|
}
|
|
|
|
if ($data['key'] != config('payone.defaults.key')) {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2002 App\Http\Controllers\Api\PayoneController::paymentStatus Key error',
|
|
$data
|
|
);
|
|
echo 'TSOK';
|
|
exit;
|
|
}
|
|
|
|
$shopping_order = ShoppingOrder::find($data['param']);
|
|
if (! $shopping_order) {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2003 App\Http\Controllers\Api\PayoneController::paymentStatus ShoppingOrder not found:',
|
|
$data
|
|
);
|
|
echo 'TSOK';
|
|
exit;
|
|
}
|
|
|
|
$shopping_payment = ShoppingPayment::where('reference', $data['reference'])->first();
|
|
if (! $shopping_payment) {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2004 App\Http\Controllers\Api\PayoneController::paymentStatus ShoppingPayment not found',
|
|
$data
|
|
);
|
|
echo 'TSOK';
|
|
exit;
|
|
}
|
|
|
|
if ($shopping_payment->shopping_order_id != $shopping_order->id) {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2005 App\Http\Controllers\Api\PayoneController::paymentStatus ShoppingPayment no realation ShoppingOrder',
|
|
$data
|
|
);
|
|
echo 'TSOK';
|
|
exit;
|
|
}
|
|
|
|
$price = number_format((round($data['price'], 2) * 100), 0, '.', '');
|
|
$price_amount = number_format($shopping_payment->amount, 0, '.', '');
|
|
if ($price_amount != $price) {
|
|
$data['shopping_payment-amount'] = $price_amount;
|
|
$data['price-amount'] = $price;
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2006 App\Http\Controllers\Api\PayoneController::paymentStatus Price error',
|
|
$data
|
|
);
|
|
echo 'TSOK';
|
|
exit;
|
|
}
|
|
|
|
/* TODO -- need this? */
|
|
if ($shopping_payment->txaction == $data['txaction']) {
|
|
|
|
if ($data['txaction'] === 'paid' && $shopping_order->txaction === 'paid') {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2007 App\Http\Controllers\Api\PayoneController::paymentStatus same txaction - was already paid',
|
|
$data,
|
|
false
|
|
);
|
|
// was already paid
|
|
echo 'TSOK';
|
|
exit;
|
|
} else {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2007 App\Http\Controllers\Api\PayoneController::paymentStatus same txaction - show',
|
|
$data,
|
|
false
|
|
);
|
|
}
|
|
}
|
|
|
|
// create transaction
|
|
PaymentTransaction::create([
|
|
'shopping_payment_id' => $shopping_payment->id,
|
|
'request' => 'transaction',
|
|
'txid' => $data['txid'],
|
|
'userid' => $data['userid'],
|
|
'status' => 'PAYONE',
|
|
'key' => $data['key'],
|
|
'txaction' => $data['txaction'],
|
|
'transmitted_data' => Util::utf8ize($data),
|
|
'mode' => $data['mode'],
|
|
]);
|
|
|
|
// Define txaction priority (higher number = higher priority)
|
|
$txaction_priority = [
|
|
'appointed' => 1,
|
|
'pending' => 2,
|
|
'failed' => 3,
|
|
'paid' => 10, // highest priority - final state
|
|
];
|
|
|
|
$current_priority = isset($txaction_priority[$shopping_order->txaction]) ? $txaction_priority[$shopping_order->txaction] : 0;
|
|
$new_priority = isset($txaction_priority[$data['txaction']]) ? $txaction_priority[$data['txaction']] : 0;
|
|
|
|
// Only update txaction if new priority is higher than current
|
|
if ($new_priority > $current_priority) {
|
|
$shopping_order->txaction = $data['txaction'];
|
|
$shopping_order->save();
|
|
$shopping_payment->txaction = $data['txaction'];
|
|
$shopping_payment->save();
|
|
} else {
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'info',
|
|
'App\Http\Controllers\Api\PayoneController::paymentStatus - txaction not updated (current: '.$shopping_order->txaction.' has higher/equal priority than new: '.$data['txaction'].')',
|
|
$data,
|
|
false
|
|
);
|
|
}
|
|
|
|
$send_link = false;
|
|
$send_mail = true;
|
|
if ($data['txaction'] === 'failed') {
|
|
$shopping_order->setUserHistoryValue(['status' => 6]);
|
|
Util::setInstanceStatusByPayment($shopping_payment, 5);
|
|
}
|
|
if ($data['txaction'] === 'appointed') {
|
|
$shopping_order->setUserHistoryValue(['status' => 7]);
|
|
ShoppingUserService::snycOrdersByShoppingOrder($shopping_order);
|
|
Util::setInstanceStatusByPayment($shopping_payment, 4);
|
|
}
|
|
|
|
if ($data['txaction'] === 'paid') {
|
|
// Use DB transaction and row locking to prevent race conditions
|
|
\DB::beginTransaction();
|
|
try {
|
|
// Lock the shopping order row to prevent concurrent processing
|
|
$locked_order = ShoppingOrder::where('id', $shopping_order->id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
// Double-check if payment was already processed
|
|
if (! $locked_order->paid) {
|
|
$send_link = Payment::paymentStatusPaidAction($locked_order, true, $shopping_payment);
|
|
\DB::commit();
|
|
} else {
|
|
$send_mail = false;
|
|
\DB::commit();
|
|
}
|
|
} catch (\Exception $e) {
|
|
\DB::rollBack();
|
|
MyLog::writeLog(
|
|
'payone',
|
|
'error',
|
|
'Error:2008 App\Http\Controllers\Api\PayoneController::paymentStatus Transaction failed',
|
|
['error' => $e->getMessage(), 'data' => $data]
|
|
);
|
|
throw $e;
|
|
}
|
|
}
|
|
$data['send_link'] = $send_link;
|
|
if ($send_mail) {
|
|
Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
|
|
}
|
|
echo 'TSOK';
|
|
exit;
|
|
}
|
|
}
|