InlineJS

In A Nutshell
In a nutshell

The InlineJS library provides a collection of methods that allow you accept payment in your web application.

Introduction

InlineJS is Paystack’s Javascript library that offers a simple, secure, and convenient payment flow for web applications. It provides methods for initiating different types of payments e.g one time, recurring, split etc. and handle payment state, all with a few lines of code.

Browser support

Paystack InlineJS is designed to support all recent versions of major browsers. The library is compiled to ES5 and poly-filled to ensure it can work on as many devices as possible.

We do not support outdated browsers like IE9 nor browsers that disable the use of Javascript, like Opera mini.

  • We require TLS 1.2 to be supported by the browser
  • We support Chrome and Safari on all platforms
  • We support Firefox on desktop platforms
  • We support the Android native browser on Android 4.4 and later
Opera Mini support

We don't support Opera Mini because Javascript is disabled in it. However, we support the Opera browser, except in super saver mode where JavaScript is disabled as well.

Installation

Paystack InlineJS can be included in your application via CDN, NPM or Yarn:

1<script src="https://js.paystack.co/v2/inline.js">

If you used NPM or Yarn, ensure you import the library as shown below:

1// Add for NPM, Yarn
2import Paystack from '@paystack/inline-js';
3
4const popup = new Paystack()

Paystack object

The Paystack object gives access to the methods and interfaces available in InlineJS. It exposes methods, alongside configuration options that can help you accept payment seamlessly in your web application. The methods exposed by the Paystack object include:

  1. checkout(options): This is an asynchronous method used to create a transaction.
  2. newTransaction(options): This is a synchronous method used to create a transaction.
  3. resumeTransaction(accessCode): With this method, you can initiate a transaction from your backend using the initialize endpoint, then complete the transaction in the frontend without redirecting.
  4. cancelTransaction(id): Sometimes, it might take a while to load a transaction. In such a situation, this method can be used to cancel the transaction.
  5. preloadTransaction(options): This method is used to load a transaction in the background such that when the user is about to checkout, the Popup loads instantly.
  6. paymentRequest(options): This is best suited for handling a custom user experience when your users can make a payment from their wallet (e.g. Apple Pay)
Wallet support

Apple Pay is the only wallet we currently support. Unless otherwise stated, all references to wallet in this documentation refers to Apple Pay.

Callbacks

The Paystack object also exposes callbacks that can be used to monitor certain states during the lifecycle of a transaction.

onLoad

This is called when the transaction is successfully loaded and the customer can see the Popup. It returns an object with the following parameters:

OptionTypeDescription
idStringThis is the transaction id
accessCodeStringThis is a unique payment code used for creating the payment link and loading the Popup
customerObjectThe details of the customer making the payment
1onLoad: (response) => {
2 // Transaction has loaded
3 // You can parse the transaction object if you need to.
4}

onSuccess

This is called when the customer successfully completes a transaction. It returns an instance of a transaction object:

OptionTypeDescription
referenceStringThis is the unique payment reference that can be used for reconciliation
transStringThis is the transaction id (for backward compatibility)
statusStringThe final state of the transaction
messageStringComplimentary note of the transaction status
transactionStringThis is the transaction id
trxrefStringThis is the unique payment reference that can be used for reconciliation (for backward compatibility)
1onSuccess: (transaction) => {
2 // Post payment flow can go here
3}

onElementsMount

This is called when the Apple Pay button has been mounted. It returns null in a case where the user's device doesn't support Apple Pay.

1onElementsMount: (elements) =>{ // { applePay: true } or null
2 if (elements) {
3 console.log("Successfully mounted elements: ", JSON.stringify(elements));
4 } else {
5 console.log('Could not load elements');
6 }
7}

onCancel

This is called when the transaction is cancelled. It returns no response.

1onCancel: () => {
2 console.log("User cancelled")
3}

onError

This is called when there is an issue loading the transaction.

1onError: (error) => {
2 console.log("Error: ", error.message);
3}

Transaction request

With Paystack, a transaction can be initiated for different scenarios such as:

  • One-time payment
  • Split payment
  • Multi-split payment
  • Subscriptions

