PHP 7 Script to Integrate Stripe Subscription Payment in Website Using MySQL Database

You are currently viewing PHP 7 Script to Integrate Stripe Subscription Payment in Website Using MySQL Database

PHP 7 Script to Integrate Stripe Subscription Payment in Website Using MySQL Database

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`subscription_id` int(11) NOT NULL DEFAULT '0',
`first_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
`last_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`gender` enum('Male','Female') COLLATE utf8_unicode_ci NOT NULL,
`phone` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
`status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `user_subscriptions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL DEFAULT '0',
`payment_method` enum('stripe') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'stripe',
`stripe_subscription_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`stripe_customer_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`stripe_plan_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`plan_amount` float(10,2) NOT NULL,
`plan_amount_currency` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`plan_interval` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`plan_interval_count` tinyint(2) NOT NULL,
`payer_email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
`plan_period_start` datetime NOT NULL,
`plan_period_end` datetime NOT NULL,
`status` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

<?php
// Subscription plans
// Minimum amount is $0.50 US
// Interval day, week, month or year
$plans = array(
    '1' => array(
        'name' => 'Weekly Subscription',
        'price' => 25,
        'interval' => 'week'
    ),
    '2' => array(
        'name' => 'Monthly Subscription',
        'price' => 85,
        'interval' => 'month'
    ),
    '3' => array(
        'name' => 'Yearly Subscription',
        'price' => 950,
        'interval' => 'year'
    )
);
$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_API_KEY', 'Your_API_Secret_key');
define('STRIPE_PUBLISHABLE_KEY', 'Your_API_Publishable_key');
  
// 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');

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

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

