Micro ATM

Micro ATM Android SDK integration: a developer guide

A Micro ATM turns an Android phone and a Bluetooth card reader into a cash withdrawal point for any debit card. The card and PIN are handled inside an SDK, but your app and server still own the transaction, the result and the money. This guide walks through the integration as it runs on the Payonclick Micro ATM API.

A Micro ATM lets a retailer serve a customer who has a debit card but no nearby ATM. The customer swipes or inserts their card into a small Bluetooth reader paired with the retailer's phone, enters their PIN on the reader, and gets cash from the retailer's drawer. Behind that simple counter flow sit three parties: your server, your Android app with the SDK inside it, and the bank network. Getting the hand-offs right is what keeps money safe when a phone dies mid-transaction. This guide follows the Payonclick Micro ATM API and its Android SDK reference.

How the pieces fit

Part What it does What it must never do
Your server Creates each transaction with a signed API call, receives the result report and the webhook Expose your API key to the phone
Your Android app Launches the SDK with the values from your server, saves the reference, sends the result to your server Decide the final status on its own
The Micro ATM SDK Talks to the Bluetooth reader, reads the card and PIN, returns an outcome Pass card or PIN data to your app
The bank network Approves or declines and confirms the transaction

The key rule: the SDK result is evidence, not the final word. A withdrawal becomes SUCCESS, and your AEPS wallet is credited net of charges, only when the bank network's confirmation reaches Payonclick.

Before you start

  • Outlet onboarding. Each outlet is onboarded and completes eKYC once through /ext/v1/aeps/merchants, the same endpoints the AEPS API uses.
  • API key. A key with the matm permission, called only from your whitelisted server.
  • SDK files. Our team shares the SDK (payonclick-microatm-sdk-v1.0.0.aar) and the card-reader driver (payonclick-card-reader-v1.0.0.jar). Copy both into app/libs.
  • Android 7.0 or later (API 24).
  • A supported reader. PAX, MoreFun or NewLand Bluetooth readers.

Step 1: add the SDK to your app

Add a flatDir { dirs 'libs' } repository in app/build.gradle, include both files, and add the libraries the SDK depends on, listed in the reference. The SDK ships its own R8 and ProGuard rules, so a minified release build needs no extra rules.

Declare the Bluetooth and location permissions in the manifest: BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_SCAN, BLUETOOTH_CONNECT, ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION. Ask for the runtime permissions before you open the SDK. A denied Bluetooth permission is the most common reason a reader is "not found".

Step 2: create the transaction on your server

Your server calls POST /ext/v1/matm/transactions, signed with your API key, with the transaction type, the amount, the reader type and your own client_reference. The response carries a reference_id and an sdk object with the launch values.

Pass data.sdk and data.reference_id to the app. Never create the transaction from the phone: the request signature needs your secret, and a phone is not a safe place for it.

Use one client_reference per customer request, such as MATM-<outlet>-<your order id>. If the create call times out, read the transaction back by that reference instead of creating a second one.

Step 3: launch the SDK

In the app, build the intent with PayonclickMatm.createIntent(context, sdk, deviceId) and start it. Two details matter:

  • Save the reference_id first. Android can kill your app while the customer enters their PIN. Keep the reference in onSaveInstanceState or on disk before you launch, so you can still report the result when the app returns.
  • Don't change the transaction type. sdk.TYPE comes from your server. It is cash withdrawal, balance enquiry or mini statement.

Step 4: read and report the result

When the SDK returns, parse it with PayonclickMatm.parseResult(resultCode, data). The result has an outcome, the amount, a message and, for a mini statement, its rows.

Outcome What the retailer does
SUCCESS Hand over cash, or show the balance or statement
FAILED No cash; show the message
PENDING No cash yet; the bank has not decided
CANCELLED or NO_RESPONSE Treat as pending; the bank may still complete it

Send result.toReportJson() to your server, and have your server call POST /ext/v1/matm/transaction/{reference_id}/result. Always report, including cancelled and no-response outcomes, and queue the report on the phone until your server confirms it received it.

Step 5: wait for the final status

The final answer comes from the bank network. Subscribe to the matm.success and matm.failed webhooks, or poll GET /ext/v1/matm/transaction/{reference_id}. Your AEPS wallet is credited only on success.

Never start a new withdrawal for the same customer while one is pending. If the first one completes, the customer's account is debited twice. Wait for the final status, and show the retailer that the transaction is still being confirmed.

Common integration mistakes

  • Calling the create endpoint from the app. It leaks your API key. Keep every signed call on your server.
  • Losing the reference on process death. Save it before launching the SDK.
  • Treating CANCELLED as failed. The bank may still have debited the card. Report it and wait.
  • Paying out on the SDK's word alone in your own ledger. Credit retailers only on the confirmed webhook or status.
  • Skipping runtime permissions on Android 12 and later. BLUETOOTH_SCAN and BLUETOOTH_CONNECT are runtime permissions there.
FAQ

Frequently asked questions

Which Android versions does the Micro ATM SDK support?

Android 7.0 (API 24) and later, with the Bluetooth and location permissions granted at runtime before the SDK opens.

Which card readers work?

PAX, MoreFun and NewLand Bluetooth readers. Your server sets the reader in the create call, and the app can override it when it builds the intent.

Does card or PIN data reach my server?

No. The card and PIN are handled inside the SDK and the reader. Your app and server see only the outcome, the amount and, for a mini statement, its rows.

When is my wallet credited for a withdrawal?

Only when the bank network confirms the withdrawal. The SDK's own success is reported as evidence, and the credit follows the confirmed status.

What if the app closes during a transaction?

Read the saved reference_id, report whatever the SDK returned, and wait for the webhook or status. Never start a new withdrawal for the same customer until the first one has a final status.

Can I run Micro ATM on iPhone or in a browser?

No. The SDK and the Bluetooth readers work on Android only.

Ready to get started?

Talk to the Payonclick India team about API access, a white-label platform or custom fintech software.

Keep exploring

Related services and guides

Get started

Tell us what you want to launch

Share a few details. Our team will call you back within one business day with the next steps, the documents needed and pricing for your use case.