How to Integrate Stripe Payment Gateway in PHP

Hey there! If you're looking to integrate Stripe payment gateway into your PHP website or application, you're in the right place. Stripe is a popular choice for processing online payments due to its simplicity and robust features.

In this guide, I'll walk you through the step-by-step process of integrating the Stripe payment gateway into your PHP project.

So, let's see how to integrate stripe payment gateway in php, php stripe integration, php payment gateway integration, stripe payment gateway integration, stripe API, and stripe payment gateway API in PHP.

stripe_payments_php

How to Integrate Stripe Payment Gateway in PHP: A Step-by-Step Guide

Step 1: Sign up for a Stripe Account

First things, you need to sign up for a Stripe account if you haven't already. Head over to the Stripe website and create an account.

 

Step 2: Obtain API Keys

To integrate Stripe into your PHP application, you'll need to obtain your API keys. In your Stripe dashboard, navigate to the Developers section and click on API keys.

Here, you'll find your publishable key and secret key. Keep these keys secure, as they will be used to authenticate your requests to the Stripe API.

 

Step 3: Install Stripe PHP Library

Now, let's set up the Stripe PHP library in your project. You can either download the library manually from the Stripe GitHub repository or install it via Composer, which is the preferred method.

If you're using Composer, simply run the following command in your project directory:

composer require stripe/stripe-php

Here is the directory structure.

|- Stripe-Payment-Gateway-Integration
|- public
 |- checkout.css
 |- checkout.js
 |- checkout.html
 |- create.php
|- composer.json
|- secrets.php

 

Step 4: Create PHP File

Now, we'll create a create.php file in the public folder and create PaymentIntent API. A PaymentIntent tracks the customer’s payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once.

<?php

require_once '../vendor/autoload.php';
require_once '../secrets.php';

$stripe = new \Stripe\StripeClient($stripeSecretKey);

header('Content-Type: application/json');

try {
    // retrieve JSON from POST body
    $jsonStr = file_get_contents('php://input');
    $jsonObj = json_decode($jsonStr);

    // Create a PaymentIntent with amount and currency
    $paymentIntent = $stripe->paymentIntents->create([
        'amount' => 10*100,
        'currency' => 'usd',
        // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.        
        'automatic_payment_methods' => [
            'enabled' => true,
        ],
    ]);

    $output = [
        'clientSecret' => $paymentIntent->client_secret,
    ];

    echo json_encode($output);
} catch (Error $e) {
    http_response_code(500);
    echo json_encode(['error' => $e->getMessage()]);
}

Also, we configure payment methods and we enable cards and other common payment methods by default. You can enable or disable payment methods directly in the Dashboard.

 

Step 5: Set Up Your Payment Form

Next, we'll need to create a payment form on your website where users can enter their payment details. Here's a basic example of stripe payment gateway integration in PHP.

In this, we'll load stripe.js and create a payment form.

checkout.html

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="utf-8" />
	<title>How to Integrate Stripe Payment Gateway in PHP - Techsolutionstuff</title>
	<meta name="description" content="A demo of a payment on Stripe" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<link rel="stylesheet" href="checkout.css" />
	<script src="https://js.stripe.com/v3/"></script>
	<script src="checkout.js" defer></script>
</head>

<body>
	<!-- Display a payment form -->
    <h3>How to Integrate Stripe Payment Gateway in PHP - Techsolutionstuff</h3>
	<form id="payment-form">
		<div id="payment-element">
			<!--Stripe.js injects the Payment Element-->
		</div>
		<button id="submit">
			<div class="spinner hidden" id="spinner"></div>
			<span id="button-text">Pay now</span>
		</button>
		<div id="payment-message" class="hidden"></div>
	</form>
</body>

</html>

 

Step 6: Initialize Stripe.js

Initialize Stripe.js with your publishable API keys. You’ll use Stripe.js to create the Payment Element and complete the payment on the client. Also, Fetch a PaymentIntent, Initialize Stripe Elements, and Create the PaymentElement.

checkout.js

const stripe = Stripe("pk_test_xxxxxxxxxxx");

// The items the customer wants to buy
const items = [{ id: "xl-tshirt" }];

let elements;

initialize();
checkStatus();

document
	.querySelector("#payment-form")
	.addEventListener("submit", handleSubmit);

// Fetches a payment intent and captures the client secret
async function initialize() {
	const { clientSecret } = await fetch("/create.php", {
		method: "POST",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({ items }),
	}).then((r) => r.json());

	elements = stripe.elements({ clientSecret });

	const paymentElementOptions = {
		layout: "tabs",
	};

	const paymentElement = elements.create("payment", paymentElementOptions);
	paymentElement.mount("#payment-element");
}

async function handleSubmit(e) {
	e.preventDefault();
	setLoading(true);

	const { error } = await stripe.confirmPayment({
		elements,
		confirmParams: {
			// Make sure to change this to your payment completion page
			return_url: "http://localhost:4242/checkout.html",
		},
	});

	// This point will only be reached if there is an immediate error when
	// confirming the payment. Otherwise, your customer will be redirected to
	// your `return_url`. For some payment methods like IDEAL, your customer will
	// be redirected to an intermediate site first to authorize the payment, then
	// redirected to the `return_url`.
	if (error.type === "card_error" || error.type === "validation_error") {
		showMessage(error.message);
	} else {
		showMessage("An unexpected error occurred.");
	}

	setLoading(false);
}

