Get started with 33% off your first certification using code: 33OFFNEW

Handling SCA in Stripe with PHP SDK

4 min read
Published on 16th July 2024

With the rise of digital payments, security has become a paramount concern. The Strong Customer Authentication (SCA) requirement is part of the EU’s Payment Services Directive (PSD2) aimed at reducing fraud and making online payments more secure. For developers, integrating SCA into your payment systems is essential. Stripe, a popular payment processing platform, offers a PHP SDK to facilitate this integration. This article will guide you through handling Stripe SCA using the PHP SDK.

What is Strong Customer Authentication (SCA)?

Strong Customer Authentication (SCA) is a regulation under PSD2 requiring two-factor authentication for electronic payments. It involves validating transactions through at least two of the following:

  • Knowledge (something the user knows, like a password).
  • Possession (something the user has, like a phone).
  • Inherence (something the user is, like a fingerprint).

SCA aims to make online payments more secure and reduce fraud, but it also means that developers need to ensure their systems can handle these requirements.

Setting Up the Stripe PHP SDK

To get started with the Stripe PHP SDK, you'll need to install it and configure your environment. Here’s how:

  1. Install the Stripe PHP SDK:

    Use Composer to install the Stripe SDK:

    composer require stripe/stripe-php
    
  2. Set Up Your Environment:

    Ensure you have your Stripe API keys ready. You can find these in your Stripe Dashboard.

    Create a file named config.php to store your API key:

    <?php
    require 'vendor/autoload.php';
    
    \Stripe\Stripe::setApiKey('your-stripe-secret-key');
    ?>
    

Creating Payment Intents

Payment Intents are a central feature in Stripe’s API for handling SCA. A Payment Intent represents the process of collecting a payment from your customer.

Here’s how to create a Payment Intent in PHP:

  1. Create a Payment Intent:

    require 'config.php';
    
    $intent = \Stripe\PaymentIntent::create([
        'amount' => 1099, // Amount in cents
        'currency' => 'usd',
        'payment_method_types' => ['card'],
    ]);
    
    echo json_encode(['client_secret' => $intent->client_secret]);
    

    This code initializes a payment intent for $10.99. The client_secret returned will be used on the frontend to complete the payment process.

Handling SCA in the Frontend

The frontend will handle the interaction with the customer and trigger SCA when required. Stripe.js is the JavaScript library used to handle this.

  1. Include Stripe.js:

    <script src="https://js.stripe.com/v3/"></script>
    
  2. Create a Payment Form:

    <form id="payment-form">
      <div id="card-element"><!--Stripe.js injects the Card Element--></div>
      <button type="submit">Pay</button>
    </form>
    
  3. Handle Payment Submission:

    <script>
      var stripe = Stripe('your-publishable-key');
      var elements = stripe.elements();
      var card = elements.create('card');
      card.mount('#card-element');
    
      var form = document.getElementById('payment-form');
      form.addEventListener('submit', async function(event) {
        event.preventDefault();
    
        const { client_secret } = await fetch('/path-to-create-payment-intent', {
          method: 'POST',
        }).then(r => r.json());
    
        const { error, paymentIntent } = await stripe.confirmCardPayment(client_secret, {
          payment_method: {
            card: card,
            billing_details: {
              name: 'Customer Name',
            },
          },
        });
    
        if (error) {
          // Handle error
          console.error(error);
        } else if (paymentIntent.status === 'succeeded') {
          // Payment succeeded
          console.log('Payment succeeded');
        }
      });
    </script>
    

Confirming Payment Intents

Once the customer completes the authentication challenge, Stripe confirms the Payment Intent.

  1. Confirm Payment on the Server-Side:

    If you need to handle any additional logic on the server-side after the payment is confirmed, you can use webhooks to listen for the payment_intent.succeeded event.

    // Webhook handler
    require 'config.php';
    
    $payload = @file_get_contents('php://input');
    $event = null;
    
    try {
      $event = \Stripe\Event::constructFrom(json_decode($payload, true));
    } catch(\UnexpectedValueException $e) {
      http_response_code(400); // Invalid payload
      exit();
    }
    
    // Handle the event
    if ($event->type === 'payment_intent.succeeded') {
      $paymentIntent = $event->data->object; // contains a StripePaymentIntent
      // Fulfill the purchase, e.g. update the database, send emails, etc.
    }
    
    http_response_code(200); // Acknowledge receipt of the event
    

Testing Your Integration

Testing is crucial to ensure your integration works as expected. Stripe provides several test card numbers to simulate various scenarios, including SCA.

  1. Use Test Cards:

    • SCA-required test card: 4000 0025 0000 3155
    • SCA-passed test card: 4242 4242 4242 4242

    Use these cards in your testing environment to simulate SCA challenges and success responses.

  2. Simulate Webhook Events:

    Stripe CLI can be used to trigger webhook events locally for testing:

    stripe listen --forward-to localhost:8000/webhook
    

    This command listens for events and forwards them to your local webhook handler, allowing you to test your webhook integration.

Wrapping Up: Mastering Stripe SCA with PHP

Handling Stripe SCA using the PHP SDK involves creating Payment Intents, handling frontend interactions, and confirming payments. By integrating these components, you ensure your application is compliant with SCA requirements and provides a secure payment experience for your users.

For further details, refer to the official Stripe PHP documentation and the SCA migration guide.