Stripe Checkout Integration in PHP

Stripe is the most popular payment gateway to accept credit card payments in the web application. The Stripe API provides a secure and powerful solution to integrate the checkout system on the website. You can allow the user to make payment directly from the website using their credit or debit card via the Stripe Prebuilt Checkout page.

The Stripe payment gateway can be easily integrated into the website to provide a user-friendly payment experience. Using Stripe checkout API and PHP, you can allow the user to make payment with credit cards without page refresh (leaving the website). In this tutorial, we will show you how to integrate Stripe checkout payment gateway and collect payment online using Stripe JavaScript API and PHP.

In this example code, we will integrate the Stripe checkout with the client-side and server-side process using PHP library and JavaScript API. We will integrate a custom payment process that allows you to trigger Checkout with any JavaScript event or HTML element. The following functionality will be implemented to demonstrate the Stripe checkout process in PHP using JavaScript API.

  • Display product details with a Pay Now button.
  • Create a checkout session with Stripe API and redirect to Stripe Checkout.
  • Redirect back to the website with the session ID.
  • Verify the transaction and insert payment data into the database.

Stripe Test API Keys

Before making the Stripe payment gateway live, the checkout process needs to be tested. Stripe Test API Keys Data allow checking the checkout process with test transactions. Follow the below steps to generate test API keys in the Stripe account.

  • Login to your Stripe account and navigate to the Developers » API keys page.
  • Under the TEST DATA section, you’ll see the Standard API keys (Publishable key and Secret key) are listed. To view the Secret key, click on the Reveal test key token button.
    stripe-developer-test-data-publishable-secret-api-keys-codexworld
  • Copy the Publishable key and Secret key for later use in the script.

Before getting started to integrate Stripe Checkout in PHP, take a look at the file structure.

stripe_checkout_with_php/
├── config.php
├── dbConnect.php
├── index.php
├── payment_init.php
├── payment-success.php
├── payment-cancel.php
├── stripe-php/
├── css/
│   └── style.css
└── images/

Create Database Table

A table is required to store the transaction data in the database. The following SQL creates a transactions table in the MySQL database.