// Fetches the payment intent status after payment submission
async function checkStatus() {
	const clientSecret = new URLSearchParams(window.location.search).get(
		"payment_intent_client_secret"
	);

	if (!clientSecret) {
		return;
	}

	const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);

	switch (paymentIntent.status) {
		case "succeeded":
			showMessage("Payment succeeded!");
			break;
		case "processing":
			showMessage("Your payment is processing.");
			break;
		case "requires_payment_method":
			showMessage("Your payment was not successful, please try again.");
			break;
		default:
			showMessage("Something went wrong.");
			break;
	}
}

// ------- UI helpers -------

function showMessage(messageText) {
	const messageContainer = document.querySelector("#payment-message");

	messageContainer.classList.remove("hidden");
	messageContainer.textContent = messageText;

	setTimeout(function () {
		messageContainer.classList.add("hidden");
		messageContainer.textContent = "";
	}, 4000);
}

// Show a spinner on payment submission
function setLoading(isLoading) {
	if (isLoading) {
		// Disable the button and show a spinner
		document.querySelector("#submit").disabled = true;
		document.querySelector("#spinner").classList.remove("hidden");
		document.querySelector("#button-text").classList.add("hidden");
	} else {
		document.querySelector("#submit").disabled = false;
		document.querySelector("#spinner").classList.add("hidden");
		document.querySelector("#button-text").classList.remove("hidden");
	}
}

 

Step 7: Configure Secret File

Now, we'll create a secrets.php file. and add the stripe secret key to that file.

<?php
// Keep your Stripe API key protected by including it as an environment variable
// or in a private script that does not publicly expose the source code.

// This is a public sample test API key.
// Don’t submit any personally identifiable information in requests made with this key.
// Sign in to see your own test API key embedded in code samples.
$stripeSecretKey = 'sk_test_xxxxxxxxxxxxxxxx';

 

Step 8: Style the Payment Element

Customize the Payment Element UI by creating an appearance object and initializing Elements with it. Use your company’s color scheme and font to make it match with the rest of your checkout page.

/* Variables */
* {
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  display: flex;
  justify-content: center;
  align-content: center;
  height: 100vh;
  width: 100vw;
}

form {
  width: 30vw;
  min-width: 500px;
  align-self: center;
  box-shadow: 0px 0px 0px 0.5px rgba(50, 50, 93, 0.1),
    0px 2px 5px 0px rgba(50, 50, 93, 0.1), 0px 1px 1.5px 0px rgba(0, 0, 0, 0.07);
  border-radius: 7px;
  padding: 40px;
}

.hidden {
  display: none;
}

#payment-message {
  color: rgb(105, 115, 134);
  font-size: 16px;
  line-height: 20px;
  padding-top: 12px;
  text-align: center;
}

#payment-element {
  margin-bottom: 24px;
}

/* Buttons and links */
button {
  background: #5469d4;
  font-family: Arial, sans-serif;
  color: #ffffff;
  border-radius: 4px;
  border: 0;
  padding: 12px 16px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  display: block;
  transition: all 0.2s ease;
  box-shadow: 0px 4px 5.5px 0px rgba(0, 0, 0, 0.07);
  width: 100%;
}
button:hover {
  filter: contrast(115%);
}
button:disabled {
  opacity: 0.5;
  cursor: default;
}

/* spinner/processing state, errors */
.spinner,
.spinner:before,
.spinner:after {
  border-radius: 50%;
}
.spinner {
  color: #ffffff;
  font-size: 22px;
  text-indent: -99999px;
  margin: 0px auto;
  position: relative;
  width: 20px;
  height: 20px;
  box-shadow: inset 0 0 0 2px;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
}
.spinner:before,
.spinner:after {
  position: absolute;
  content: "";
}
.spinner:before {
  width: 10.4px;
  height: 20.4px;
  background: #5469d4;
  border-radius: 20.4px 0 0 20.4px;
  top: -0.2px;
  left: -0.2px;
  -webkit-transform-origin: 10.4px 10.2px;
  transform-origin: 10.4px 10.2px;
  -webkit-animation: loading 2s infinite ease 1.5s;
  animation: loading 2s infinite ease 1.5s;
}
.spinner:after {
  width: 10.4px;
  height: 10.2px;
  background: #5469d4;
  border-radius: 0 10.2px 10.2px 0;
  top: -0.1px;
  left: 10.2px;
  -webkit-transform-origin: 0px 10.2px;
  transform-origin: 0px 10.2px;
  -webkit-animation: loading 2s infinite ease;
  animation: loading 2s infinite ease;
}

@-webkit-keyframes loading {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes loading {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@media only screen and (max-width: 600px) {
  form {
    width: 80vw;
    min-width: initial;
  }
}

 

Step 9: Test the integration

Run your server and go to localhost:4242/checkout.html.

php -S 127.0.0.1:4242 --docroot=public

 


You might also like:

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS