Pay by App button
Drop-in button that hands the customer off to their bank's app (ABSA, Standard Bank, Capitec, etc.) via a deep link.
The PayByApp button lets a customer pay through their bank's mobile app rather than entering card details in your app. The button shows a chooser of installed bank apps; the customer picks one; Scan to Pay deep-links into that app to complete the payment.
It's useful when:
- Your customer base prefers paying via their bank app
- You want to avoid card-on-file registration overhead for first-time customers
- You're integrating in a regulated context where keeping cardholder data out of your app is preferable
For the pure card-in-SDK flow, see Pay-by-Card button instead.
How it works
Your app Lib Lite SDK Bank app Scan to Pay
──────── ──────────── ──────── ───────────
│ │ │ │
user taps │ │ │
PayByApp │ │ │
├──────────────────►│ │ │
│ │ list installed │ │
│ │ bank apps │ │
│ │ ───┐ │ │
│ │ ◄──┘ │ │
│ ◄──── chooser ───┤ │ │
│ │ │ │
user picks bank │ │ │
├──────────────────►│ │ │
│ │ deep-link launch │ │
│ ├───────────────────►│ │
│ │ │ user pays in their │
│ │ │ bank app │
│ │ │ ───────────────────► │
│ │ │ ◄─────────────────── │
│ │ returns result │ │
│ │ ◄─────────────────── │
│ ◄── result ──────┤ │
Step 1 — Manifest entries
Add the PayByAppActivity to your AndroidManifest.xml:
<activity
xmlns:tools="http://schemas.android.com/tools"
android:name="com.eftcorp.liblite.PayByAppActivity"
android:exported="true"
tools:node="merge">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="@string/deeplink_host"
android:pathPrefix="@string/deeplink_path_prefix"
android:scheme="@string/deeplink_scheme" />
</intent-filter>
</activity>Step 2 — String resources
In res/values/strings.xml, define your app's universal-link target — the SDK uses these so the bank app knows where to return after payment:
<string name="deeplink_scheme">https</string>
<string name="deeplink_host">sample.com</string>
<string name="deeplink_path_prefix">/prefix</string>Replace with your own verified universal-link domain. The autoVerify="true" attribute requires the matching .well-known/assetlinks.json on that domain — see Android App Links docs for setup details.
Step 3 — Add the button to your layout
<com.eftcorp.liblite.paybyapp.PayByAppButton
android:id="@+id/payByApp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />Step 4 — Register the result launcher
Same launcher pattern as the standard payment activity:
private final ActivityResultLauncher<Intent> libLiteActivityLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> handleLibLiteResult(result.getResultCode(), result.getData())
);Step 5 — Launch the PayByApp activity
When the button is tapped, build and launch the intent. Note the additional deep-link extras compared to the Pay-by-Card flow:
public void startLibLiteActivityWithPayByApp(CodeBean codeBean) {
Intent intent = new Intent(this, PayByAppActivity.class);
intent.putExtra(LibLiteActivity.IN_APP_LINK_SCHEME, getString(R.string.deeplink_scheme));
intent.putExtra(LibLiteActivity.IN_APP_LINK_HOST, getString(R.string.deeplink_host));
intent.putExtra(LibLiteActivity.IN_APP_LINK_PATH_PREFIX, getString(R.string.deeplink_path_prefix));
intent.putExtra(LibLiteActivity.IN_HASH, "YOUR_SMS_HASH");
intent.putExtra(LibLiteActivity.IN_API_KEY, "YOUR_API_KEY");
intent.putExtra(LibLiteActivity.IN_CODE, "1234567890");
libLiteActivityLauncher.launch(intent);
}Supported bank apps
The button discovers installed bank apps using their published deep-link schemes. Currently supported:
| Bank | Scheme |
|---|---|
| ABSA | masterpass.absa.scheme:// |
| Standard Bank | masterpass.sbsa.scheme:// |
| Nedbank | masterpass.nedbank.scheme:// |
| FNB | masterpass.fnb.scheme:// |
| Capitec | masterpass.capitec.scheme:// |
| VodaPay | masterpass.vodapay.scheme:// |
| Spenda | masterpass.spenda.scheme:// |
The supported list is maintained by EFT Corporation — new banks are added in SDK minor releases. See Changelog.
Result handling
Identical to the standard payment activity — five possible result codes. See Payments.
The extra OUT_LOCATION value on LIBLITE_USER_CANCELLED is particularly useful for Pay-by-App: it tells you whether the customer cancelled in your app, the chooser, or after the bank-app handoff.
When no bank apps are installed
If none of the supported bank apps are installed, the button falls back to the standard Pay-by-Card flow — same UX as if you'd used PayByCardButton directly. The customer can register a card on the spot.
What's next
- Just want the card flow? → Pay-by-Card button
- The payment activity behind both buttons → Payments
- Result codes → Errors
- App-to-app from the merchant side → App-to-app
Updated 2 days ago
