Checkout SDK
Simplify payment collection across Web, iOS, Android, and Flutter applications using Xtopay's Checkout SDKs.
Checkout SDK
The Checkout SDK provides a simplified way for developers to accept online payments within web, mobile, and cross-platform applications. Instead of redirecting customers away from your application, the Checkout SDK opens a native overlay interface to process card, mobile money, and wallet payments securely in-context.
JavaScript Web SDK
The Xtopay JavaScript SDK supports three primary methods of integration:
- Redirect Integration: Opens the hosted payment page in a new browser tab or window.
- Iframe Integration: Embeds the checkout experience inside a secure iframe container on your webpage.
- Modal Integration: Loads the checkout flow inside a lightbox popup overlay on top of your webpage.
Installation
To integrate the JavaScript SDK into your web project, install the NPM package or include the CDN script tag.
npm install @xtopay/checkoutPre-Checkout Flow
[!IMPORTANT] Secure Session Initialization Before invoking the frontend SDK, your backend server must create a checkout session via
POST /v1/payments. Never initialize checkout with your Secret API Key on the client side.
Backend Session Creation
On your server, initiate the session and return the payload to your client app:
{
"success": true,
"data": {
"amount": 10000,
"currency": "GHS",
"description": "Premium Plan Purchase",
"clientReference": "f03dbdcf8d4040dd88d0a82794b0229f",
"customer": {
"name": "Kwame Mensah",
"email": "kwame@example.com",
"phone": "+233241234567"
}
}
}Web Integration Methods
1. Redirect Integration
Opens the payment page in a new window or tab.
import XtopayCheckout from "@xtopay/checkout";
const checkout = new XtopayCheckout();
// Purchase information returned from your pre-checkout backend
const purchaseInfo = {
amount: 10000, // GHS 100.00
purchaseDescription: "Premium Plan Purchase",
customerPhoneNumber: "+233241234567",
clientReference: "f03dbdcf8d4040dd88d0a82794b0229f"
};
const config = {
publicKey: "xtpk_live_xxxxxxxxxxxxxxxxxxxx",
branding: "enabled",
callbackUrl: "https://merchant.com/webhooks/xtopay"
};
// Redirect customer to checkout
const initiatePayment = () => {
checkout.redirect({
purchaseInfo,
config
});
};2. Iframe Integration
Embeds the checkout flow inside a local container element.
Add a designated container element in your HTML:
<div id="xtopay-checkout-iframe"></div>Initialize the inline iframe using the SDK:
import XtopayCheckout from "@xtopay/checkout";
const checkout = new XtopayCheckout();
const purchaseInfo = {
amount: 10000,
purchaseDescription: "Premium Plan Purchase",
customerPhoneNumber: "+233241234567",
clientReference: "f03dbdcf8d4040dd88d0a82794b0229f"
};
const config = {
publicKey: "xtpk_live_xxxxxxxxxxxxxxxxxxxx",
branding: "enabled",
callbackUrl: "https://merchant.com/webhooks/xtopay"
};
const iframeStyle = {
width: "100%",
height: "550px",
border: "none"
};
const openEmbeddedCheckout = () => {
checkout.initIframe({
purchaseInfo,
config,
iframeStyle,
callBacks: {
onInit: () => console.log("Iframe initialized"),
onLoad: () => console.log("Iframe finished loading"),
onPaymentSuccess: (data) => console.log("Payment successful", data),
onPaymentFailure: (error) => console.error("Payment failed", error),
onFeesChanged: (fees) => console.log("Applicable fees changed", fees),
onResize: (size) => console.log("Iframe resized to:", size.height)
}
});
};3. Modal Integration
Renders the checkout process inside a dismissible screen overlay popup.
import XtopayCheckout from "@xtopay/checkout";
const checkout = new XtopayCheckout();
const purchaseInfo = {
amount: 10000,
purchaseDescription: "Premium Plan Purchase",
customerPhoneNumber: "+233241234567",
clientReference: "f03dbdcf8d4040dd88d0a82794b0229f"
};
const config = {
publicKey: "xtpk_live_xxxxxxxxxxxxxxxxxxxx",
branding: "enabled",
callbackUrl: "https://merchant.com/webhooks/xtopay"
};
const openCheckoutPopup = () => {
checkout.openModal({
purchaseInfo,
config,
callBacks: {
onInit: () => console.log("Modal initialized"),
onLoad: () => console.log("Modal content loaded"),
onPaymentSuccess: (data) => {
console.log("Payment succeeded:", data);
checkout.closePopUp(); // Dismiss modal overlay
},
onPaymentFailure: (error) => console.error("Payment failed:", error),
onClose: () => console.log("Checkout modal dismissed by user")
}
});
};JS SDK Configurations
| Parameter | Type | Required | Description |
|---|---|---|---|
purchaseInfo | Object | Yes | Transaction details. |
purchaseInfo.amount | Number | Yes | Charge amount in minor units (e.g. 10000 = GHS 100.00). |
purchaseInfo.purchaseDescription | String | Yes | Item purchase summary. |
purchaseInfo.customerPhoneNumber | String | Yes | Mobile wallet or contact phone number. |
purchaseInfo.clientReference | String | Yes | Unique string reference for order mapping. |
config | Object | Yes | Session configurations. |
config.publicKey | String | Yes | Client-side API key. |
config.branding | String | No | "enabled" to show merchant headers/logos; "disabled" to hide them. |
config.callbackUrl | String | Yes | Target url to receive payment notification updates. |
Android SDK
The Xtopay Android SDK simplifies checkout integration inside native Kotlin or Java applications.
Installation
Add the maven coordinates into your module's build.gradle dependencies:
dependencies {
implementation "com.xtopay:merchant-checkout-sdk:1.0.0"
}Creating Checkout Intent
To initialize the checkout controller UI, configure the intent variables using the CheckoutIntent.Builder utility:
import com.xtopay.checkout.CheckoutIntent
import com.xtopay.checkout.ThemeConfig
import java.util.UUID
val themeConfig = ThemeConfig().apply {
primaryColor = "#7C3AED" // Custom styling theme color
}
val checkoutIntent = CheckoutIntent.Builder(this)
.setAmount(100.0) // Transaction amount in base units
.setApiKey("xtpk_live_xxxxxxxxxxxxxxxxxxxx")
.setMerchantId("11684") // Collection account ID
.setClientReference(UUID.randomUUID().toString())
.setCustomerPhoneNumber("+233241234567")
.setDescription("Order #99283")
.setCallbackUrl("https://merchant.com/webhooks/xtopay")
.setTheme(themeConfig)
.build()
startActivityForResult(checkoutIntent, CHECKOUT_REQUEST_CODE)Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | Double | Yes | Payment amount. |
apiKey | String | Yes | Base64 or plain client Public Key (xtpk_...). |
merchantId | String | Yes | Collection merchant ID. |
clientReference | String | Yes | Unique transaction ID (max 36 chars). |
customerPhoneNumber | String | Yes | Customer phone number. |
callbackUrl | String | Yes | Merchant webhook callback URL. |
Handling Results
Override your Activity's or Fragment's onActivityResult block to process payment completion results:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CHECKOUT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
val status = data?.getParcelableExtra<CheckoutStatus?>(CheckoutStatus.CHECKOUT_RESULT)
status?.let {
val isSuccess = it.isPaymentSuccessful
val transactionId = it.transactionId
val methodUsed = it.paymentMethod
val isCanceled = it.isCanceled
if (isSuccess) {
// Payment succeeded
}
}
}
}iOS SDK
The Xtopay iOS SDK allows integration inside Swift or Objective-C iOS applications.
Installation
Include the SDK pod identifier inside your Podfile:
pod 'XtopayMerchantCheckoutSDK', '~> 1.0.0'Run pod install from your command line to sync project settings.
Initialization & View Presentation
Create configuration and purchase information profiles before calling the presentation controller:
import xtopay_merchant_checkout_sdk
// Step 1: Initialize Configuration Profile
let configuration = XtopayCheckoutConfiguration(
merchantId: "11684",
callbackUrl: "https://merchant.com/webhooks/xtopay",
merchantApiKey: "xtpk_live_xxxxxxxxxxxxxxxxxxxx"
)
// Step 2: Initialize Purchase Specifications
let purchaseInfo = PurchaseInfo(
amount: 100.0,
customerPhoneNumber: "+233241234567",
purchaseDescription: "Invoice Item #10023",
clientReference: UUID().uuidString
)
// Step 3: Launch Checkout View Overlay
CheckoutViewController.presentCheckout(
from: self,
with: configuration,
and: purchaseInfo,
delegate: self,
tintColor: UIColor.purple
)Delegate Callbacks
To check the checkout status result, implement the PaymentFinishedDelegate protocol inside your view controller:
extension MyViewController: PaymentFinishedDelegate {
func checkStatus(value: PaymentStatus, transactionId: String) {
switch value {
case .paymentSuccessful:
print("Payment completed successfully. Txn: \(transactionId)")
case .paymentFailed:
print("Payment authorization failed")
case .userCancelledPayment:
print("Customer closed the checkout interface without paying")
case .unknown:
print("Payment state undefined. Query backend status API")
@unknown default:
break
}
}
}Flutter SDK
Accept payments inside cross-platform Flutter applications on iOS and Android.
Installation
Open your project's pubspec.yaml file and add the git dependency reference:
dependencies:
xtopay_merchant_checkout_sdk:
git:
url: https://github.com/xtopay/xtopay-flutter-merchant-checkout-sdk.git
ref: mainIntegration
Load the widgets and push the screen view configuration onto your navigation stack:
import 'package:xtopay_merchant_checkout_sdk/xtopay_merchant_checkout_sdk.dart';
// Create checkout settings
final configuration = XtopayCheckoutConfiguration(
merchantId: "11684",
callbackUrl: "https://merchant.com/webhooks/xtopay",
merchantApiKey: "xtpk_live_xxxxxxxxxxxxxxxxxxxx"
);
// Define purchase parameters
final purchaseInfo = PurchaseInfo(
amount: 100.0,
customerPhoneNumber: "+233241234567",
purchaseDescription: "Store Checkout Item #8812",
clientReference: "txn_8812_unique"
);
// Trigger payment screen
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return CheckoutScreen(
purchaseInfo: purchaseInfo,
configuration: configuration,
themeConfig: ThemeConfig(primaryColor: Colors.deepPurple),
);
},
),
);
if (result is CheckoutCompletionStatus) {
if (result == CheckoutCompletionStatus.paymentSuccessful) {
// Payment success
} else if (result == CheckoutCompletionStatus.userCancelledPayment) {
// Customer dismissed checkout
}
}Webhook Callbacks
When using the Checkout SDK, Xtopay registers the customer actions and performs asynchronous postback webhooks to the callback URL configured in the payment object parameters.
Sample Webhook (Successful Payment)
{
"ResponseCode": "0000",
"Message": "success",
"Data": {
"Amount": 100.00,
"Charges": 1.50,
"AmountAfterCharges": 98.50,
"Description": "The MTN Mobile Money payment has been approved and processed successfully",
"ClientReference": "f03dbdcf8d4040dd88d0a82794b0229f",
"TransactionId": "4a5f113ceeec419399753dc7d704454d",
"ExternalTransactionId": "0000007375832466",
"AmountCharged": 100.00,
"OrderId": "4a5f113ceeec419399753dc7d704454d",
"PaymentDate": "2026-06-06T17:18:58Z"
}
}Sample Webhook (Failed Payment)
{
"ResponseCode": "2001",
"Message": "failed",
"Data": {
"Amount": 100.00,
"Charges": 0.00,
"AmountAfterCharges": 100.00,
"Description": "Transaction failed: Insufficient wallet balance",
"ClientReference": "f03dbdcf8d4040dd88d0a82794b0229f",
"TransactionId": "478e03ec641b4a4287ca7dd0ec0e199b",
"ExternalTransactionId": "42042068855",
"AmountCharged": 100.00,
"OrderId": "478e03ec641b4a4287ca7dd0ec0e199b",
"PaymentDate": "2026-06-06T17:00:33Z"
}
}How is this guide?