Requesting a payment
Call MPScanToPay.checkout and handle the delegate callbacks — with sample Swift and the full callback reference.
This page documents the core Scan to PayKit checkout flow: calling checkout(...) from a view controller and handling the delegate callbacks. For drop-in alternatives, see Pay-by-Card button. For installation, see Installation.
The payment flow
1. Your backend creates a code via /code (fixed amount)
↓
2. Your view controller gets the code + your Lib Lite API key
↓
3. Your view controller calls MPScanToPay().checkout(...)
↓
4. SDK presents the payment UI; customer picks a card and pays
↓
5. SDK calls your delegate with one of 5 result methods
↓
6. Your view controller sends txReference to your backend
↓
7. Your backend confirms via webhook or /transactionState before
shipping goods / releasing service
Never trust the SDK's success callback alone. Always re-verify on your backend with a webhook or/transactionStatelookup. See Webhooks.
Calling checkout
import ScanToPayKit
@IBAction func checkoutAction(_ sender: Any) {
let code = "6799782555"
let apiKey = "YOUR_API_KEY"
let system = MPSystem.test // or .live
let scanToPay = MPScanToPay()
scanToPay.checkout(withCode: code,
apiKey: apiKey,
system: system,
controller: self,
delegate: self)
}Optionally pre-fill the customer's MSISDN:
scanToPay.checkout(withCode: code,
apiKey: apiKey,
system: system,
controller: self,
delegate: self,
preMSISDN: "27832006283")Parameters
| Name | Type | Required | Description |
|---|---|---|---|
code | String | yes | Transaction code from /code. Must be a fixed-amount code. |
apiKey | String | yes | Your Lib Lite API token from the Portal |
system | MPSystem | yes | .live (prod) or .test (sandbox) |
controller | UIViewController | yes | The presenting view controller |
delegate | MPScanToPayDelegate | yes | Where the SDK will call back |
preMSISDN | String | optional | International-format MSISDN to pre-fill on registration |
Adopting the delegate
import UIKit
import ScanToPayKit
class CheckoutViewController: UIViewController, MPScanToPayDelegate {
func scanToPayInvalidCode() {
// IN_CODE was malformed, expired, or already used
showAlert(title: "Invalid Code",
message: "Please retry — the payment code wasn't accepted.")
}
func scanToPayError(_ error: MPError) {
// Something errored before / outside the payment attempt
handleSdkError(error)
}
func scanToPayPaymentSucceeded(withTransactionReference transactionReference: String!) {
// Customer completed payment. Verify on backend!
verifyOnBackend(transactionReference)
}
func scanToPayPaymentFailed(withTransactionReference transactionReference: String!) {
// Payment was attempted but failed (bank declined, etc.)
logFailure(transactionReference)
}
func scanToPayUserDidCancel() {
// Customer backed out
}
func scanToPayUserRegistered() {
// Card registered successfully (typically follows preRegister)
}
func scanToPayUserCompletedWallet() {
// Manage-card flow completed
}
}Delegate callbacks
| Callback | When you'll see it | Argument |
|---|---|---|
scanToPayPaymentSucceeded(withTransactionReference:) | Customer completed payment. Verify server-side. | String — the transaction reference |
scanToPayPaymentFailed(withTransactionReference:) | Payment was attempted but failed | String — the failed transaction reference |
scanToPayUserDidCancel() | Customer aborted before completing | (none) |
scanToPayInvalidCode() | The code you passed is invalid | (none) |
scanToPayError(_:) | Something errored before / during the payment attempt | MPError — see Errors |
scanToPayUserRegistered() | (after preRegister(...)) Customer registered a card | (none) |
scanToPayUserCompletedWallet() | (after walletManagement(...)) Customer finished managing cards | (none) |
What you do server-side
When you receive scanToPayPaymentSucceeded(withTransactionReference:):
- POST the
transactionReferenceto your backend - Backend confirms the state:
- Wait for the webhook (recommended) — see Webhooks
- Or poll
/transactionState/{transactionId}— see Querying transactions
- Once confirmed
SUCCESS, fulfil the order / release the service
When you receive scanToPayPaymentFailed(...):
- Log the reference for support correlation
- Show a friendly retry message
- Don't auto-retry — let the customer choose
Test card numbers
For sandbox (system: .test), see Sandbox and test cards. The two essentials:
| Card | Use |
|---|---|
50010001000105 | Success |
50010001000101 | Insufficient funds |
What's next
- Use a drop-in button → Pay-by-Card button
- Hand off to a bank app → Pay-by-App button
- Standalone card management → Manage Card
- Pre-register a card → Pre-registration
- MPError reference → Errors
Updated 2 days ago
