How to integrate Stripe payment gateway in PHP

We are going to use Stripe as an example to show us how to do payment gateway integration in PHP. With Stripe’s payment gateway, you can easily accept credit cards directly on your website by integrating a checkout system and enabling payment.

To integrate Stripe payment gateway in your PHP-based website, you need to implement the following functionalities.

  1. Prepare the HTML form to collect credit card information.
  2. Create Stripe token to securely transmit card information.
  3. Submit the form with card details.
  4. Verify the card and process charges.
  5. Insert payment details in the database for status to be shown to the user.

Test Stripe API Keys Data

Before getting your Stripe payment gateway integration live, you need to test it thoroughly. To test the credit card payment process, you need the TEST API Keys to generate in your Stripe account.

  1. Login to your Stripe account and navigate to the API page.
  2. Under the TEST DATA section, you’ll see the API keys are listed. To show the Secret key, click on the Reveal test key token button.

Collect the Publishable key and Secret key to later use in the script.

You probably need to look at the files structures before you proceeding any further:

Create Database Table

Next, you will need to create a table in the database to save the transaction details. What follows is an SQL creating the orders table in the MySQL database.

CREATE TABLE `orders` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `card_num` bigint(20) NOT NULL,
 `card_cvc` int(5) NOT NULL,
 `card_exp_month` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
 `card_exp_year` varchar(5) 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 DEFAULT 'usd',
 `paid_amount` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
 `paid_amount_currency` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
 `txn_id` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `payment_status` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 

Database Configuration (dbConfig.php)

You will need the dbConfig.php file to connect and select the database. Specify the database host ($dbHost), username ($dbUsername), password ($dbPassword), and name ($dbName) after your database credentials.

<?php
//Database credentials
$dbHost     = 'localhost';
$dbUsername = 'root';
$dbPassword = '*****';
$dbName     = 'codexworld';

//Connect with the database
$db = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);

//Display error if failed to connect
if ($db->connect_errno) {
    printf("Connect failed: %s\n", $db->connect_error);
    exit();
}

Stripe Checkout Form (index.php)

JavaScript

Include the Stripe JavaScript library to securely send sensitive information to Stripe directly from the browser.

<!-- Stripe JavaScript library -->
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>

The jQuery library is not necessary to use Stripe; it is used only for this example.

<!-- jQuery is used only for this example; it isn't required to use Stripe -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

In the JavaScript code, set your publishable API key that identifies your website to Stripe. The stripeResponseHandler() function creates a single-use token and inserts a token field in the payment form HTML.

<script type="text/javascript">
//set your publishable key
Stripe.setPublishableKey('Your_API_Publishable_Key');

//callback to handle the response from stripe
function stripeResponseHandler(status, response) {
    if (response.error) {
        //enable the submit button
        $('#payBtn').removeAttr("disabled");
        //display the errors on the form
        $(".payment-errors").html(response.error.message);
    } else {
        var form$ = $("#paymentFrm");
        //get token id
        var token = response['id'];
        //insert the token into the form
        form$.append("<input type='hidden' name='stripeToken' value='" 
+ token + "' />");
        //submit form to the server
        form$.get(0).submit();
    }
}
$(document).ready(function() {
    //on form submit
    $("#paymentFrm").submit(function(event) {
        //disable the submit button to prevent repeated clicks
        $('#payBtn').attr("disabled", "disabled");
        
        //create single-use token to charge the user
        Stripe.createToken({
            number: $('.card-number').val(),
            cvc: $('.card-cvc').val(),
            exp_month: $('.card-expiry-month').val(),
            exp_year: $('.card-expiry-year').val()
        }, stripeResponseHandler);
        
        //submit from callback
        return false;
    });
});
</script>

HTML

The following HTML form collects the user information (name and email) and card details (Card Number, Expiration Date, and CVC No.). For further card payment processing, the form is submitted to the PHP script (submit.php).

<h1>Charge $55 with Stripe</h1>

<!-- display errors returned by createToken -->
<span class="payment-errors"></span>

<!-- stripe payment form -->
<form action="submit.php" method="POST" id="paymentFrm">
    <p>
        <label>Name</label>
        <input type="text" name="name" size="50" />
    </p>
    <p>
        <label>Email</label>
        <input type="text" name="email" size="50" />
    </p>
    <p>
        <label>Card Number</label>
        <input type="text" name="card_num" size="20" autocomplete="off" 
class="card-number" />
    </p>
    <p>
        <label>CVC</label>
        <input type="text" name="cvc" size="4" autocomplete="off" class="card-cvc" />
    </p>
    <p>
        <label>Expiration (MM/YYYY)</label>
        <input type="text" name="exp_month" size="2" class="card-expiry-month"/>
        <span> / </span>
        <input type="text" name="exp_year" size="4" class="card-expiry-year"/>
    </p>
    <button type="submit" id="payBtn">Submit Payment</button>
</form>

Stripe PHP Library

Next, we’re going to use the Stripe PHP library to process the card payment. The library is available here.

Validate and Process Payment (submit.php)

In this file, the submitted card details are validated, and the charge is processed using the Stripe PHP library.

  1. Get the token, card details, and the user info from the submitted form.
    Include the Stripe PHP library.
  2. Set your Publishable key and Secret key, which we have created in Stripe Test API Data section.
  3. Add customer to Stripe using the user email and Stripe token.
  4. Specify product details and create a charge to the credit card or debit card.
  5. Retrieve the charge details that have previously been created.
  6. If the charge is successful, the order and transaction details will be inserted in the database. Otherwise, an error message will be shown.

 

//check whether stripe token is not empty
if(!empty($_POST['stripeToken'])){
    //get token, card and user info from the form
    $token  = $_POST['stripeToken'];
    $name = $_POST['name'];
    $email = $_POST['email'];
    $card_num = $_POST['card_num'];
    $card_cvc = $_POST['cvc'];
    $card_exp_month = $_POST['exp_month'];
    $card_exp_year = $_POST['exp_year'];
    
    //include Stripe PHP library
    require_once('stripe-php/init.php');
    
    //set api key
    $stripe = array(
      "secret_key"      => "Your_API_Secret_Key",
      "publishable_key" => "Your_API_Publishable_Key"
    );
    
    \Stripe\Stripe::setApiKey($stripe['secret_key']);
    
    //add customer to stripe
    $customer = \Stripe\Customer::create(array(
        'email' => $email,
        'source'  => $token
    ));
    
    //item information
    $itemName = "Premium Script CodexWorld";
    $itemNumber = "PS123456";
    $itemPrice = 55;
    $currency = "usd";
    $orderID = "SKA92712382139";
    
    //charge a credit or a debit card
    $charge = \Stripe\Charge::create(array(
        'customer' => $customer->id,
        'amount'   => $itemPrice,
        'currency' => $currency,
        'description' => $itemName,
        'metadata' => array(
            'order_id' => $orderID
        )
    ));
    
    //retrieve charge details
    $chargeJson = $charge->jsonSerialize();
    //check whether the charge is successful
    if($chargeJson['amount_refunded'] == 0 && empty($chargeJson
['failure_code']) && $chargeJson['paid'] == 1 && $chargeJson['captured'] == 1){
        //order details 
        $amount = $chargeJson['amount'];
        $balance_transaction = $chargeJson['balance_transaction'];
        $currency = $chargeJson['currency'];
        $status = $chargeJson['status'];
        $date = date("Y-m-d H:i:s");
        
        //include database config file
        include_once 'dbConfig.php';
        
        //insert tansaction data into the database
        $sql = 
"INSERT INTO orders(name,email,card_num,card_cvc,card_exp_month,card_exp_year,
item_name,item_number,item_price,item_price_currency,paid_amount,
paid_amount_currency,txn_id,payment_status,created,modified) VALUES
('".$name."','".$email."','".$card_num."','".$card_cvc."','".$card_exp_month."',
'".$card_exp_year."','".$itemName."','".$itemNumber."','".$itemPrice."','".$currency."',
'".$amount."','".$currency."','".$balance_transaction."'
,'".$status."','".$date."','".$date."')";
        $insert = $db->query($sql);
        $last_insert_id = $db->insert_id;
        
        //if order inserted successfully
        if($last_insert_id && $status == 'succeeded'){
            $statusMsg = "<h2>The transaction was successful.</h2>
<h4>Order ID: {$last_insert_id}</h4>";
        }else{
            $statusMsg = "Transaction has been failed";
        }
    }else{
        $statusMsg = "Transaction has been failed";
    }
}else{
    $statusMsg = "Form submission error.......";
}
//show success or error message
echo $statusMsg;

 

Test Card Details

To test the payment process, you need test card details. Use any of the following test card numbers, a valid, future expiration date, and any random CVC number to test Stripe payment gateway integration in PHP.

  • 378282246310005 American Express
  • 6011111111111117 Discover
  • 4242424242424242 Visa
  • 4000056655665556 Visa (debit)
  • 5555555555554444 Mastercard
  • 5200828282828210 Mastercard (debit)

Launch Stripe Payment Gateway Live

Once testing is done and the payment process is working properly, follow the steps below to have Stripe payment gateway go live.

  1. Login to your Stripe account and navigate to the API page.
  2. Collect the API keys (Publishable key and Secret key) from Live Data.
  3. Change the Test API keys (Publishable key and Secret key) with the Live API keys (Publishable key and Secret key) in the script.