InlineJS provide parameters and methods to to create the different types of transaction. The table below shows the general options that be used when creating a transaction:

OptionTypeRequiredDescription
keyStringTrueYour public key, gotten from your Paystack dashboard in Settings > API Keys & Webhook
amountNumberTrueThe amount of the transaction in the lowest denomination of your currency
emailStringTrueThe customer's email address
currencyNumberFalseThe currency of the transaction. You can check the API Reference for all supported currency
firstNameStringFalseThe customer's first name
lastNameStringFalseThe customer's last name
phoneStringFalseThe customer's phone number
customerCodeStringFalseA valid Paystack customer code. If provided, this overrides all the customer information above
channelsArrayFalseAn array of payment channels to use. Available channels are ['card', 'bank', 'ussd', 'qr', 'eft', 'mobile_money', 'bank_transfer', β€˜apple_pay’]
metadataObjectFalseA valid object of extra information that you want to be saved to the transaction.
referenceStringFalseUnique case sensitive transaction reference. Only -, ., = and alphanumeric characters allowed.

One-time transaction

The most basic way to use InlineJS is to accept payment for a one-off transaction. Generally, the payment is non-recurring and requires no special configuration. We provide two methods to accept one-time payments:

  1. newTransaction(options)
  2. checkout(options)

newTransaction(options)

This is a synchronous method used to create a transaction. It’s best suited for cases where using an asynchronous flow isn’t necessary. It takes all the general transaction request options and can be used as shown below:

1const popup = new Paystack()
2
3popup.newTransaction({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 23400,
7 onSuccess: (transaction) => {
8 console.log(transaction);
9 },
10 onLoad: (response) => {
11 console.log("onLoad: ", response);
12 },
13 onCancel: () => {
14 console.log("onCancel");
15 },
16 onError: (error) => {
17 console.log("Error: ", error.message);
18 }
19})

checkout(options)

Similar to its counterpart but for an asynchronous flow. It takes all the general transaction request options and can be used as shown below:

1const popup = new Paystack()
2
3popup.checkout({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 23400,
7 onSuccess: (transaction) => {
8 console.log(transaction);
9 },
10 onLoad: (response) => {
11 console.log("onLoad: ", response);
12 },
13 onCancel: () => {
14 console.log("onCancel");
15 },
16 onError: (error) => {
17 console.log("Error: ", error.message);
18 }
19})

Payment request

Payment requests are used for handling wallet payments such as Apple Pay. It’s used to create a custom experience by making the wallet option more prominent on your website. For example, you can have an Apple Pay button and another button to load the checkout.

paymentRequest(options)

The paymentRequest method the following options in addition to the general option:

OptionTypeRequiredDescription
containerStringTrueID of div to mount the payment request button
loadPaystackCheckoutButtonStringFalseID of button to open checkout form
stylesObjectFalseCSS style for the wallet button

The styles object takes the following options:

OptionTypeRequiredDescription
themeStringFalseOption to customize the button background and text color. Available options are dark | light
applePayObjectFalseStyles for the Apple Pay button

The applePay object takes the following options:

OptionTypeRequiredDescription
widthStringFalseSpecify the width of the button
heightStringFalseSpecify the height of the button
borderRadiusStringFalseSpecify the radius of the button edges
typeStringFalseThis determines the text that shows on the button
localeStringFalseSet the language of the button
1<!-- Payment request buttons, styles and event listeners will be injected to this div -->
2<div id="paystack-apple-pay"></div>
3<button id="paystack-other-channels">More payment options</button>
1const popup = new Paystack()
2
3const onElementsMount = (elements) => {
4 if (elements && elements.applePay) {
5 document.querySelector("#pay-button").innerText = "More Payment Options";
6 }
7}
8
9try {
10 await popup.paymentRequest({
11 key: 'pk_domain_xxxxxx',
12 email: '[email protected]',
13 amount: 10000,
14 currency: "NGN",
15 container: 'payment-request-buttons',
16 loadPaystackCheckoutButton: 'pay-button',
17 styles: {
18 theme: 'dark',
19 applePay: {
20 width: '100%',
21 height: '50px',
22 borderRadius: '3px',
23 type: 'plain',
24 locale: 'en'
25 }
26 },
27 onElementsMount,
28 });
29} catch (error) {
30
31}

