Skip to Content
Course content

194: Integrating Stripe Payments in PHP

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I worked with a developer named Marcus who was building a high-end membership site. He decided to build his own credit card intake form from scratch, thinking he could just send the card details to an API. He didn't realize that the moment a credit card number touches your server, you enter a world of pain called PCI Compliance. He spent three sleepless weekends trying to figure out why his server was failing security audits before I stepped in and told him, "Marcus, stop touching the card data. Let Stripe handle the risk."

That's the golden rule of modern payments: never actually see the credit card number if you can avoid it. We do this by using Stripe Checkout, which redirects the user to a secure, Stripe-hosted page. You don't have to worry about the layout, the security, or the validation; you just tell Stripe what the user is buying and where to send them when they're done.

Handing the User Off to Stripe Checkout

To get started, you'll need the Stripe PHP library installed via Composer. Once that's in place, the core of your integration is creating a Session. Think of a Session as a temporary "shopping cart" that Stripe manages. You define the price, the currency, and the product name, and Stripe gives you a unique URL.

 ['card'],
  'line_items' => [[
    'price_data' => [
      'currency' => 'usd',
      'product_data' => [
        'name' => 'Annual Pro Membership',
      ],
      'unit_amount' => 9900, // $99.00 (amount is in cents)
    ],
    'quantity' => 1,
  ]],
  'mode' => 'payment',
  'success_url' => 'https://your-site.com/success.php',
  'cancel_url' => 'https://your-site.com/cancel.php',
]);

header("HTTP/1.1 303 See Other");
header("Location: " . $session->url);

One thing that trips people up is the unit_amount. Stripe handles money in the smallest currency unit (cents for USD). If you put 99, you're charging the customer 99 cents, not 99 dollars. I've seen plenty of developers lose money on a launch day because they forgot to multiply their prices by 100.

Closing the Loop with Webhooks

Here is where most beginners make a critical mistake: they try to fulfill the order on the success_url page. Never do this. If a user closes their browser window after the payment is processed but before the redirect happens, your database will never know they paid. You'll have a customer who spent money but didn't get their product.

The solution is a Webhook. This is a script on your server that Stripe calls directly (server-to-server) to tell you, "Hey, payment pay_123 was successful." It's the only way to ensure your data stays consistent.

type == 'checkout.session.completed') {
    $session = $event->data->object;
    
    // Now you can safely update your database
    // Example: updateOrder($session->id, 'paid');
}

http_response_code(200);

Notice the constructEvent method. This is non-negotiable. Since this endpoint is public, anyone could send a fake "payment successful" request to your server. Verifying the signature ensures the request actually came from Stripe and wasn't spoofed by someone trying to get your product for free.




📋 Practical Task

Exercise: Building a Digital PDF Access Gateway

Your goal is to create a payment flow for a digital e-book. You need to implement two specific PHP files:

  1. checkout.php: This script should initiate a Stripe Checkout session for a "PHP Mastery E-book" priced at $25.00. It must redirect the user to the Stripe-hosted payment page.
  2. webhook_handler.php: This script must listen for the checkout.session.completed event. Instead of a real database, have this script write the Session ID and a timestamp to a local text file named orders.txt to prove the payment was captured.

Requirements:

  • Use the Stripe PHP SDK.
  • Implement signature verification in the webhook to prevent fake requests.
  • Ensure the unit_amount is correctly calculated in cents.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.