Logo

dev-resources.site

for different kinds of informations.

Receive payments easily using Stripe and PHP

Published at
9/12/2024
Categories
stripe
php
payments
integration
Author
icolomina
Categories
4 categories in total
stripe
open
php
open
payments
open
integration
open
Author
9 person written this
icolomina
open
Receive payments easily using Stripe and PHP

Introduction

Many times, our applications require to provide an easy way to make payments to purchase products or services. Stripe can be a good option to receive payments. In this post, we are going to learn how to create a stripe payment link so that you can redirect your users to those link to send their payments.

What is Stripe ?

Stripe is a technology company that provides online payment processing services, allowing businesses to accept payments over the internet. It offers a suite of tools and APIs that enable companies to manage online transactions, subscriptions, and other payment-related tasks.

Before starting to write code, we must understand the following Stripe components:

  • Product: A product represents a good or service that you want to sell. It includes the name, description, and pricing details among others.
  • Price: A price is a specific pricing configuration for a product. It defines the amount that a customer will pay for a product, as well as any additional pricing details such as currency, billing cycle, and pricing tiers. As an example, for a service named "Community Membership" you could have two prices:

    • Annual for which users would pay 50$ per year.
    • Monthly for which users would pay 3.5$ per month.
  • Payment link: A payment link is a URL that allows customers to make a payment for a specific price. When a customer clicks on a payment link, they are redirected to a Stripe-hosted payment page where they can enter their payment information and complete the transaction. Payment links can be shared via email, messaging apps, or embedded on your website.

Prices also allow us to define the payment type which can be "recurring" or "one_time". For the "Community membership example", the annual payment could be one_type and the monthly one could be recurrent. Every year, the users would renew (or not) their memberships and would choose the payment type again.

Install the Stripe PHP component

The stripe php library can be installed using composer, so, to install it, you simply have to execute the following command in your project root folder:

composer require stripe/stripe-php
Enter fullscreen mode Exit fullscreen mode

Retreiving the Developer API key

Before you can retrieve your api key, you must be registered on Stripe. One you have been registered, you can follow the next steps:

  • Log-in to your Stripe account.
  • Click on the gear icon in the top right corner of the screen and select "Developers".
  • Click on "API keys" and you will be able to create them.

Create a Stripe Price

We can create the Stripe Price creating the product first and then the price or embedding the product name into the price options. Let's code it using the first way so we can see all the process.

$stripe = new \Stripe\StripeClient(<your_stripe_api_key>);

$product = $stripe->products->create([
     'name' => 'Community Subscription',
     'description' => 'A Subscription to our community',
]);

$price  = $stripe->prices->create([
     'currency' => 'usd',
     'unit_amount' => 5025,
     'product': $product->id,
     'type' => 'one_time'
]);
Enter fullscreen mode Exit fullscreen mode

Let's explain the above code step by step:

  • We create a new StripeClient passing our stripe api keys.
  • Then, we create a new product named "Community Subscription".
  • Finally, we create a price for the recently created product with the following features:
    • It uses de USD currency.
    • It references the created product by its id.
    • The payment will not be recurrent.

The unit_amount parameter deserves special attention. The Stripe documentation says the following about unit_amount: "A positive integer in cents (or 0 for a free price) representing how much to charge." This means that we must multiply the price by 100 to convert it to cents before passing it to the unit_amount parameter. For example, if the price is $10.99, we would set unit_amount to 1099. This is a common gotcha, so be sure to double-check your code to avoid any unexpected pricing issues.

For instance, if you have an "$amount" variable which holds a float value as amount, you could code something like this:

$formattedAmount = (int)($amount * 100);
Enter fullscreen mode Exit fullscreen mode

Create the payment link

So far, we have a price created with a correctly formatted amount. Now its time to create the payment link.

$stripe = new \Stripe\StripeClient(<your_stripe_api_key>);
$paymentLink = $stripe->paymentLinks->create([
     'line_items' => [
        [
           'price' => $price->id,
           'quantity' => 1,
        ]
     ],
     'after_completion' => [
        'type' => 'redirect',
        'redirect' => [
           'url' => <your redirect link>
        ]
     ]
]);
Enter fullscreen mode Exit fullscreen mode

Let's explain it step by step:

  • We create the StripeClient object as before.
  • Then, we create the payment link by using the following options:
    • line_items: Here you can include all the items we want to add for selling. In this case we only add the created price and we only sell one unit.
    • after_completion: We instruct Stripe to redirect to an url after the payment is completed.

We could redirect to an intermediate url which could perform some stuff such as updating our database register payment. The following code shows a simple Symfony controller which would perform the required tasks and then would redirect to the final url where the user will see that the payment has been completed.

class StripeController extends AbstractController
{

