Sick Gaming
[Tut] Stripe One Time Payment with Prebuilt Hosted Checkout in PHP - Printable Version

+- Sick Gaming (https://www.sickgaming.net)
+-- Forum: Programming (https://www.sickgaming.net/forum-76.html)
+--- Forum: PHP Development (https://www.sickgaming.net/forum-82.html)
+--- Thread: [Tut] Stripe One Time Payment with Prebuilt Hosted Checkout in PHP (/thread-97611.html)



[Tut] Stripe One Time Payment with Prebuilt Hosted Checkout in PHP - xSicKxBot - 10-06-2020

Stripe One Time Payment with Prebuilt Hosted Checkout in PHP

<div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/10/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php.jpg" width="550" height="190" title="" alt="" /></div><div><p>Last modified on October 6th, 2020.</p>
<p>Stripe provides payment processing to support eCommerce software and mobile APPs. The key features by Stripe are,</p>
<ul>
<li>fast and interactive checkout experience.</li>
<li>secure, smooth payment flow.</li>
<li>scope to uplift the conversion rate and business growth.</li>
</ul>
<p>Stripe is the most popular payment gateway solution supporting card payments along with PayPal. Its complete documentation helps developers to do an effortless integration.</p>
<p>Stripe provides different types of payment services to accept payments. It supports accepting one-time payment, recurring payment, in-person payment and more.</p>
<p>There are two ways to set up the Stripe one-time payment option in a eCommerce website.</p>
<ol>
<li>Use the secure <strong>prebuilt hosted checkout page</strong>.</li>
<li>Create a <strong>custom payment flow</strong>.</li>
</ol>
<p>Let us take the first method to integrate Stripe’s one-time payment. The example code redirects customers to the Stripe hosted checkout page. It’s a pre-built page that allows customers to enter payment details.</p>
<p>Stripe hosted checkout option piggybacks on the Stripe trust factor. If your website is lesser-known, if you are not popular, then it is best to choose this option. Because the end users may feel uncomfortable to enter their card details on your page.</p>
<p>This diagram depicts the Stripe payment flow, redirect and response handling.</p>
<p><img loading="lazy" class="alignnone size-large wp-image-12166" src="https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-block-diagram-550x190.jpg" alt="Stripe Hosted Checkout Block Diagram" width="550" height="190" srcset="https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-block-diagram-550x190.jpg 550w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-block-diagram-300x103.jpg 300w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-block-diagram-768x265.jpg 768w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-block-diagram-1536x530.jpg 1536w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-block-diagram.jpg 1664w" sizes="(max-width: 550px) 100vw, 550px"></p>
<p>In this example, it uses the latest checkout version to set up a one-time payment. If you want to <a href="https://phppot.com/php/manage-recurring-payments-using-stripe-billing-in-php/">create Stripe subscription payment</a>, then the linked article has an example for it.</p>
<h2>What is inside?</h2>
<ol>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#about-stripe-checkout">About Stripe Checkout</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#steps-to-set-up-stripe-one-time-payment-flow">Steps to set up Stripe one-time payment flow</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#about-this-example">About this example</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#generate-and-configure-stripe-api-keys">Generate and configure Stripe API keys</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#create-webhook-and-map-events">Create webhook and map events</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#required-libraries-to-access-stripe-api">Required libraries to access Stripe API</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#create-client-server-side-code-to-initiate-checkout">Create client-server-side code to initiate checkout</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#capture-and-process-webhook-response">Capture and process webhook response</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#evaluate-integration-with-test-data">Evaluate integration with test data</a></li>
<li><a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#stripe-one-time-payment-example-output">Stripe one-time payment example output</a></li>
</ol>
<h2 id="about-stripe-checkout">About Stripe Checkout</h2>
<p>Latest Stripe Checkout provides a frictionless smooth checkout experience. The below list shows some features of the latest Stripe checkout version.</p>
<ul>
<li>Strong Customer Authentication (SCA).</li>
<li>Checkout interface fluidity over various devices’ viewport.</li>
<li>Multilingual support.</li>
<li>Configurable options to enable billing address collection, email receipts, and Button customizations</li>
</ul>
<p>If you are using the legacy version,&nbsp; it’s so simple to migrate to the latest Stripe Checkout version. The upgraded version supports advanced features like <strong>3D secure</strong>, mobile payments and more.</p>
<h2 id="steps-to-set-up-stripe-one-time-payment-flow">Steps to setup Stripe one-time payment flow</h2>
<p>The below steps are the least needs to <a href="https://stripe.com/docs/checkout/integration-builder" target="_blank" rel="noopener noreferrer">set up a Stripe one-time payment</a> online.</p>
<ol>
<li>Register with Stripe and generate API keys.</li>
<li>Configure API keys with the application.</li>
<li>Install and load the required libraries to access API.</li>
<li>Create client and server-side code to make payments.</li>
<li>Create endpoints to receive payment response and log into a database.</li>
<li>Create a UI template to acknowledge customers.</li>
</ol>
<p>We will see the above steps in this article with example code and screenshots.</p>
<h2 id="about-this-example">About Stripe payment integration example</h2>
<p>Stripe API allows applications to access and use its online payment services. It provides Stripe.js a JavaScript library to initiate the payment session flow.</p>
<p>This example code imports the Stripe libraries to access the API functions. It sets the endpoint to build the request and receive the response.</p>
<p>The client and server-side code redirect customers to the Stripe hosted checkout page. In the callback handlers, it processes the payment response sent by the API.</p>
<p>This example uses a database to store payment entries. It uses <a href="https://phppot.com/php/crud-with-mysqli-prepared-statement-using-php/">MySQLi with prepared statements</a> to execute queries.</p>
<p>This image shows the simple file architecture of this example<span>.</span></p>
<p><img loading="lazy" class="alignnone wp-image-12101 size-full" src="https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-file-structure.jpg" alt="Stripe Hosted Checkout File Structure" width="350" height="563" srcset="https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-file-structure.jpg 350w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-file-structure-187x300.jpg 187w" sizes="(max-width: 350px) 100vw, 350px"></p>
<h2 id="generate-and-configure-stripe-api-keys">Get and configure Stripe API keys</h2>
<p>Register and log in with Stripe to get the API keys. Stripe dashboard will show two keys publishable_key and secret_key.</p>
<p>These keys are the reference to validate the request during the authentication process.</p>
<p><strong>Note:</strong> Once finish testing in a sandbox mode, Stripe requires to activate the account to get the live API keys.</p>
<p><img loading="lazy" class="alignnone wp-image-12114 size-large" src="https://phppot.com/wp-content/uploads/2020/10/get-stripe-api-keys-550x328.png" alt="Get Stripe API Keys" width="550" height="328" srcset="https://phppot.com/wp-content/uploads/2020/10/get-stripe-api-keys-550x328.png 550w, https://phppot.com/wp-content/uploads/2020/10/get-stripe-api-keys-300x179.png 300w, https://phppot.com/wp-content/uploads/2020/10/get-stripe-api-keys.png 600w" sizes="(max-width: 550px) 100vw, 550px"></p>
<p>This code shows the constants created to configure the API keys for this example.</p>
<pre class="prettyprint lang-php">&lt;?php
namespace Phppot; class Config
{ const ROOT_PATH = "https://your-domain/stripe-hosted"; /* Stripe API test keys */ const STRIPE_PUBLISHIABLE_KEY = ""; const STRIPE_SECRET_KEY = ""; /* PRODUCT CONFIGURATIONS BEGINS */ const PRODUCT_NAME = 'A6900 MirrorLess Camera'; const PRODUCT_IMAGE = Config::ROOT_PATH . '/images/camera.jpg'; const PRODUCT_PRICE = '289.61'; const CURRENCY = 'USD'; const PRODUCT_TYPE = 'good';
}
</pre>
<h2 id="create-webhook-and-map-events">Create webhook and map events</h2>
<p>Creating a webhook is a conventional way to get the payment notifications sent by the API. All payment gateway providers give the option to create webhook for callback.</p>
<p>In <a href="https://phppot.com/php/paypal-payment-gateway-integration-in-php/">PayPal payment gateway integration</a> article, we have seen the types of notification mechanisms supported by PayPal.</p>
<p>The code has the webhook endpoint registered with Stripe. It handles the API responses based on the event that occurred.</p>
<p>The below image shows the screenshot of the add-endpoint dialog. It populates the URL and the mapped events in the form fields.</p>
<p>Navigate via&nbsp;<em>Developers-&gt;Webhooks</em>&nbsp;and click the <em>Add endpoint</em> button to see the dialog.</p>
<p><a href="https://phppot.com/wp-content/uploads/2020/10/add-stripe-webhook-endpoint.jpg"><img loading="lazy" class="alignnone size-large wp-image-12118" src="https://phppot.com/wp-content/uploads/2020/10/add-stripe-webhook-endpoint-550x553.jpg" alt="Add Stripe Webhook Endpoint" width="550" height="553" srcset="https://phppot.com/wp-content/uploads/2020/10/add-stripe-webhook-endpoint-550x553.jpg 550w, https://phppot.com/wp-content/uploads/2020/10/add-stripe-webhook-endpoint-298x300.jpg 298w, https://phppot.com/wp-content/uploads/2020/10/add-stripe-webhook-endpoint-150x150.jpg 150w, https://phppot.com/wp-content/uploads/2020/10/add-stripe-webhook-endpoint.jpg 631w" sizes="(max-width: 550px) 100vw, 550px"></a></p>
<h2 id="required-libraries-to-access-stripe-api">Required libraries to access Stripe API</h2>
<p>First, download and install the <strong>stripe-php</strong> library. This will help to send flawless payment initiation request to the Stripe API.</p>
<p>This command helps to install this library via Composer. It is also available to <a href="https://github.com/stripe/stripe-php/releases">download from GitHub.</a></p>
<pre class="prettyprint lang-php">composer require stripe/stripe-php
</pre>
<p>Load Stripe.js JavaScript library into the page which has the checkout button. Load this file by using https://js.stripe.com/v3/ instead of having it in local.</p>
<pre class="prettyprint lang-php">&lt;script src="https://js.stripe.com/v3/"&gt;&lt;/script&gt;
</pre>
<h2 id="create-client-server-side-code-to-initiate-checkout">Create client-server code to process checkout</h2>
<p>This section includes the steps needed to create the client-server code for setting up the Stripe one-time payment.</p>
<ol>
<li>Add checkout button and load Stripe.js</li>
<li>Create a JavaScript event handler to initiate checkout session</li>
<li>Create PHP endpoint to post create-checkout-session request</li>
<li>Redirect customers to the Stripe hosted checkout page</li>
<li>Get checkout session-id from the response.</li>
</ol>
<h3>HTML page with Stripe checkout button</h3>
<p>This page has HTML code to add the Stripe checkout button. It loads the Stripe.js library.</p>
<p>This page loads a JavaScript that initiates the checkout session and redirects the user to the prebuilt Stripe hosted checkout.</p>
<p>The Stripe hosted checkout form handles the card validation effectively. We have created a custom car validator for <a href="https://phppot.com/php/authorize-net-payment-gateway-integration-using-php/">Authorize.net payment integration</a> code. Hosted checkout is more secure than handling card details by custom handlers.</p>
<p class="code-heading">index.php</p>
<pre class="prettyprint lang-php">&lt;?php
namespace Phppot;
?&gt;
&lt;html&gt;
&lt;title&gt;Stripe Prebuilt Hosted Checkout&lt;/title&gt;
&lt;head&gt;
&lt;link href="css/style.css" type="text/css" rel="stylesheet" /&gt;
&lt;script src="https://js.stripe.com/v3/"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt; &lt;div class="phppot-container"&gt; &lt;h1&gt;Stripe Prebuilt Hosted Checkout&lt;/h1&gt; &lt;div id="payment-box"&gt; &lt;img src="images/camera.jpg" /&gt; &lt;h4 class="txt-title"&gt;A6900 MirrorLess Camera&lt;/h4&gt; &lt;div class="txt-price"&gt;$289.61&lt;/div&gt; &lt;button id="checkout-button"&gt;Checkout&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;script&gt; var stripe = Stripe('&lt;?php echo Config::STRIPE_PUBLISHIABLE_KEY; ?&gt;'); var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { fetch('create-checkout-session.php', { method: 'POST', }) .then(function(response) { return response.json(); }) .then(function(session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function(result) { if (result.error) { alert(result.error.message); } }) .catch(function(error) { console.error('Error:', error); }); }); &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>JavaScript event handler initiates checkout session</h3>
<p>In the previous section, it loads a JavaScript to do the following.</p>
<ol>
<li>Instantiate Stripe Javascript library object with the reference of the Stripe Publishable key.</li>
<li>Map the checkout button’s click event to initiate a create-checkout-session.</li>
<li>Redirect customers to the Stripe hosted checkout page with the checkout session id.</li>
</ol>
<p>It calls the PHP endpoint builds the API request params to start a checkout session.</p>
<p>Then it receives the checkout-session-id as returned by the PHP endpoint. The <em>redirectToCheckout()</em> method sends customers to the prebuilt checkout to complete the payment.</p>
<h3>PHP endpoint processing create-checkout-session request</h3>
<p>When clicking the checkout button, the JavaScript executes an AJAX request. It fetches the PHP endpoint processing the create-checkout-session request.</p>
<p>The below code shows how to create the Stripe checkout-session via API. The API request is with the required query parameters. It includes the product detail, unit amount, payment method and more.</p>
<p>Then the API will return the session object after processing this request. This endpoint parses the response and grab the session-id and return it.</p>
<p class="code-heading">ajax-endpoint/create-checkout-session.php</p>
<pre class="prettyprint lang-php">&lt;?php
namespace Phppot; use Phppot\StripeService;
use Phppot\StripePayment; $orderReferenceId = rand(100000, 999999); require_once __DIR__ . "/../lib/StripeService.php";
require_once __DIR__ .'/../Common/Config.php'; require_once __DIR__ . '/../lib/StripePayment.php';
$stripePayment = new StripePayment(); $stripeService = new StripeService(); $currency = Config::CURRENCY; $orderId = $stripePayment-&gt;insertOrder(Config::PRODUCT_PRICE, $currency, $orderReferenceId, "Payment in-progress");
$unitAmount = Config::PRODUCT_PRICE * 100;
$session = $stripeService-&gt;createCheckoutSession($unitAmount, $orderId);
echo json_encode($session);
</pre>
<p>The StripeService is a PHP class created to build API requests and process responses.</p>
<p>The createCheckoutSession() function builds the param array for the create-checkout-session request.</p>
<p>This service also handles the webhook responses sent by the API. The API sends the response on the occurrences of the events mapped with the webhook endpoint URL.</p>
<p class="code-heading">lib/StripeService.php</p>
<pre class="prettyprint lang-php">&lt;?php
namespace Phppot; require_once __DIR__ . '/../Common/Config.php'; class StripeService
{ function __construct() { require_once __DIR__ . "/../vendor/autoload.php"; // Set your secret key. Remember to set your live key in production! \Stripe\Stripe::setApiKey(Config::STRIPE_SECRET_KEY); } public function createCheckoutSession($unitAmount, $clientReferenceId) { $checkout_session = \Stripe\Checkout\Session::create([ 'payment_method_types' =&gt; ['card'], 'line_items' =&gt; [[ 'price_data' =&gt; [ 'currency' =&gt; Config::CURRENCY, 'unit_amount' =&gt; $unitAmount, 'product_data' =&gt; [ 'name' =&gt; Config::PRODUCT_NAME, 'images' =&gt; [Config::PRODUCT_IMAGE], ], ], 'quantity' =&gt; 1, ]], 'mode' =&gt; 'payment', 'client_reference_id' =&gt; $clientReferenceId, 'success_url' =&gt; Config::ROOT_PATH . '/success.php?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' =&gt; Config::ROOT_PATH . '/index.php?status=cancel', ]); return $checkout_session; } public function captureResponse() { $payload = @file_get_contents('php://input'); $event = json_decode($payload); require_once __DIR__ . "/../lib/StripePayment.php"; $stripePayment = new StripePayment(); switch($event-&gt;type) { case "customer.created": $param["stripe_customer_id"] = $event-&gt;data-&gt;object-&gt;id; $param["email"] = $event-&gt;data-&gt;object-&gt;email; $param["customer_created_datetime"] = date("Y,m,d H:i:s", $event-&gt;data-&gt;object-&gt;created); $param["stripe_response"] = json_encode($event-&gt;data-&gt;object); $stripePayment-&gt;insertCustomer($param); break; case "checkout.session.completed": $param["order_id"] = $event-&gt;data-&gt;object-&gt;client_reference_id; $param["customer_id"] = $event-&gt;data-&gt;object-&gt;customer; $param["payment_intent_id"] = $event-&gt;data-&gt;object-&gt;payment_intent; $param["stripe_checkout_response"] = json_encode($event-&gt;data-&gt;object); $stripePayment-&gt;updateOrder($param); break; case "payment_intent.created": $param["payment_intent_id"] = $event-&gt;data-&gt;object-&gt;id; $param["payment_create_at"] = date("Y-m-d H:i:s", $event-&gt;data-&gt;object-&gt;created); $param["payment_status"] = $event-&gt;data-&gt;object-&gt;status; $param["stripe_payment_response"] = json_encode($event-&gt;data-&gt;object); $stripePayment-&gt;insertPayment($param); break; case "payment_intent.succeeded": $param["payment_intent_id"] = $event-&gt;data-&gt;object-&gt;id; $param["billing_name"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;billing_details-&gt;name; $param["billing_email"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;billing_details-&gt;email; $param["payment_last_updated"] = date("Y-m-d H:i:s", $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;created); $param["payment_status"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;status; $param["stripe_payment_response"] = json_encode($event-&gt;data-&gt;object); $stripePayment-&gt;updatePayment($param); break; case "payment_intent.canceled": $param["payment_intent_id"] = $event-&gt;data-&gt;object-&gt;id; $param["billing_name"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;billing_details-&gt;name; $param["billing_email"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;billing_details-&gt;email; $param["payment_last_updated"] = date("Y-m-d H:i:s", $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;created); $param["payment_status"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;status; $param["stripe_payment_response"] = json_encode($event-&gt;data-&gt;object); $stripePayment-&gt;updatePayment($param); break; case "payment_intent.payment_failed": $param["payment_intent_id"] = $event-&gt;data-&gt;object-&gt;id; $param["billing_name"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;billing_details-&gt;name; $param["billing_email"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;billing_details-&gt;email; $param["payment_last_updated"] = date("Y-m-d H:i:s", $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;created); $param["payment_status"] = $event-&gt;data-&gt;object-&gt;charges-&gt;data[0]-&gt;status; $param["stripe_payment_response"] = json_encode($event-&gt;data-&gt;object); $stripePayment-&gt;updatePayment($param); break; } http_response_code(200); }
} </pre>
<h2 id="capture-and-process-webhook-response">Capture and process response</h2>
<p>The <em>capture-response.php</em> file calls the StripeService class to handle the webhook response.</p>
<p>The registered webhook endpoint has the mapping for the events. The figure shows the mapped events and the webhook URL below.</p>
<p><img loading="lazy" class="alignnone wp-image-12121 size-large" src="https://phppot.com/wp-content/uploads/2020/10/stripe-developers-webhook-detail-550x200.jpg" alt="Stripe Developers Webhook Detail" width="550" height="200" srcset="https://phppot.com/wp-content/uploads/2020/10/stripe-developers-webhook-detail-550x200.jpg 550w, https://phppot.com/wp-content/uploads/2020/10/stripe-developers-webhook-detail-300x109.jpg 300w, https://phppot.com/wp-content/uploads/2020/10/stripe-developers-webhook-detail-768x279.jpg 768w, https://phppot.com/wp-content/uploads/2020/10/stripe-developers-webhook-detail.jpg 791w" sizes="(max-width: 550px) 100vw, 550px"></p>
<p>The captureResponse() function handles the API response based on the events that occurred.</p>
<p>On each event, it updates the customer, order database tables. It creates the payment response log to put entries into the tbl_stripe_response table.</p>
<p class="code-heading">webhook-ep/capture-response.php</p>
<pre class="prettyprint lang-php">&lt;?php
namespace Phppot; use Phppot\StriService; require_once __DIR__ . "/../lib/StripeService.php"; $stripeService = new StripeService(); $stripeService-&gt;captureResponse(); ?&gt;
</pre>
<p>It invokes the StripeService function captureResponse(). It calls StripePayment to store Orders, Customers and Payment data into the database.</p>
<p>The StripePayment class it uses DataSource to connect the database and access it.</p>
<p class="code-heading">lib/StripePayment.php</p>
<pre class="prettyprint lang-php">&lt;?php
namespace Phppot; use Phppot\DataSource; class StripePayment
{ private $ds; function __construct() { require_once __DIR__ . "/../lib/DataSource.php"; $this-&gt;ds = new DataSource(); } public function insertOrder($unitAmount, $currency, $orderReferenceId, $orderStatus) { $orderAt = date("Y-m-d H:i:s"); $insertQuery = "INSERT INTO tbl_order(order_reference_id, amount, currency, order_at, order_status) VALUES (?, ?, ?, ?, ?) "; $paramValue = array( $orderReferenceId, $unitAmount, $currency, $orderAt, $orderStatus ); $paramType = "sisss"; $insertId = $this-&gt;ds-&gt;insert($insertQuery, $paramType, $paramValue); return $insertId; } public function updateOrder($param) { $paymentDetails = $this-&gt;getPaymentByIntent($param["payment_intent_id"]); if (! empty($paymentDetails)) { if($paymentDetails[0]["payment_status"] == "succeeded") { $paymentStatus = "Paid"; } else if($paymentDetails[0]["payment_status"] == "requires_source") { $paymentStatus = "Payment in-progress"; } $query = "UPDATE tbl_order SET stripe_customer_id = ?, stripe_payment_intent_id = ?, stripe_checkout_response = ?, order_status = ? WHERE id = ?"; $paramValue = array( $param["customer_id"], $param["payment_intent_id"], $param["stripe_checkout_response"], $paymentStatus, $param["order_id"] ); $paramType = "ssssi"; $this-&gt;ds-&gt;execute($query, $paramType, $paramValue); } } public function insertCustomer($customer) { $insertQuery = "INSERT INTO tbl_customer(stripe_customer_id, email, customer_created_datetime, stripe_response) VALUES (?, ?, ?, ?) "; $paramValue = array( $customer["stripe_customer_id"], $customer["email"], $customer["customer_created_datetime"], $customer["stripe_response"] ); $paramType = "ssss"; $this-&gt;ds-&gt;insert($insertQuery, $paramType, $paramValue); } public function insertPayment($param) { $insertQuery = "INSERT INTO tbl_payment(stripe_payment_intent_id, payment_create_at, payment_status, stripe_payment_response) VALUES (?, ?, ?, ?) "; $paramValue = array( $param["payment_intent_id"], $param["payment_create_at"], $param["payment_status"], $param["stripe_payment_response"] ); $paramType = "ssss"; $this-&gt;ds-&gt;insert($insertQuery, $paramType, $paramValue); } public function updatePayment($param) { $query = "UPDATE tbl_payment SET billing_name = ?, billing_email = ?, payment_last_updated = ?, payment_status = ?, stripe_payment_response = ? WHERE stripe_payment_intent_id = ?"; $paramValue = array( $param["billing_name"], $param["billing_email"], $param["payment_last_updated"], $param["payment_status"], $param["stripe_payment_response"], $param["payment_intent_id"] ); $paramType = "ssssss"; $this-&gt;ds-&gt;execute($query, $paramType, $paramValue); } public function getPaymentByIntent($paymentIntent) { $query = "SELECT * FROM tbl_payment WHERE stripe_payment_intent_id = ?"; $paramValue = array( $paymentIntent ); $paramType = "s"; $result = $this-&gt;ds-&gt;select($query, $paramType, $paramValue); return $result; }
}
?&gt;
</pre>
<h3>Showing success page after payment</h3>
<p>As sent with the create-checkout-session request, Stripe invokes the success page URL after payment.</p>
<p>The below code has the payment success message to acknowledge customers.</p>
<p class="code-heading">success.php</p>
<pre class="prettyprint lang-php">&lt;?php
namespace Phppot; require_once __DIR__ . '/Common/Config.php';
?&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Payment Response&lt;/title&gt;
&lt;link href="./css/style.css" type="text/css" rel="stylesheet" /&gt;
&lt;/head&gt;
&lt;body&gt; &lt;div class="phppot-container"&gt; &lt;h1&gt;Thank you for shopping with us.&lt;/h1&gt; &lt;p&gt;You have purchased "&lt;?php echo Config::PRODUCT_NAME; ?&gt;" successfully.&lt;/p&gt; &lt;p&gt;You have been notified about the payment status of your purchase shortly.&lt;/p&gt; &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h2 id="database-script">Database script</h2>
<p>Import the following SQL script to execute this example in your environment. It has the SQL to create tables created for this example and to build a relationship between them.</p>
<p>sql/structure.sql</p>
<pre class="prettyprint lang-php">--
-- Table structure for table `tbl_customer`
-- CREATE TABLE `tbl_customer` ( `id` int(11) NOT NULL, `stripe_customer_id` varchar(255) NOT NULL, `email` varchar(50) NOT NULL, `customer_created_datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `stripe_response` text NOT NULL, `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -------------------------------------------------------- --
-- Table structure for table `tbl_order`
-- CREATE TABLE `tbl_order` ( `id` int(11) NOT NULL, `order_reference_id` varchar(255) NOT NULL, `stripe_customer_id` varchar(255) DEFAULT NULL, `stripe_payment_intent_id` varchar(255) DEFAULT NULL, `amount` decimal(10,2) NOT NULL, `currency` varchar(10) NOT NULL, `order_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `order_status` varchar(25) NOT NULL, `stripe_checkout_response` text NOT NULL, `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -------------------------------------------------------- --
-- Table structure for table `tbl_payment`
-- CREATE TABLE `tbl_payment` ( `id` int(11) NOT NULL, `stripe_payment_intent_id` varchar(255) NOT NULL, `payment_create_at` timestamp NULL DEFAULT NULL, `payment_last_updated` timestamp NULL DEFAULT '0000-00-00 00:00:00', `billing_name` varchar(255) NOT NULL, `billing_email` varchar(255) NOT NULL, `payment_status` varchar(255) NOT NULL, `stripe_payment_response` text NOT NULL, `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1; --
-- Indexes for dumped tables
-- --
-- Indexes for table `tbl_customer`
--
ALTER TABLE `tbl_customer` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `stripe_customer_id` (`stripe_customer_id`); --
-- Indexes for table `tbl_order`
--
ALTER TABLE `tbl_order` ADD PRIMARY KEY (`id`), ADD KEY `stripe_payment_intent_id` (`stripe_payment_intent_id`), ADD KEY `stripe_customer_id` (`stripe_customer_id`); --
-- Indexes for table `tbl_payment`
--
ALTER TABLE `tbl_payment` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `stripe_payment_intent_id` (`stripe_payment_intent_id`); --
-- AUTO_INCREMENT for dumped tables
-- --
-- AUTO_INCREMENT for table `tbl_customer`
--
ALTER TABLE `tbl_customer` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --
-- AUTO_INCREMENT for table `tbl_order`
--
ALTER TABLE `tbl_order` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --
-- AUTO_INCREMENT for table `tbl_payment`
--
ALTER TABLE `tbl_payment` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --
-- Constraints for dumped tables
-- --
-- Constraints for table `tbl_order`
--
ALTER TABLE `tbl_order` ADD CONSTRAINT `tbl_order_ibfk_1` FOREIGN KEY (`stripe_payment_intent_id`) REFERENCES `tbl_payment` (`stripe_payment_intent_id`), ADD CONSTRAINT `tbl_order_ibfk_2` FOREIGN KEY (`stripe_customer_id`) REFERENCES `tbl_customer` (`stripe_customer_id`);
COMMIT;
</pre>
<h2 id="evaluate-integration-with-test-data">Evaluate integration with test data</h2>
<p>After integrating Stripe one-time payment, evaluate the integration with test card details.</p>
<p>The following test card details help to try a successful payment flow.</p>
<table class="tutorial-table" width="100%">
<tbody>
<tr>
<td>Card Number</td>
<td>4242424242424242</td>
</tr>
<tr>
<td>Expiry Month/Year</td>
<td>Any future date</td>
</tr>
<tr>
<td>CVV</td>
<td>Three-digit number</td>
</tr>
</tbody>
</table>
<p>Stripe provides more <a href="https://stripe.com/docs/testing" target="_blank" rel="noopener noreferrer">test card details</a> to receive more types of responses.</p>
<h2 id="stripe-one-time-payment-example-output">Stripe one-time payment example output</h2>
<p>This example displays a product tile with the Stripe Checkout button as shown below.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-12132" src="https://phppot.com/wp-content/uploads/2020/10/Stripe-Payment-Landing-Page.jpg" alt="Stripe Payment Landing Page" width="305" height="429" srcset="https://phppot.com/wp-content/uploads/2020/10/Stripe-Payment-Landing-Page.jpg 305w, https://phppot.com/wp-content/uploads/2020/10/Stripe-Payment-Landing-Page-213x300.jpg 213w" sizes="(max-width: 305px) 100vw, 305px"></p>
<p>On clicking the Checkout button, it redirects customers to the prebuilt Stripe hosted checkout page.</p>
<p><img loading="lazy" class="alignnone size-large wp-image-12133" src="https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-page-550x317.jpg" alt="Stripe Hosted Checkout Page" width="550" height="317" srcset="https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-page-550x317.jpg 550w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-page-300x173.jpg 300w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-page-768x443.jpg 768w, https://phppot.com/wp-content/uploads/2020/10/stripe-hosted-checkout-page.jpg 800w" sizes="(max-width: 550px) 100vw, 550px"></p>
<p>After processing the payment, Stripe will redirect customers to the success page URL.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-12170" src="https://phppot.com/wp-content/uploads/2020/10/payment-success-page.jpg" alt="Payment Success Page" width="520" height="148" srcset="https://phppot.com/wp-content/uploads/2020/10/payment-success-page.jpg 520w, https://phppot.com/wp-content/uploads/2020/10/payment-success-page-300x85.jpg 300w" sizes="(max-width: 520px) 100vw, 520px"></p>
<h2>Conclusion</h2>
<p>We have seen how to integrate the stripe hosted checkout in PHP with an example. Hope it is simple and easy to follow.</p>
<p>It helps to have a quick glance with the bullet points pre-requisites, implementation steps. It pinpoints the todo items in short.</p>
<p>The downloadable source code has the required vendor files. It is not needed to download libraries and SDK from anywhere.</p>
<p>With database intervention, the code is ready to integrate with a full-fledged application.</p>
<p>With the latest Stripe checkout version, it provides payment services with SCA and more advanced features.</p>
<p><a class="download" href="https://phppot.com/downloads/stripe-hosted-checkout.zip">Download</a></p>
<p> <!-- #comments --> </p>
<div class="related-articles">
<h2>Popular Articles</h2>
</p></div>
<p> <a href="https://phppot.com/php/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/#top" class="top">↑ Back to Top</a> </p>
</div>


https://www.sickgaming.net/blog/2020/10/01/stripe-one-time-payment-with-prebuilt-hosted-checkout-in-php/