Android SDK Integration
Add the Payonclick Micro ATM SDK to your Android app, launch it with the values from POST /ext/v1/matm/transactions and report what it returns.
The card and the PIN never touch your server or ours: the Payonclick Micro ATM SDK pairs with the Bluetooth card reader, reads the card, takes the PIN on the reader and talks to the bank network itself. Your app does three things around it — ask your server to start the transaction, open the SDK with the values it returns, and send the SDK’s result back.
POST /ext/v1/matm/transactions (signed with your API key — never call the API from the phone). Pass data.sdk and data.reference_id to your app.PayonclickMatm.createIntent(context, sdk, deviceId) and launch it.PayonclickMatm.parseResult(...), then send result.toReportJson() to POST /ext/v1/matm/transaction/{reference_id}/result.matm.success / matm.failed or poll GET /transaction/{reference_id} for the final answer.1. Add the SDK
You receive two files: payonclick-microatm-sdk-v1.0.0.aar (the SDK) and payonclick-card-reader-v1.0.0.jar (the card-reader driver). Copy both into app/libs. The SDK needs Android 7.0 (API 24) or newer.
repositories { flatDir { dirs 'libs' } }
dependencies {
implementation(name: 'payonclick-microatm-sdk-v1.0.0', ext: 'aar')
implementation(name: 'payonclick-card-reader-v1.0.0', ext: 'jar')
// libraries the SDK uses
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.github.f0ris.sweetalert:library:1.6.2'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.29'
}
The SDK carries its own consumer rules, so a minified release build needs nothing in your proguard-rules.pro. The SDK’s screens show Payonclick Micro ATM.
Declare BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_SCAN, BLUETOOTH_CONNECT, ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION in the manifest, and request the runtime ones before you open the SDK.
2. Open it
import com.payonclick.matm.PayonclickMatm
import com.payonclick.matm.PayonclickMatmResult
private val microAtm = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { r -> onMicroAtmResult(PayonclickMatm.parseResult(r.resultCode, r.data)) }
// sdk = data.sdk from POST /ext/v1/matm/transactions (via your server)
fun startMicroAtm(sdk: JSONObject, deviceId: String) {
referenceId = sdk.getString("TXN_ID") // keep it: needed for the report
microAtm.launch(PayonclickMatm.createIntent(this, sdk, deviceId))
}
Intent intent = PayonclickMatm.createIntent(this, sdkJson, deviceId); // optional: a reader other than the one sent to /transactions PayonclickMatm.withDevice(intent, PayonclickMatm.DEVICE_PAX); launcher.launch(intent);
| Constant | Value | Meaning |
|---|---|---|
DEVICE_MOREFUN / DEVICE_PAX / DEVICE_NEWLAND | 2 / 1 / 3 | Card reader model (device on /transactions sets it for you). |
TYPE_CASH_WITHDRAWAL / _BALANCE_ENQUIRY / _MINI_STATEMENT | 2 / 4 / 7 | Already in sdk.TYPE; never change it. |
sdk.TXN_ID | string | Your reference_id. It ties the bank network’s confirmation to the transaction: createIntent passes it through untouched. |
3. Report the result
fun onMicroAtmResult(result: PayonclickMatmResult) {
when {
result.isSuccess -> showPayCash(result.amount) // hand over the cash
result.isPending -> showPending() // do NOT retry for this customer
else -> showDeclined(result.message)
}
// Always report (also CANCELLED / NO_RESPONSE). Your server signs and calls
// POST /ext/v1/matm/transaction/{reference_id}/result with this body.
myBackend.reportMicroAtm(referenceId, result.toReportJson())
}
result.outcome | What to do at the outlet |
|---|---|
SUCCESS | Pay out the cash (CW) or show the balance / statement. Your wallet is credited when the bank network confirms it (matm.success). |
FAILED | No cash. result.message says why (wrong PIN, insufficient funds…). |
PENDING | The bank has not decided. Tell the customer it is pending; do not start another withdrawal for them. |
CANCELLED / NO_RESPONSE | No verdict on the phone. Treat as pending — the bank may still complete it. |
result.miniStatement holds the mini statement rows (date, txnType, amount, narration); toReportJson() already includes them.
Android can kill your app while the customer enters the PIN. Keep the reference_id in onSaveInstanceState (or on disk) before you open the SDK, and queue the result report until your server confirms it, so a result is never lost.