    #[Route('/confirm-payment', name: 'confirm-payment', methods: ['GET'])]
    public function confirmPayment(Request $request): Response
    {
        // Here you perform the necessary stuff
        $succeedUrl = '...';
        return new RedirectResponse($succeedUrl);
    }
}
Enter fullscreen mode Exit fullscreen mode

After we have created the PaymentLink object, we can access the string payment url by the url property:

$paymentUrl = $paymentLink->url;
Enter fullscreen mode Exit fullscreen mode

Using a webhook to receive confirmations

Although we could perform that necessary stuff in the intermediate url, it would be better to set and endpoint as a webhook on your stripe account and register to the event you want to be notified.
You can verify the webhook origin by checking the signature that Stripe sends as a header with your endpoint secret (you can get your endpoint secret after configuring the webhook in your stripe account).

#[Route('/stripe/webhook', name: 'stripe_webhook', methods: ['POST'])]
public function stripeWebhook(Request $request): JsonResponse
{
    $stripeEndpointSecret = '...' ; // your endpoint secret
    $sigHeader = $request->server->get('HTTP_STRIPE_SIGNATURE');
    $event = Webhook::constructEvent($request->getContent(), $sigHeader, $stripeEndpointSecret){
    if($event->type === 'checkout.session.completed') {
        // do your stuff
    }

    return new JsonResponse(null, 204);
}
Enter fullscreen mode Exit fullscreen mode

The above symfony controller receives a Stripe webhook and proceeds as follows:

  • Gets the signature from the request server array.
  • Constructs the event using the method constructEvent of the stripe-php Webhook class. The constructEvent validates the signature so you must not do it.
  • If the event type is the one you are waiting for, then your stuff will be executed.
  • A 2xx response is returned so that Stripe knows we've been successfully received the hook.

Conclusion

In this post we have learned how to configure our php backend to easily accept payments with stripe using the stripe-php component.
Processing the payments in your php backend offers some advantages such as:

  • Keep sensitive payment information, such as the API keys, secure.
  • Gives more control over the payment flow and allows for greater flexibility in handling different payment scenarios.

If you like my content and enjoy reading it and you are interested in learning more about PHP, you can read my ebook about how to create an operation-oriented API using PHP and the Symfony Framework. You can find it here: Building an Operation-Oriented Api using PHP and the Symfony Framework: A step-by-step guide

payments Article's
30 articles in total
Favicon
Open Banking: Revolutionising the future of financial services
Favicon
Direct debit vs. recurring card payments: Choosing the best option for gyms and wellness centers
Favicon
πŸ—ž Rapyd Developer Newsletter: December 2024 πŸ’° From API Security to Global FX: Must-Know Dev Tools This Month
Favicon
The future of fitness: What to expect in 2025 and beyond
Favicon
Creating and Paying a Freight Invoice with the Rapyd API and FX
Favicon
What is SASSA?
Favicon
How is subscription billing impacting the fitness industry?
Favicon
Top 5 Invoice Generator Apps to Streamline Your Business
Favicon
AWS India customers can now setup automated recurring payments on their cards
Favicon
How to Integrate Crypto Payments in Your Apps & Build Your Own Crypto Payment Gateway with ZinariPays OpenAPI
Favicon
Understanding SEPA and Cross-Border Payments
Favicon
How to Streamline Payment Processing for Your Business with LSP
Favicon
Using Rapyd for Your Gig Economy Payment Gateway and Disbursement Platform
Favicon
A Developer's Guide to the newΒ iDEAL
Favicon
ZinariPay 2.0.0: The New Era of Cryptocurrency Payments Integration
Favicon
A Complete Guide to the Types of Payment Methods in Nigeria
Favicon
Receive payments easily using Stripe and PHP
Favicon
Streamline Group Payments with Pay Calculator: A Web App to Balance Shared Expenses
Favicon
Financial Integration Use Cases for Developers
Favicon
How to Make In-App Payments Using the Rapyd Bank Transfer API
Favicon
How to Integrate ZinariPay with Your Application Using the CDN
Favicon
Introducing ZinariPay: The Future of Cryptocurrency Payments
Favicon
What Are the Most Common Issues with PayPal Payments?
Favicon
Understanding Credit Card Decline Codes: A Developer's Guide to Error Handling with Rapyd
Favicon
Creating and Paying a Delivery Invoice with the Rapyd API
Favicon
The Power of Digital Payments in Upgrading Lives & Communities
Favicon
Refunds Demystified Part #1 : Why do refunds take time?
Favicon
πŸ—ž Rapyd Developer Newsletter: July 2024 πŸ’³ 🧩 Financial Integration Use Cases for Developers + EMEA Payout Method Types
Favicon
Tokenization vs encryption
Favicon
Building with and Testing Rapyd's OpenAPI

Featured ones: