Предположим, что мы хотим создать систему бронирования рейсов, которая использует внешний API, у нас есть эти шаги, чтобы получить билет
- поиск рейсов
- выбор рейсов
- отправьте данные пассажира
- если на нашем кошельке достаточно средств можете заказать билет
- если у нас нет билета go на банковский шлюз и в обратном вызове в случае успеха оплата зарядить кошелек , а затем отправить в API на забронировать билет
- В случае неудачного платежа мы показываем ошибку и больше ничего не нужно делать
Для шага 5 я использую ATlpay API в качестве банковского шлюза, они работают с GET Обратный вызов
Я создаю базу данных транзакций с этими полями
Id | api_id | amount | status | user_id
Auto Increment | atlpay transaction id | double | Enum('start' , 'failed' , 'success' ) | Auth::user()->id
* default status is start
Это сценарий отправки пользователя в банк Gateway
1.create transaction with price and user_id and status= 'start' as a default and return a transaction with id 7
1.A and set **callback url** for bank like my_site.com/transaction/callback/7
2.post request to bank to get a url
2.in successful request bank get us an url and atlpay_id like u3873873873873 that is unique
2.A we save this id to transaction $transaction->api_id = u3873873873873 ; $transaction->save();
3.redirect user to bank url like ( atlpay.com/transaction/u3873873873873)
4.after bank payment is complete bank redirect to our **callback url** that set in step 1.A
после перенаправления банка на my_site.com/transaction/callback/7, я получаю транзакцию $ для этого пользователя и этот идентификатор транзакции (в данном примере - 7), если статус транзакции «старт»
и аф После этого я изменяю статус на Неудачный, на другой запрос не может попасть в эту транзакцию (Но я знаю, что это не гарантируется это требование! Я хочу найти наилучшую практику, чтобы только один запрос мог выполнить эту строку и другую строку после этого // ТОЛЬКО ОДИН ЗАПРОС ДОЛЖЕН достичь этого ++++
$transaction= Auth::user()->transactions()
->where('status' , 'start')
->where('id' , $id)
->first();
if(!$transaction)
dd("You are not The owner");
//ONLY ONE REQUEST MUST achieve this ++++
$transaction->status = 'failed';
$transaction->save();
$api_url = 'transactions/'.$transaction->api_id;
$payment_data = $this->get_transaction_payment_data($api_url);
if(is_success_payment($payment_data )
$this->charge_wallet($payment_data->price);
И моя функция charge_wallet равна
public function charge_wallet($price)
{
Wallet::where('user_id' , Auth::user()->id)->increment('amount', $price );
return true;
}