Resume transaction

The resume transaction flow allows you to initiate a transaction on your server and complete it in the browser. This flow provides both the security of server initialization and the convenience of the user experience in the browser. To get started, make a POST request from your backend to the Initialize TransactionAPI endpoint:

Show Response
1curl https://api.paystack.co/transaction/initialize
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ "email": "[email protected]",
5 "amount": "500000"
6 }'
7-X POST
1{
2 "status": true,
3 "message": "Authorization URL created",
4 "data": {
5 "authorization_url": "https://checkout.paystack.com/nkdks46nymizns7",
6 "access_code": "nkdks46nymizns7",
7 "reference": "nms6uvr1pl"
8 }
9}

In the data object of the response returned, you need to save the access_code and send it to your frontend.

Secret key safeguarding

Do not make an API request to the Initialize Transaction endpoint directly on your mobile app because it requires your secret key. Your secret key should only be used on your server where stronger security measures can be put in place.

resumeTransaction(accessCode)

In your frontend, you can use this access_code to complete the payment without leaving your site.

OptionTypeRequiredDescription
accessCodeStringTrueAccess code returned from the transaction initialization
1const popup = new Paystack()
2
3popup.resumeTransaction(access_code)

The resumeTransaction method triggers the checkout in the browser, allowing the user to choose their preferred payment channel to complete the transaction.

Split transaction

Sometimes you need to share a transaction with another business or entity. To do this you can create a subaccount and pass the subaccoutCode from the response when setting up payment:

1const popup = new Paystack()
2
3popup.newTransaction({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 45000,
7 subaccountCode: 'ACCT_dskvlw3y3dsvkmt',
8 onSuccess: (transaction) => {
9 console.log(transaction);
10 },
11 onLoad: (response) => {
12 console.log("onLoad: ", response);
13 },
14 onCancel: () => {
15 console.log("onCancel");
16 },
17 onError: (error) => {
18 console.log("Error: ", error.message);
19 }
20})

The table below shows the parameters that can be used to config split payments:

OptionTypeRequiredDescription
subaccountCodeStringTrueA valid Paystack subaccount code e.g. ACCT_8f4s1eq7ml6rlzj
bearerStringFalseThis is used to specific the account that bears the Paystack charges. Values can be account or subaccount (defaults to account).
transactionChargeNumberFalseA flat fee (in the smallest denomination of your currency) the main account should take. This overrides the split percentage set when the subaccount was created.

Multi-split transaction

Multi-split payment is used to share a single transaction with multiple partners. Based on your use-case, the split can be created ahead of time via the API or dynamically during the transaction initiation.

If you are certain of your split configuration ahead of time, you can create the split and pass the split_code when setting up the transaction:

1const popup = new Paystack()
2
3popup.newTransaction({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 35650,
7 currency: 'NGN',
8 split: {
9 type: 'percentage',
10 bearer_type: 'account',
11 subaccounts: [
12 {
13 subaccount: 'ACCT_dskvlw3y3dsvkmt',
14 share: 30
15 },
16 {
17 subaccount: 'ACCT_eg4sob4590pq9vb',
18 share: 20
19 }
20 ]
21 },
22 onSuccess: (transaction) => {
23 console.log(transaction);
24 },
25 onLoad: (response) => {
26 console.log("onLoad: ", response);
27 },
28 onCancel: () => {
29 console.log("onCancel");
30 },
31 onError: (error) => {
32 console.log("Error: ", error.message);
33 }
34})
OptionTypeRequiredDescription
split_codeStringTrueA valid Paystack split code with configuration for how payment should be split with partners

Otherwise, you might want to create the split on the fly by passing the split object in the transaction request:

1const popup = new Paystack()
2
3popup.newTransaction({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 98540,
7 split_code: 'SPL_RYUUL4u1hP',
8 onSuccess: (transaction) => {
9 console.log(transaction);
10 },
11 onLoad: (response) => {
12 console.log("onLoad: ", response);
13 },
14 onCancel: () => {
15 console.log("onCancel");
16 },
17 onError: (error) => {
18 console.log("Error: ", error.message);
19 }
20})
OptionTypeRequiredDescription
typeStringTrueTakes either flat or percentage to indicate if you want a fixed or variable share
bearer_typeStringTrueThis is used to indicate the bearer of the transaction fee. It takes one of the following values: all,Β all-proportional, accountΒ orΒ subaccount
subaccountsArrayTrueTakes an array of subaccount objects used to specify the account and share of each account
bearer_subaccountStringFalseSubaccount code of the bearer. It should be specified ifΒ bearer_typeΒ isΒ subaccount
referenceStringFalseUnique reference for the split

Subscriptions

Subscription allows you process recurring billing for your customers. The first time you are setting up payments, you can add the following parameters that tells us to continuously charge the customer:

OptionTypeRequiredDescription
planIntervalStringTrueInterval for the plan. Valid intervals are daily, weekly, monthly, annually
subscriptionLimitNumberFalseThe number of times to charge for this subscription
subscriptionStartDateStringFalseThe start date for the subscription (after the first charge)
1const popup = new Paystack()
2
3popup.newTransaction({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 20000,
7 planInterval: 'weekly',
8 onSuccess: (transaction) => {
9 console.log(transaction);
10 },
11 onLoad: (response) => {
12 console.log("onLoad: ", response);
13 },
14 onCancel: () => {
15 console.log("onCancel");
16 },
17 onError: (error) => {
18 console.log("Error: ", error.message);
19 }
20})
Subscription amount

The amount specified in the request will be used subsequently for the subscription.

Alternatively, you can create a plan via the API or dashboard and pass the planCode in the transaction request:

1const popup = new Paystack()
2
3popup.newTransaction({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 40000,
7 planCode: 'PLN_l6aglbqzebn32c6',
8 onSuccess: (transaction) => {
9 console.log(transaction);
10 },
11 onLoad: (response) => {
12 console.log("onLoad: ", response);
13 },
14 onCancel: () => {
15 console.log("onCancel");
16 },
17 onError: (error) => {
18 console.log("Error: ", error.message);
19 }
20})
OptionTypeRequiredDescription
planCodeStringTrueA valid Paystack plan code e.g. PLN_cujsmvoyq2209ws
subscriptionCountNumberFalseThe number of subscriptions to create for this plan
Plan amount precedence

While amount is a required parameter, the amount used to create the plan takes precedence when subscribing to a plan.

Preload transaction

Preloading a transaction is similar to creating a new transaction but with a little twist. Rather than waiting till the final moment to make a transaction request, you can load the transaction ahead of time.

This method loads a transaction on the Popup without opening it. It returns a function that can be used to open the Popup at a later time. This allows the Popup to load instantly at the point the user is ready to make a payment.

preloadTransaction(options)

This method takes all the general options of a transaction request:

1<button id="make-payment">Make Payment</button>
1const popup = new Paystack()
2
3const loadPopup = popup.preloadTransaction({
4 key: 'pk_domain_xxxxxx',
5 email: '[email protected]',
6 amount: 10000,
7 currency: "NGN"
8});
9
10document.querySelector("#make-payment").onclick = loadPopup;

Cancel transaction

There are situations where you want to build a logic to cancel a transaction. The cancelTransaction method allows you to cancel a transaction and hide the checkout iFrame.

cancelTransaction(id)

OptionTypeRequiredDescription
idStringTrueTransaction ID of the payment to cancel
1const popup = new Paystack()
2
3const transaction = popup.newTransaction({
4 key: 'pk_domain_xxxxx', // Replace with your public key
5 email: "[email protected]",
6 amount: 10000,
7 onLoad: (transaction) => {
8 window.clearInterval(redirectTimer);
9 }
10});
11
12let timeElapsed = 0;
13const timeLimit = 2;
14const redirectURL = 'https://your.redirecturl.com';
15const redirectTimer = setInterval(() => {
16 timeElapsed += 1;
17 if (timeElapsed === timeLimit) {
18 popup.cancelTransaction(transaction.id);
19 window.location.href = redirectURL;
20 }
21}, 1000);