Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PHP, Perl, Python Новый топик    Ответить
 Laravel 5.5 Braintree защита от повторных созданий подписки  [new]
alonecat
Member

Откуда:
Сообщений: 122
Всем привет!

Работаю над проектом с оплатой и подписками braintree.

Возник вопрос защиты от повторных запросов на подписку пользователя. Они возникают, например, если не блокировать кнопку submit при отправки формы. Если сохранять форму из разных табов/брузеров. Функция создания подписки состоит из двух частей - запрос к braintree на создании подписки и затем сохранение в БД подписки. За время запроса к braintree которое может быть до пару секунд возникает race_conditions когда первый запрос еще не сделал пользователя подписанным и за ним проходят еще несколько запросов.

Код создания подписки:
public function createSubscription($request)
{   

    if (isset($request['payment_method_nonce'])) {
        $gatewayCustomer = $this->findOrCreateCustomer();
        $this -> createPaymentMethod($request['payment_method_nonce'], $gatewayCustomer);
    }

    $trial_ends_at = isset($request['trial_ends_at']) ? $request['trial_ends_at'] : null;

    $plan = Plan::findOrFail($request["plan_id"]);


    if (!empty($this->defaultCard)) {
        $gatewaySubscription =  $this -> createGatewaySubscription($plan, $trial_ends_at);
    } 

    $subscription = $this->subscriptions()->create([
        'plan_id' => $plan->id,
        'trial_ends_at' => $trial_ends_at,
        'gateway_id' => isset($gatewaySubscription) ? $gatewaySubscription -> id : null,
        'card_id' => isset($this->defaultCard) ? $this->defaultCard->id : null,
    ]);
}

Также замечу, что пользователь может иметь только одну активную подписку одновременно.

Думаю в начале функции нужно записывать куда то время начале запроса. И при следующем запросе если с этого времени прошло скажем менее минуты отсекать повторный запрос. Пометку данную убирать в случае когда подписка успешно добавлена.

Думаю как лучше создавать такую метку. Через фасад Cache в памяти? Но надежно ли? Создать столбец типа locked_time в Users? Также через фасад Cache, но выбрать драйвер для кеша БД?
15 дек 17, 23:27    [21038536]     Ответить | Цитировать Сообщить модератору
 Re: Laravel 5.5 Braintree защита от повторных созданий подписки  [new]
alonecat
Member

Откуда:
Сообщений: 122
Вот что нашел

$sem = sem_get(1234, 1);
if (sem_acquire($sem)) {
    //successful lock, go ahead
    sem_release($sem);
} else {
    //Something went wrong...
}


Встроенную блокировку семафором в PHP
16 дек 17, 01:22    [21038698]     Ответить | Цитировать Сообщить модератору
 Re: Laravel 5.5 Braintree защита от повторных созданий подписки  [new]
Hett
Member

Откуда: Бийск, Новосибирск
Сообщений: 13254
Использовать транзакции?
16 дек 17, 08:18    [21038799]     Ответить | Цитировать Сообщить модератору
 Re: Laravel 5.5 Braintree защита от повторных созданий подписки  [new]
alonecat
Member

Откуда:
Сообщений: 122
Не причем... Запрос к БД один. И есть ещё запрос через API его то в транзакцию не запихнешь...
16 дек 17, 10:57    [21038896]     Ответить | Цитировать Сообщить модератору
Все форумы / PHP, Perl, Python Ответить