Я настраиваю небольшое приложение Slim 3, которое будет посредником при обработке веб-формы оплаты Stripe. Приложение Slim будет обрабатывать бизнес-логику c обращения к Stripe и проведения платежа, а также отправки данных о платеже в некоторые сторонние CRM / приложения.
Моя проблема во время тестирования заключается в том, что когда я делаю пробный платеж через платежную форму Stripe JS, приложение slim регистрирует 3 повторных запроса с интервалом в 1 секунду. Вот как выглядит логирование:
test@gmail.com Attempting to make payment 2020-04-27 05:34:39
test@gmail.com Attempting to make payment 2020-04-27 05:34:40
test@gmail.com Attempting to make payment 2020-04-27 05:34:41
test@gmail.com Payment success 2020-04-27 05:34:44
test@gmail.com Payment success 2020-04-27 05:34:45
test@gmail.com Payment success 2020-04-27 05:34:47
Это все от отдельной "оплаты" с использованием учетных данных Stripe Test.
Схема Slim достаточно проста с точки зрения маршрута, проходящего через запрос прямо в мой StripeController
класс. Класс StripeController
(в разработке) примет значения запроса и передаст его в Stripe API для проведения платежа.
Схема маршрута:
$this->post('/stripe-payment', 'StripeController:stripePayment');
Контроллер (раздет до предметов первой необходимости):
class StripeController extends Controller
{
private $privateKey;
private $httpClient;
public function __construct() {
$this->privateKey = getenv('STRIPE_KEY');
$this->httpClient = new Client();
\Stripe\Stripe::setApiKey($this->privateKey);
}
//
public function stripePayment($request, $response)
{
// Get the request body
$r = (object)$request->getParsedBody();
// Initial Logging
$log = new LogController($r->email_address, 'Attempting to make payment');
$log->saveLog();
// Attempt to find an existing user
$user = User::where('email', $r->email_address)->first();
if($user !== null) {
// If user exists, use their StripeID
$invoice = $this->stripeInvoice($r, $user->stripe_id);
// Log the transaction
$this->savePayment( $user->id, 'stripe-invoice', $invoice->id, $invoice->amount_paid );
// Third party application push
$this->pushUser($r, $invoice->amount_paid);
// Return with success
return $response->withRedirect('example.com/payment-success/');
} else {
// Same as above, just create a user then push.
}
}
public function stripeInvoice(object $r, string $stripe_id)
{
// Try to create the invoice in stripe
try {
\Stripe\InvoiceItem::create([
'customer' => $stripe_id,
'amount' => (int)$r->product,
'currency' => 'USD',
'description' => $plan_desc
]);
} catch ( Exception $e ) {
error_log('STRIPE_INVOICE_EXCEPTION: '.$e->getMessage());
}
// Try to charge the customer the invoice we just created
try {
$invoice = \Stripe\Invoice::create([
'customer' => $stripe_id
]);
$_get_invoice = \Stripe\Invoice::retrieve($invoice->id);
$_get_invoice->pay();
$success = 1;
// Use Stripe's library to make requests...
} catch(\Stripe\Exception\CardException $e) {
$error = $e->getMessage();
// Since it's a decline, \Stripe\Exception\CardException will be caught
} catch (\Stripe\Exception\RateLimitException $e) {
$error = $e->getMessage();
// Too many requests made to the API too quickly
} catch (\Stripe\Exception\InvalidRequestException $e) {
$error = $e->getMessage();
// Invalid parameters were supplied to Stripe's API
} catch (\Stripe\Exception\AuthenticationException $e) {
$error = $e->getMessage();
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
} catch (\Stripe\Exception\ApiConnectionException $e) {
$error = $e->getMessage();
// Network communication with Stripe failed
} catch (\Stripe\Exception\ApiErrorException $e) {
$error = $e->getMessage();
// Display a very generic error to the user, and maybe send
// yourself an email
} catch (Exception $e) {
// Something else happened, completely unrelated to Stripe
$error = $e->getMessage();
}
if($success != 1) {
return $response->withRedirect('example.com&error='.$error);
} else {
return $_get_invoice;
}
}
}
Есть ли что-нибудь, что Slim делать в фоновом режиме, как проверка источника, что может вызвать проблему дублирования?