CREATE TABLE `transactions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `customer_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `customer_email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `item_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `item_number` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `item_price` float(10,2) NOT NULL,
  `item_price_currency` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `paid_amount` float(10,2) NOT NULL,
  `paid_amount_currency` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `txn_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `payment_status` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
  `stripe_checkout_session_id` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Stripe API and Database Configuration (config.php)

In the config.php file, some constant variables are defined to specify the Stripe API and database settings.

Product Information:

  • $productName – Name of the product.
  • $productID – Product identification number.
  • $productPrice – Product price.
  • $currency – Currency code.

Stripe API Constants:

  • STRIPE_SECRET_KEY – Specify the API Secret key.
  • STRIPE_PUBLISHABLE_KEY – Specify the API Publishable key.
  • STRIPE_SUCCESS_URL – URL to redirect the customer after payment.
  • STRIPE_CANCEL_URL – URL to redirect the customer on payment cancellation.

Database Constants:

  • DB_HOST – Specify the database host.
  • DB_USERNAME – Specify the database username.
  • DB_PASSWORD – Specify the database password.
  • DB_NAME – Specify the database name.
<?php 

// Product Details 
// Minimum amount is $0.50 US 
$productName "Codex Demo Product"
$productID "12345"
$productPrice 55;
$currency "usd";
 
/*
 * Stripe API configuration
 * Remember to switch to your live publishable and secret key in production!
 * See your keys here: https://dashboard.stripe.com/account/apikeys
 */
define('STRIPE_SECRET_KEY''Stripe_API_Secret_Key');
define('STRIPE_PUBLISHABLE_KEY''Stripe_API_Publishable_Key');
define('STRIPE_SUCCESS_URL''https://example.com/payment-success.php'); //Payment success URL
define('STRIPE_CANCEL_URL''https://example.com/payment-cancel.php'); //Payment cancel URL
   
// Database configuration   
define('DB_HOST''MySQL_Database_Host');  
define('DB_USERNAME''MySQL_Database_Username');
define('DB_PASSWORD''MySQL_Database_Password');  
define('DB_NAME''MySQL_Database_Name');

?>

Note that: Stripe API Secret key and Publishable key will be found in the API Keys Data section of your Stripe account.

Database Connection (dbConnect.php)

The dbConnect.php file is used to connect the database using PHP and MySQL.

<?php   
// Connect with the database  
$db = new mysqli(DB_HOSTDB_USERNAMEDB_PASSWORDDB_NAME);  
  
// Display error if failed to connect  
if ($db->connect_errno) {  
    
printf("Connect failed: %s\n"$db->connect_error);  
    exit();  
}

Stripe Checkout Page (index.php)

Initially, the product details are displayed with a Pay Now button. Once this button is clicked, the user is redirected to the Stripe checkout page.

At first, include the configuration file.

<?php 
// Include configuration file  
require_once 'config.php'
?>

Product Info with Checkout Button:
The following code display product details on the web page with the custom Stripe checkout button.

  • Once the Pay Now button is clicked, a Checkout Session is generated with Stripe API and the user is redirected to the Stripe Checkout page.
  • If any error occurred during the Checkout Session creation, the message is displayed under the paymentResponse element.
<!-- Display errors returned by checkout session -->
<div id="paymentResponse" class="hidden"></div>
	
<!-- Product details -->
<h2><?php echo $productName?></h2>
<img src="images/product-image.png"/>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
<p>Price: <b>$<?php echo $productPrice.' '.strtoupper($currency); ?></b></p>

<!-- Payment button -->
<button class="stripe-button" id="payButton">
    <div class="spinner hidden" id="spinner"></div>
    <span id="buttonText">Pay Now</span>
</button>

Create Checkout Session and Redirect to Checkout:
Include the Stripe JS library (Stripe.js).

<!-- Stripe JavaScript library -->
<script src="https://js.stripe.com/v3/"></script>

The following JavaScript helps to create a Checkout Session and redirect the customer to the Stripe Checkout page.

  • Create an instance of the Stripe object and set the publishable API key.
  • Initialize session create request on CLICK event of the payment button.
    • When the Buy button is clicked, the createCheckoutSession() method is called to create Checkout Session and fetch session ID from the server-side.
  • The createCheckoutSession() function POST checkout session creation request to the server-side script (payment_init.php) using JavaScript fetch() method.
  • The handleResult() function is used to handle the errors during the checkout session creation via AJAX request.
  • If the Checkout Session creation is successful, the redirectToCheckout() method of the Stripe JS library is triggered to redirect to the Checkout page.
  • The setLoading() function is used to display a spinner on payment processing.
    • If set true, disable the payment button and show the loader.
    • If set false, enable the payment button and hide the loader.
  • The showMessage() function helps to display status messages.
<script>
// Set Stripe publishable key to initialize Stripe.js
const stripe = Stripe('<?php echo STRIPE_PUBLISHABLE_KEY?>');

// Select payment button
const payBtn = document.querySelector("#payButton");

// Payment request handler
payBtn.addEventListener("click", function (evt) {
    setLoading(true);

    createCheckoutSession().then(function (data) {
        if(data.sessionId){
            stripe.redirectToCheckout({
                sessionId: data.sessionId,
            }).then(handleResult);
        }else{
            handleResult(data);
        }
    });
});
    
// Create a Checkout Session with the selected product
const createCheckoutSession = function (stripe) {
    return fetch("payment_init.php", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            createCheckoutSession: 1,
        }),
    }).then(function (result) {
        return result.json();
    });
};

// Handle any errors returned from Checkout
const handleResult = function (result) {
    if (result.error) {
        showMessage(result.error.message);
    }
    
    setLoading(false);
};

// Show a spinner on payment processing
function setLoading(isLoading) {
    if (isLoading) {
        // Disable the button and show a spinner
        payBtn.disabled = true;
        document.querySelector("#spinner").classList.remove("hidden");
        document.querySelector("#buttonText").classList.add("hidden");
    } else {
        // Enable the button and hide spinner
        payBtn.disabled = false;
        document.querySelector("#spinner").classList.add("hidden");
        document.querySelector("#buttonText").classList.remove("hidden");
    }
}

// Display message
function showMessage(messageText) {
    const messageContainer = document.querySelector("#paymentResponse");
	
    messageContainer.classList.remove("hidden");
    messageContainer.textContent = messageText;
	
    setTimeout(function () {
        messageContainer.classList.add("hidden");
        messageContainer.textContent = "";
    }, 5000);
}
</script>

Stripe PHP Library

The Stripe PHP library provides an easy way to access the Stripe API and helps to process the card payment. You don’t need to download this library separately, all the required library files are included in our source code. Also, you don’t need to use the composer, this Stripe PHP Library will work without the composer.

Create Checkout Session (payment_init.php)

This file handles the Checkout Session creation process with the Stripe PHP SDK library.

  • Load the Stripe PHP SDK library.
  • Initialize Stripe client library and set API Secret key in StripeClient() method of the Stripe class.
  • Get the JSON request and decode with json_decode() function in PHP.
  • Validate the REQUEST sent by the AJAX from the client-side.
  • Create a new Checkout Session using create() method of Stripe Session API.
    • payment_method_types – Specify the types of payment methods this Checkout session can accept.
    • line_items.price_data.product_data – Specify the product details and generate a new product object.
    • line_items.price_data.unit_amount – Amount to charge.
    • line_items.price_data.currency – Three-letter ISO currency code in lowercase.
    • line_items.quantity – Quantity of the product.
    • mode – Mode of Checkout Session.
    • success_url – The URL to which Stripe should send the customer when the payment is completed.
    • cancel_url – The URL to which Stripe should send the customer when payment is cancelled.
  • Return JSON encoded response using json_encode() function in PHP.
<?php 

// Include the configuration file
require_once 'config.php';

// Include the Stripe PHP library
require_once 'stripe-php/init.php';

// Set API key
$stripe = new \Stripe\StripeClient(STRIPE_SECRET_KEY);

$response = array(
    
'status' => 0,
    
'error' => array(
        
'message' => 'Invalid Request!'   
    
)
);

if (
$_SERVER['REQUEST_METHOD'] == 'POST') {
    
$input file_get_contents('php://input');
    
$request json_decode($input);    
}

if (
json_last_error() !== JSON_ERROR_NONE) {
    
http_response_code(400);
    echo 
json_encode($response);
    exit;
}

if(!empty(
$request->createCheckoutSession)){
    
// Convert product price to cent
    
$stripeAmount round($productPrice*1002);

    
// Create new Checkout Session for the order
    
try {
        
$checkout_session $stripe->checkout->sessions->create([
            
'line_items' => [[
                
'price_data' => [
                    
'product_data' => [
                        
'name' => $productName,
                        
'metadata' => [
                            
'pro_id' => $productID
                        
]
                    ],
                    
'unit_amount' => $stripeAmount,
                    
'currency' => $currency,
                ],
                
'quantity' => 1
            
]],
            
'mode' => 'payment',
            
'success_url' => STRIPE_SUCCESS_URL.'?checkout_session_id={CHECKOUT_SESSION_ID}',
            
'cancel_url' => STRIPE_CANCEL_URL,
        ]);
    } catch(
Exception $e) { 
        
$api_error $e->getMessage(); 
    }
    
    if(empty(
$api_error) && $checkout_session){
        
$response = array(
            
'status' => 1,
            
'message' => 'Checkout Session created successfully!',
            
'sessionId' => $checkout_session->id
        
);
    }else{
        
$response = array(
            
'status' => 0,
            
'error' => array(
                
'message' => 'Checkout Session creation failed! '.$api_error   
            
)
        );
    }
}

// Return response
echo json_encode($response);

?>

Payment Success Page (payment-success.php)

Stripe will redirect the customer to the specified Success Page URL when the payment is completed.

  • Retrieve the Session ID from the query string of the URL using the PHP $_GET method.
  • Check whether the transaction data exist in the database with the same Session ID.
  • If it exists, fetch the transaction data from the database.
  • If new transaction,
    • Load the Stripe PHP SDK library.
    • Initialize Stripe client library and set API Secret key in StripeClient() method of the Stripe class.
    • Fetch the Checkout Session by ID using the retrieve() method of Stripe Session API.
    • Retrieve the transaction details using the retrieve() method of the Stripe PaymentIntent API.
    • Retrieves the customer details using the retrieve() method of Stripe Customer API.
    • Verify the transaction and check whether the payment is successful.
    • Insert the transaction data into the database using MySQL Prepared Statements with PHP.
  • Display the order status and transaction details on the webpage.
<?php 
// Include configuration file 
require_once 'config.php';

// Include database connection file 
include_once 'dbConnect.php';

$payment_id $statusMsg '';
$status 'error';

// Check whether stripe checkout session is not empty
if(!empty($_GET['checkout_session_id'])){
    
$checkout_session_id $_GET['checkout_session_id'];
    
    
// Fetch transaction data from the database if already exists
    
$sqlQ "SELECT * FROM transactions WHERE stripe_checkout_session_id = ?";
    
$stmt $db->prepare($sqlQ); 
    
$stmt->bind_param("s"$checkout_session_id);
    
$stmt->execute();
    
$result $stmt->get_result();

    if(
$result->num_rows 0){
        
// Transaction details
        
$transData $result->fetch_assoc();
        
$payment_id $transData['id'];
        
$transactionID $transData['txn_id'];
        
$paidAmount $transData['paid_amount'];
        
$paidCurrency $transData['paid_amount_currency'];
        
$payment_status $transData['payment_status'];
        
        
$customer_name $transData['customer_name'];
        
$customer_email $transData['customer_email'];
        
        
$status 'success';
        
$statusMsg 'Your Payment has been Successful!';
    }else{
        
// Include the Stripe PHP library
        
require_once 'stripe-php/init.php';
        
        
// Set API key
        
$stripe = new \Stripe\StripeClient(STRIPE_SECRET_KEY);
        
        
// Fetch the Checkout Session to display the JSON result on the success page
        
try {
            
$checkout_session $stripe->checkout->sessions->retrieve($checkout_session_id);
        } catch(
Exception $e) { 
            
$api_error $e->getMessage(); 
        }
        
        if(empty(
$api_error) && $checkout_session){
            
// Get customer details
            
$customer_details $checkout_session->customer_details;

            
// Retrieve the details of a PaymentIntent
            
try {
                
$paymentIntent $stripe->paymentIntents->retrieve($checkout_session->payment_intent);
            } catch (
\Stripe\Exception\ApiErrorException $e) {
                
$api_error $e->getMessage();
            }
            
            if(empty(
$api_error) && $paymentIntent){
                
// Check whether the payment was successful
                
if(!empty($paymentIntent) && $paymentIntent->status == 'succeeded'){
                    
// Transaction details 
                    
$transactionID $paymentIntent->id;
                    
$paidAmount $paymentIntent->amount;
                    
$paidAmount = ($paidAmount/100);
                    
$paidCurrency $paymentIntent->currency;
                    
$payment_status $paymentIntent->status;
                    
                    
// Customer info
                    
$customer_name $customer_email '';
                    if(!empty(
$customer_details)){
                        
$customer_name = !empty($customer_details->name)?$customer_details->name:'';
                        
$customer_email = !empty($customer_details->email)?$customer_details->email:'';
                    }
                    
                    
// Check if any transaction data is exists already with the same TXN ID
                    
$sqlQ "SELECT id FROM transactions WHERE txn_id = ?";
                    
$stmt $db->prepare($sqlQ); 
                    
$stmt->bind_param("s"$transactionID);
                    
$stmt->execute();
                    
$result $stmt->get_result();
                    
$prevRow $result->fetch_assoc();
                    
                    if(!empty(
$prevRow)){
                        
$payment_id $prevRow['id'];
                    }else{
                        
// Insert transaction data into the database
                        
$sqlQ "INSERT INTO transactions (customer_name,customer_email,item_name,item_number,item_price,item_price_currency,paid_amount,paid_amount_currency,txn_id,payment_status,stripe_checkout_session_id,created,modified) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())";
                        
$stmt $db->prepare($sqlQ);
                        
$stmt->bind_param("ssssdsdssss"$customer_name$customer_email$productName$productID$productPrice$currency$paidAmount$paidCurrency$transactionID$payment_status$checkout_session_id);
                        
$insert $stmt->execute();
                        
                        if(
$insert){
                            
$payment_id $stmt->insert_id;
                        }
                    }
                    
                    
$status 'success';
                    
$statusMsg 'Your Payment has been Successful!';
                }else{
                    
$statusMsg "Transaction has been failed!";
                }
            }else{
                
$statusMsg "Unable to fetch the transaction details! $api_error"
            }
        }else{
            
$statusMsg "Invalid Transaction! $api_error"
        }
    }
}else{
    
$statusMsg "Invalid Request!";
}
?> <?php if(!empty($payment_id)){ ?> <h1 class="<?php echo $status?>"><?php echo $statusMsg?></h1> <h4>Payment Information</h4> <p><b>Reference Number:</b> <?php echo $payment_id?></p> <p><b>Transaction ID:</b> <?php echo $transactionID?></p> <p><b>Paid Amount:</b> <?php echo $paidAmount.' '.$paidCurrency?></p> <p><b>Payment Status:</b> <?php echo $payment_status?></p> <h4>Customer Information</h4> <p><b>Name:</b> <?php echo $customer_name?></p> <p><b>Email:</b> <?php echo $customer_email?></p> <h4>Product Information</h4> <p><b>Name:</b> <?php echo $productName?></p> <p><b>Price:</b> <?php echo $productPrice.' '.$currency?></p> <?php }else{ ?> <h1 class="error">Your Payment been failed!</h1> <p class="error"><?php echo $statusMsg?></p> <?php ?>

Payment Cancel Page (payment-cancel.php)

Stripe will redirect the customer to the specified Cancel page URL when the payment is canceled.

<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Payment Canceled - Stripe Checkout with PHP</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Stylesheet file -->
<link href="css/style.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="status">
        <h1 class="error">Checkout Canceled!</h1>
        <h2 class="error">Your transaction was canceled.</h2>
    </div>
    <a href="index.php" class="btn-link">Back to Product Page</a>
</div>
</body>
</html>

Test Checkout Integration

After redirecting to the Stripe Checkout page, use any of the following test cards to simulate the payment process. Use a valid future expiration date and any random CVC number to test Stripe checkout payment gateway integration in PHP.

  • Payment Success: 4242 4242 4242 4242
  • Payment Requires Authentication: 4000 0025 0000 3155
  • Payment Declined: 4000 0000 0000 9995

Make Stripe Payment Gateway Live

Once you are satisfied with the Stripe checkout payment process, you can make the Stripe Payment gateway live to accept payment online from a real customer.

  • Login to your Stripe account and go to the Developers » API keys page.
  • Collect the API keys (Publishable key and Secret key) from the Live Data section.
  • In the config.php file,
    • Specify the Live API keys (Publishable key and Secret key) in Stripe API constants (STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY).
    • Specify the Live redirect URLs (Success page and Cancel page) in Stripe API constants (STRIPE_SUCCESS_URL and STRIPE_CANCEL_URL).
    define('STRIPE_PUBLISHABLE_KEY''Stripe_API_LIVE_Publishable_Key'); 
    define('STRIPE_SECRET_KEY''Stripe_API_LIVE_Secret_Key');

Stripe Subscription Payment Integration in PHP

Conclusion

If you want to accept payment on your web application, Stripe is the best option for credit card payment. This Stripe checkout script is supported 3D Secure authentication and is ready for SCA (Strong Customer Authentication). You can allow the customer to make payment using their credit or debit card with Stripe checkout API. Our example code will help you to integrate single page checkout using Stripe API and PHP.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

7 Comments

  1. Salvador Said...
  2. Samuel VINCENT Said...
  3. Alex Demian Said...
  4. Taleeb Said...
  5. Navneet Said...
  6. مقاله دانشجویی Said...
  7. Paramjeet Singh Said...

Leave a reply

keyboard_double_arrow_up