<div class="panel">
    <form action="payment.php" method="POST" id="paymentFrm">
        <div class="panel-heading">
            <h3 class="panel-title">Plan Subscription with Stripe</h3>

            <!-- Plan Info -->
            <p>
                <b>Select Plan:</b>
                <select name="subscr_plan" id="subscr_plan">
                    <?php foreach($plans as $id=>$plan){ ?>
                        <option value="<?php echo $id; ?>"><?php echo $plan['name'].' [
<script src="https://js.stripe.com/v3/"></script>

<script>
// Create an instance of the Stripe object
// Set your publishable API key
var stripe = Stripe('<?php echo STRIPE_PUBLISHABLE_KEY; ?>');
 
// Create an instance of elements
var elements = stripe.elements();
 
var style = {
    base: {
        fontWeight: 400,
        fontFamily: 'Roboto, Open Sans, Segoe UI, sans-serif',
        fontSize: '16px',
        lineHeight: '1.4',
        color: '#555',
        backgroundColor: '#fff',
        '::placeholder': {
            color: '#888',
        },
    },
    invalid: {
        color: '#eb1c26',
    }
};
 
var cardElement = elements.create('cardNumber', {
    style: style
});
cardElement.mount('#card_number');
 
var exp = elements.create('cardExpiry', {
    'style': style
});
exp.mount('#card_expiry');
 
var cvc = elements.create('cardCvc', {
    'style': style
});
cvc.mount('#card_cvc');
 
// Validate input of the card elements
var resultContainer = document.getElementById('paymentResponse');
cardElement.addEventListener('change', function(event) {
    if (event.error) {
        resultContainer.innerHTML = '<p>'+event.error.message+'</p>';
    } else {
        resultContainer.innerHTML = '';
    }
});
 
// Get payment form element
var form = document.getElementById('paymentFrm');
 
// Create a token when the form is submitted.
form.addEventListener('submit', function(e) {
    e.preventDefault();
    createToken();
});
 
// Create single-use token to charge the user
function createToken() {
    stripe.createToken(cardElement).then(function(result) {
        if (result.error) {
            // Inform the user if there was an error
            resultContainer.innerHTML = '<p>'+result.error.message+'</p>';
        } else {
            // Send the token to your server
            stripeTokenHandler(result.token);
        }
    });
}
 
// Callback to handle the response from stripe
function stripeTokenHandler(token) {
    // Insert the token ID into the form so it gets submitted to the server
    var hiddenInput = document.createElement('input');
    hiddenInput.setAttribute('type', 'hidden');
    hiddenInput.setAttribute('name', 'stripeToken');
    hiddenInput.setAttribute('value', token.id);
    form.appendChild(hiddenInput);

    // Submit the form
    form.submit();
}
</script>

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

// Get user ID from current SESSION
$userID = isset($_SESSION['loggedInUserID'])?$_SESSION['loggedInUserID']:1;

$payment_id = $statusMsg = $api_error = '';
$ordStatus = 'error';

// Check whether stripe token is not empty
if(!empty($_POST['subscr_plan']) && !empty($_POST['stripeToken'])){
    
    // Retrieve stripe token and user info from the submitted form data
    $token  = $_POST['stripeToken'];
    $name = $_POST['name'];
    $email = $_POST['email'];
    
    // Plan info
    $planID = $_POST['subscr_plan'];
    $planInfo = $plans[$planID];
    $planName = $planInfo['name'];
    $planPrice = $planInfo['price'];
    $planInterval = $planInfo['interval'];
    
    // Include Stripe PHP library
    require_once 'stripe-php/init.php';
    
    // Set API key
    \Stripe\Stripe::setApiKey(STRIPE_API_KEY);
    
    // Add customer to stripe
    try {  
        $customer = \Stripe\Customer::create(array(
            'email' => $email,
            'source'  => $token
        ));
    }catch(Exception $e) {  
        $api_error = $e->getMessage();  
    }
    
    if(empty($api_error) && $customer){  
    
        // Convert price to cents
        $priceCents = round($planPrice*100);
    
        // Create a plan
        try {
            $plan = \Stripe\Plan::create(array(
                "product" => [
                    "name" => $planName
                ],
                "amount" => $priceCents,
                "currency" => $currency,
                "interval" => $planInterval,
                "interval_count" => 1
            ));
        }catch(Exception $e) {
            $api_error = $e->getMessage();
        }
        
        if(empty($api_error) && $plan){
            // Creates a new subscription
            try {
                $subscription = \Stripe\Subscription::create(array(
                    "customer" => $customer->id,
                    "items" => array(
                        array(
                            "plan" => $plan->id,
                        ),
                    ),
                ));
            }catch(Exception $e) {
                $api_error = $e->getMessage();
            }
            
            if(empty($api_error) && $subscription){
                // Retrieve subscription data
                $subsData = $subscription->jsonSerialize();
        
                // Check whether the subscription activation is successful
                if($subsData['status'] == 'active'){
                    // Subscription info
                    $subscrID = $subsData['id'];
                    $custID = $subsData['customer'];
                    $planID = $subsData['plan']['id'];
                    $planAmount = ($subsData['plan']['amount']/100);
                    $planCurrency = $subsData['plan']['currency'];
                    $planinterval = $subsData['plan']['interval'];
                    $planIntervalCount = $subsData['plan']['interval_count'];
                    $created = date("Y-m-d H:i:s", $subsData['created']);
                    $current_period_start = date("Y-m-d H:i:s", $subsData['current_period_start']);
                    $current_period_end = date("Y-m-d H:i:s", $subsData['current_period_end']);
                    $status = $subsData['status'];
                    
                    // Include database connection file  
                    include_once 'dbConnect.php';
        
                    // Insert transaction data into the database
                    $sql = "INSERT INTO user_subscriptions(user_id,stripe_subscription_id,stripe_customer_id,stripe_plan_id,plan_amount,plan_amount_currency,plan_interval,plan_interval_count,payer_email,created,plan_period_start,plan_period_end,status) VALUES('".$userID."','".$subscrID."','".$custID."','".$planID."','".$planAmount."','".$planCurrency."','".$planinterval."','".$planIntervalCount."','".$email."','".$created."','".$current_period_start."','".$current_period_end."','".$status."')";
                    $insert = $db->query($sql);  
                      
                    // Update subscription id in the users table  
                    if($insert && !empty($userID)){  
                        $subscription_id = $db->insert_id;  
                        $update = $db->query("UPDATE users SET subscription_id = {$subscription_id} WHERE id = {$userID}");  
                    }
                    
                    $ordStatus = 'success';
                    $statusMsg = 'Your Subscription Payment has been Successful!';
                }else{
                    $statusMsg = "Subscription activation failed!";
                }
            }else{
                $statusMsg = "Subscription creation failed! ".$api_error;
            }
        }else{
            $statusMsg = "Plan creation failed! ".$api_error;
        }
    }else{  
        $statusMsg = "Invalid card details! $api_error";  
    }
}else{
    $statusMsg = "Error on form submission, please try again.";
}
?>
 
<div class="container">
    <div class="status">
        <h1 class="<?php echo $ordStatus; ?>"><?php echo $statusMsg; ?></h1>
        <?php if(!empty($subscrID)){ ?>
            <h4>Payment Information</h4>
            <p><b>Reference Number:</b> <?php echo $subscription_id; ?></p>
            <p><b>Transaction ID:</b> <?php echo $subscrID; ?></p>
            <p><b>Amount:</b> <?php echo $planAmount.' '.$planCurrency; ?></p>

            <h4>Subscription Information</h4>
            <p><b>Plan Name:</b> <?php echo $planName; ?></p>
            <p><b>Amount:</b> <?php echo $planPrice.' '.$currency; ?></p>
            <p><b>Plan Interval:</b> <?php echo $planInterval; ?></p>
            <p><b>Period Start:</b> <?php echo $current_period_start; ?></p>
            <p><b>Period End:</b> <?php echo $current_period_end; ?></p>
            <p><b>Status:</b> <?php echo $status; ?></p>
        <?php } ?>
    </div>
    <a href="index.php" class="btn-link">Back to Subscription Page</a>
</div>

.$plan['price'].'/'.$plan['interval'].']'; ?></option>                     <?php } ?>                 </select>             </p>         </div>         <div class="panel-body">             <!-- Display errors returned by createToken -->             <div id="paymentResponse"></div>             <!-- Payment form -->             <div class="form-group">                 <label>NAME</label>                 <input type="text" name="name" id="name" class="field" placeholder="Enter name" required="" autofocus="">             </div>             <div class="form-group">                 <label>EMAIL</label>                 <input type="email" name="email" id="email" class="field" placeholder="Enter email" required="">             </div>             <div class="form-group">                 <label>CARD NUMBER</label>                 <div id="card_number" class="field"></div>             </div>             <div class="row">                 <div class="left">                     <div class="form-group">                         <label>EXPIRY DATE</label>                         <div id="card_expiry" class="field"></div>                     </div>                 </div>                 <div class="right">                     <div class="form-group">                         <label>CVC CODE</label>                         <div id="card_cvc" class="field"></div>                     </div>                 </div>             </div>             <button type="submit" class="btn btn-success" id="payBtn">Submit Payment</button>         </div>     </form> </div>

Ranjith

Hi, I'm Manoj a full-time Blogger, YouTuber, Affiliate Marketer, & founder of Coding Diksha. Here, I post about programming to help developers.

Leave a Reply