How to prevent BIN attack on a Laravel v11 Livewire-based checkout system?

I am currently facing a BIN attack on the checkout page of my web application, which is built using Laravel and Livewire. Fraudulent users (or bots) are attempting to perform card testing by using a series of invalid or stolen credit card numbers with similar BINs (Bank Identification Numbers). These repeated attempts are affecting my payment gateway and creating issues with legitimate transactions.

I want to implement a solution that will prevent these attacks by adding additional security layers to my checkout process.

Here’s what I’ve done so far:

  • I am using Laravel Livewire to handle form submissions for the checkout process.

  • Payments are processed using a third-party payment gateway(Stripe).

  • I have basic validation in place for form inputs, but this doesn’t seem to prevent the BIN attack.

I am looking for recommendations on how to prevent these attacks effectively.

Specifically, I want to:

  • Detect and block bots or malicious users performing rapid multiple transactions with invalid card details.
  • Rate-limit requests or add CAPTCHA where appropriate.
  • Implement better protection strategies like logging suspicious activities or blocking repeated failed transactions from the same IP address

this is what i used in livewire function:

     public function initializePayment()
        {
          $application = Application::findOrFail($this->applicationId);
    
           $stripe = new StripeClient(env('STRIPE_SECRET'));

    // Define line items for the Stripe session
    $lineItem = [
        [
            'price_data' => [
                'currency' => 'usd',
                'product_data' => [
                    'name' => 'Test Name', // Set the product name
                    'description' => "Description", // Set the product description
                    'images' => [asset('assets/images/1.jpeg')], // Add image URL
                ],
                'unit_amount' => 49 * 100, // Amount in cents
            ],
            'quantity' => 1,
        ],
    ];

    // Create a Stripe checkout session
    $stripeSession = $stripe->checkout->sessions->create([
        'payment_method_types' => ['card'],
        'line_items' => $lineItem,
        'mode' => 'payment',
        'metadata' => [
            'application_id' => $application->id,
            'application_number' => $application->application_number,
        ],
        'customer_email' => $this->email, // Optional: Prefill customer's email in the 
            payment form
        'payment_intent_data' => [
            'description' => "Payment for Application #{$application- 
               >application_number}",
            'metadata' => [
                'application_id' => $application->id,
                'application_number' => $application->application_number,
                'email' => $this->email,
                'phone' => $this->phone_number,
                'first_name' => $this->first_name,
                'last_name' => $this->last_name,
               ],
             ],
            'success_url' => route('stripe.success', [], true) . '?session_id= 
              {CHECKOUT_SESSION_ID}',
            'cancel_url' => route('stripe.cancel', [], true) . '?session_id= 
            {CHECKOUT_SESSION_ID}',
          ]);

         // redirect to stripe gateway
       return redirect()->away($stripeSession->url);
     }