Integrating a payment gateway in your checkout system allows your customers to input their payment details and securely finalize purchases with confidence. A reliable payment gateway helps build trust by safeguarding sensitive financial information through encryption and compliance standards.
By offering diverse payment options such as credit or debit cards, mobile money, mobile wallets, and bank transfers, you can improve the shopping experience and reduce cart abandonment by catering to your customer's preferences. Once a payment is processed, the system automatically confirms the order and generates receipts, assuring your customers that their transaction was completed successfully.
This guide will walk you through implementing a payment gateway in your checkout system using Flutterwave. Flutterwave’s platform supports multiple payment options, such as card payments, mobile money, and bank transfers. You also have access to advanced fraud detection and encryption to protect your business and customers.
By integrating Flutterwave, you can easily track your sales, offer a secure checkout experience, and boost overall performance by building customer confidence.
Prerequisites
Before you begin integrating the payment gateway, you should have the following:
- Node.js Installed on your machine. You can download it here.
- An active Flutterwave business account. If you don’t have one, you can sign up here.
- You should also have a basic knowledge of JavaScript and React.
Choosing the Right Integration Method
Implementing a payment method incorrectly can render your transactions prone to failures and lead to issues like abandoned carts and a loss of customer trust, which can hurt your business.
On the other hand, choosing the right method based on your project requirements, complexity, and customization level helps you avoid these problems. There are three common approaches:
The HTML Checkout Method is a quick and simple way to integrate a payment gateway using pre-built components provided by the payment gateway. This involves embedding a ready-to-use checkout form or button into your website’s HTML code.
The Inline Integration Method can be used on the client side of your application, all you need to do is include a JavaScript script on your checkout page and write a callback on your payment button. When your customer clicks on the payment button and the payment is complete, they will then be redirected back to your app.
The Standard Integration Method offers you a more flexible control over your checkout form, allowing you to design an experience to match your brand and provide custom features. All you need to do is directly call API endpoints on your server-side app passing in the the necessary parameters as payloads. You will then get a response url to complete the payment, after which they will be redirected back to your application.
Integrating with SDKs allows you to streamline your payment process by utilizing pre-built frontend libraries, simplifying the handling of payment functionalities. By incorporating these front-end SDKs into your application, you can quickly implement payments, manage transactions, and handle callbacks with ease.
Setting up your Development Environment
In the next few steps, you’ll create a minimal checkout system, Integrating Flutterwave’s react SDK to handle customer payment.
Before you start implementing, let's set up your development environment.
Run the command on your preferred terminal to create a react app.
npx create-react-app checkout-app
Change to your newly created directory with the command.
cd checkout-app
Head over to your Flutterwave dashboard and navigate to the Setting > API key section to copy your API keys.
Create a
.env
file and add your testsecret_key
to the environment variableREACT_APP_FLW_SECRET_KEY
.Run the command
npm i flutterwave-react-v3
to install the Flutterwave SDK.
Building the Pre-Checkout Page
Next, you’ll create a minimal pre-checkout page for your e-commerce application.
-
Create the App Function
Go to thesrc/App.js
file and delete the page content. Paste the code below to importreact
, and the Flutterwave react methodsflutterwaveButton
andclosePaymentModal
.
Copy and add the code below into the file to create theAPP
function.
import React, { useState } from 'react'; import { flutterwaveButton, closePaymentModal } from 'flutterwave-react-v3'; import './App.css'; export default function App() { }
-
Adding Dummy Data
Create an objectUserDetails
inside theApp()
function to simulate the user’s information, and add a list of items to simulate the products in the customer’s cart. Ideally, this data would come from your commerce and user management system.
export default function App() { // User dummy data const userDetails = { name: 'John Doe', email: 'johndoe@gmail.com', phonenumber: '07059514549', address: "Somewhere on the planet", delivery: "Doorstep", }; export default function App() { // User dummy data goes here // Dummy items the user is buying const items = [ { id: 1, name: 'Laptop', price: 30000 }, { id: 2, name: 'Smartphone', price: 20000 }, { id: 3, name: 'Headphones', price: 25000 }, ]; } const totalAmount = items.reduce((sum, item) => sum + item.price, 0); }
-
Track Payment Status
Add the code below to yourApp.js
to create apaymentCompleted
state to keep track of the payment status and assign the initial state tofalse
. The code below will also create apaymentResponse
state to keep track of thepaymentResponse
and assign the initial value tonull
.
export default function App() { // userDetails object code goes here // array of items and totalAmount goes here const [paymentCompleted, setPaymentCompleted] = useState(false); const [paymentResponse, setPaymentResponse] = useState(null); }
-
Configure the Flutterwave Payment
Copy the code below to add a configuration object to initiate the Flutterwave package.
export default function App() { // dummy data code goes here // paymentCompleted and paymentResponse code goes here const config = { public_key: process.env.REACT_APP_FLW_SECRET_KEY, tx_ref: Date.now(), amount: totalAmount, currency: 'NGN', payment_options: 'card,mobilemoney,ussd', customer: { email: userDetails.email, phone_number: userDetails.phonenumber, name: userDetails.name, }, customizations: { title: 'My store', description: 'Payment for items in cart', logo: '', // Add a logo URL if you have one }, }; };
-
Configure the Flutterwave Payment Button
Now that you've set up the payment configuration, the next step is to useFlutterwaveButton
to trigger the payment process. You'll define afxConfig
object in yourApp()
component that includes properties like the button text, a callback function to handle the payment response, and conditional rendering based on the payment status.
export default function App() { // Confg code goes here const fwConfig = { ...config, text: 'Checkout', callback: (response) => { console.log(response); setPaymentCompleted(true); // Set the payment as completed setPaymentResponse(response); // Store the response to display it on the receipt closePaymentModal(); // Close the modal programmatically }, onClose: () => {}, }; }
-
Conditional Rendering
Now, you need to show different content to the customer based on whether the payment is completed or not. Initially, the customer will see the pre-checkout details (order summary and user information). After payment, they will be shown a receipt.
Update yourApp()
component with the code below.
export default function App() { // fwConfig object goes here return ( <div className="App"> {paymentCompleted ? ( // Show receipt when payment is completed <div> <h1>Payment Complete</h1> <p>Thank you for your payment, {userDetails.name}!</p> <p>Transaction Reference: {paymentResponse?.tx_ref}</p> <p>Total Amount Paid: ₦{totalAmount}</p> <p>Items Purchased:</p> <ul> {items.map((item) => ( <li key={item.id}> {item.name}: ₦{item.price} </li> ))} </ul> <p>A receipt has been sent to your email: {userDetails.email}</p> </div> ) : ( // Show order confirmation and payment button before payment <> <h1>Order Confirmation</h1> {/* Display the items the user is purchasing */} <div> <h3>Items in your cart:</h3> <ul> {items.map((item) => ( <li key={item.id}> {item.name}: ₦{item.price} </li> ))} </ul> <h3>Total: ₦{totalAmount}</h3> </div> {/* Display user details */} <div> <h3>User Information</h3> <p>Name: {userDetails.name}</p> <p>Email: {userDetails.email}</p> <p>Phone: {userDetails.phonenumber}</p> <p>Address: {userDetails.address}</p> <p>Method of delivery: {userDetails.delivery}</p> </div> {/* flutterwave payment button */} <FlutterwaveButton {...fwConfig} /> </> )} </div> ); };
Here is what it should look like after you’ve completed the
App.js
page. -
Styling your App
Head over to your App.css file and replace the entire file with the code below to add a css styling to your checkout application.
.App { font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; background-color: #f9f9f9; border-radius: 8px; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); } h1, h3 { color: #333; text-align: center; } ul { list-style-type: none; padding: 0; } li { background-color: #fff; padding: 10px; margin: 5px 0; border: 1px solid #ddd; border-radius: 5px; } h3 { font-size: 1.2em; margin-top: 20px; color: #007bff; text-align: right; } div.user-info { background-color: #eef; padding: 15px; border-radius: 5px; margin-top: 20px; } .user-info p { margin: 5px 0; color: #555; } button { display: block; width: 100%; background-color: #28a745; color: white; padding: 10px; border: none; border-radius: 5px; font-size: 1.1em; cursor: pointer; transition: background-color 0.3s ease; } button:hover { background-color: #218838; } div.receipt { padding: 20px; background-color: #e9ffe9; border: 2px solid #28a745; border-radius: 5px; } .receipt p { color: #333; } .receipt ul { border-top: 1px solid #28a745; padding-top: 10px; } .receipt li { font-size: 1em; }
To start your react application, run the command.
npm start
You’ll be redirected to your browser with the URL http://localhost:3000
.
Checking Out
In your browser, you should see the following screen.
When you click on the Checkout
button to initiate the payment process, you will be redirected to the Flutterwave payment interface, as shown in the image below.
This page gives the customer the option to use different payment methods like card, USSD, bank or bank transfer. Here are some dummy data you can use to simulate a successful card and bank payment.
# Successful Card Payment
Mastercard:{
card_number: 5531886652142950,
expiry: 09/32
cvv: 564
otp: 12345
pin: 3310
}
# Bank Transfer
{
bank: Access Bank (440)
account_number: 0690000031
otp: 123456
}
After a successful payment, you’ll get a response from Flutterwave that looks like this on your developer console in your browser.
{status: 'successful', customer: {…}, transaction_id: 6713260, tx_ref: 1726799191947, flw_ref: '1726799239531-FLW-MOCK-REF', …}
amount: 75000
charge_response_code: "00"
charge_response_message: "Pending validation"
charged_amount: 75000
created_at: "2024-09-20T02:27:19.000Z"
currency: "NGN"
customer: {name: 'John Doe', email: 'johndoe@gmail.com', phone_number: '07059514549'}
flw_ref: "1726799239531-FLW-MOCK-REF"
redirectstatus: undefined
status: "successful"
transaction_id: 6713260
tx_ref: 1726799191947
Flutterwave will redirect your customer back to your application where they can confirm the payment has been made, like in the image below.
Wrapping Up
Having completed the steps in this tutorial, you’ve learned how to implement Flutterwave’s payment gateway in a React-based e-commerce app, providing support for multiple payment methods and currencies.
In a production-ready workflow, it's important to verify each transaction before issuing any value to ensure that the payment was successful and legitimate. Flutterwave employs multiple fraud detection mechanisms, like advanced security protocols and 3D secure authentication, to further secure your transactions. By incorporating these practices, you can enhance the security and reliability of your payment process.
Check out the full project on GitHub. Additional payment integration methods can be found in the Flutterwave documentation:
Top comments (2)
Thank you this is an amazing piece, This was really helpful
I'm glad it helped