iOS SDK
The iOS SDK provides UI components and methods that allow you to accept payments in your iOS app.
Introduction
The iOS SDK is a collection of methods and interfaces that allow you to build a secure and convenient payment flow for your iOS app. Integration is a two-step process:
- Initiate the transaction on the server
- Complete it on the SDK
Project requirements
The payment UI in the Paystack iOS SDK runs on iOS 14 or later. You can add the package to an app that targets iOS 13, but the payment UI is only available on iOS 14 and later. Before using the SDK, you need to ensure your app meets the following requirements:
- iOS 14 or later to show the payment UI
- Xcode 14 or later
- Swift Package Manager
Installation
The iOS SDK package contains two libraries:
- PaystackCore: This contains the APIs and methods for processing payments.
- PaystackUI: This contains the UI components to collect the customer's payment information and display the payment status.
You can install these packages via the Swift Package Manager. To add the required packages, ensure you have the latest version of Xcode installed and follow these steps:
- Select File > Add Package Dependencies…
- Copy the repo URL and paste it into the search box of the package dependency popup
- Set the dependency rule to Up to Next Major Version from
1.0.0 - Add both the
PaystackCoreandPaystackUIlibraries to your app target
You can read the Swift Package Manager documentation to learn more about adding packages to your project.
Paystack Core
The PaystackCore module uses a builder pattern to handle housekeeping and foundational tasks before the UI components can be used.
- Swift
1import PaystackCore
The table below shows the methods available on PaystackBuilder:
| Method | Description |
|---|---|
setKey("public-key") | This method is used to set the public key. Without a public key, you can't complete a transaction. |
enableLogging() | Turns on debug logs. Logging is off by default. |
setDisplayAudience(_:) | Specifies who holds the device. .customerFacing, the default, is for customers paying on their own phone. .merchantFacing is for apps where the merchant shows the screen to the customer, such as a point-of-sale app. It applies to every payment you start with this Paystack object. See display audience. |
- Swift
1let paystack = try? PaystackBuilder2 .newInstance3 .setKey("pk_domain_xxxxxxxx")4 .build()
To show the payment UI to customers on a merchant's device, set the display audience when you build the object:
- Swift
1let paystack = try? PaystackBuilder2 .newInstance3 .setKey("pk_domain_xxxxxxxx")4 .setDisplayAudience(.merchantFacing)5 .build()6
Initialize transaction
The SDK requires an access_code to display the UI component that accepts payment. To get the access_code, make a POST request to the Initialize TransactionAPI endpoint from your server:
1curl https://api.paystack.co/transaction/initialize2-H "Authorization: Bearer YOUR_SECRET_KEY"3-H "Content-Type: application/json"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}
On a successful initialization of the transaction, you get a response that contains an access_code. You need to return this access_code back to your mobile app.
Secret key safeguarding
Don't 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.
Paystack UI
The PaystackUI module holds the UI components that manage the payment form and the available payment channels. You can add this module to your project as shown below:
- Swift
1import PaystackUI
The payment UI supports light and dark mode and follows the device's appearance setting. The PaystackUI module comes with two methods:
chargeUIButton: This is best suited for SwiftUI.presentChargeUI: This is best suited for UIKit.
chargeUIButton
This method gives you a button that you can customize to show the payment UI. This method takes the following parameters:
| Parameter | Type | Description |
|---|---|---|
accessCode | String | The access code your server receives when it initializes the transaction. |
onComplete | Callback | The callback that handles post-payment processes. Its argument is a TransactionResult. |
- SwiftUI
1paystack?.chargeUIButton(accessCode: "ACCESS_CODE", onComplete: paymentDone) {2 Text("Initiate Payment")3}
presentChargeUI
With this method, you create a button that shows the payment UI. The payment UI needs a view controller to present from, so pass a reference to the current view controller with the other parameters in the table below:
| Parameter | Type | Description |
|---|---|---|
on | UIViewController | The view controller of the current view. |
accessCode | String | The access code your server receives when it initializes the transaction. |
onComplete | Callback | The callback that handles post-payment processes. Its argument is a TransactionResult. |
- UIKit
1@IBAction func payButtonTapped(_ sender: Any) {2 paystack?.presentChargeUI(on: self,3 accessCode: "ACCESS_CODE",4 onComplete: paymentDone)5}
Transaction result
The TransactionResult exposes the different states of a transaction. It's the argument type for the PaystackUI onComplete callback:
| State | Description |
|---|---|
.completed | The customer completed the payment process. This result contains ChargeCompletionDetails, which includes the transaction reference. Use the reference to verify the transaction status and amount on your server before providing value. |
.cancelled | The customer closed the payment UI. This includes closing the error screen shown when the payment can't start, for example when the access code is invalid or the transaction has no channel the SDK supports. The payment can still complete after the customer closes the payment UI, for example a bank transfer that Paystack confirms later, so confirm the final status with your webhook. |
.error | The payment UI hit an error inside a payment channel that it can't recover from. It shows the error message and closes itself after 3 seconds. This result contains a ChargeError and, when available, the transaction reference. The ChargeError has a message you can show the customer and a cause property with the underlying error for your logs. |
- Swift
1func paymentDone(_ result: TransactionResult) {2 switch (result){3 case .completed(let details):4 print("Transaction completed with reference: (details.reference)")5 case .cancelled:6 print("Transaction was cancelled")7 case .error(error: let error, reference: let reference):8 print("An error occurred: (error.message) with reference: (String(describing: reference))")9 }10}
Payment channels
The payment UI shows a payment channel when all three of these are true:
- You enabled the channel on your integration.
- The channel supports the transaction's currency.
- The SDK supports the channel.
If only one channel qualifies, the payment UI opens it immediately. Otherwise, the customer chooses from a list. To limit the channels for a transaction, pass the channels parameter when you initialize the transactionAPI.
The payment UI handles each channel's payment flow for you, then calls onComplete with a TransactionResult.
| Country | Currency | Payment channels |
|---|---|---|
| Nigeria | NGN | Card, Pay with Transfer, and Zap |
| Ghana | GHS | Card and mobile money (MTN, AirtelTigo, and Telecel) |
| Kenya | KES | Card, mobile money (M-PESA and Airtel Money), and Pesalink |
| Côte d'Ivoire | XOF | Card |
| South Africa | ZAR | Card, Capitec Pay, Scan to Pay, and SnapScan |
When a channel attempt fails, for example a declined card or an expired session, the payment UI shows the reason and lets the customer try again or choose another channel. onComplete isn't called until the customer completes the payment, cancels it, or the payment UI hits an error it can't recover from.
Display audience
Zap works differently depending on who holds the device. Set the audience with setDisplayAudience(_:) on the Paystack builder:
| Channel | .customerFacing (default) | .merchantFacing |
|---|---|---|
| Zap | Open Zap button | QR code to scan with Zap |