Android Intent integration
Launch the miaPOS Android app from an external cash register app on the same device. Standard Android Intent mechanism — no REST calls, no network on the cashier side. Payment is authorised in miaPOS, and the result is returned as an Activity result.
When to use this
You already have a cash register / ECR app (or you are writing one) that runs on the same Android device as miaPOS — a Sunmi terminal, a smart POS, or a merchant tablet. You need miaPOS to accept the payment and hand the result back to your cashier UI. Use Android Intent. This is the fastest integration path for on-device co-existence — no HTTPS setup, no credentials to manage in your app.
Action & app id
Every string used in the Intent — action and every extra key — is prefixed with the miaPOS app id. Two builds exist:
- md.finergy.miapos — release build (production).
- md.finergy.miapos.debug — debug build (development on the same device).
The action to launch payment is <app_id>.action.MIA_PAY. Start the Intent for a result — either through ActivityResultContracts.StartActivityForResult (recommended) or the legacy Activity.startActivityForResult.
Request extras
Three required extras, all with the <app_id>.extra. prefix:
| Key | Type | Description | Example |
|---|---|---|---|
MIA_PAY_REQUEST_ID |
String (UUID) |
Idempotency key for this payment request. Your app generates a fresh UUID per payment. | c8c5584f-7a4a-… |
MIA_PAY_AMOUNT |
Float |
Amount to charge, in the currency below. | 123.54 |
MIA_PAY_CURRENCY |
String |
ISO 4217 currency code. Currently MDL only. |
MDL |
Response extras
miaPOS returns the following extras in the result Intent:
| Key | Type | When present | Description |
|---|---|---|---|
MIA_PAY_REQUEST_ID |
String (UUID) |
Always | Echoes back the request id. |
MIA_PAY_STATUS |
String |
Always | One of success, failed. |
MIA_PAY_TX_INFO |
String (JSON) |
Only on success |
Transaction info: amount, currency, date, mcc. Example: {"amount":123.45,"currency":"MDL","date":"2024-04-04T10:49:54","mcc":"1234"}. |
MIA_PAY_ERROR_REASON |
String |
Only on failed |
One of validation_error, generate_error, expired, canceled, wait_pay_error. New values can be added in the future — treat the enum as open. |
If the user backs out before finishing, the launcher receives an activity resultCode that is not RESULT_OK. Treat that as a cancellation.
Kotlin example
class CashboxActivity : ComponentActivity() { companion object { // "md.finergy.miapos" for release build private const val MIA_APP_ID = "md.finergy.miapos.debug" private const val ACTION_MIA_PAY = "$MIA_APP_ID.action.MIA_PAY" private const val EXTRA_MIA_PAY_REQUEST_ID = "$MIA_APP_ID.extra.MIA_PAY_REQUEST_ID" private const val EXTRA_MIA_PAY_AMOUNT = "$MIA_APP_ID.extra.MIA_PAY_AMOUNT" private const val EXTRA_MIA_PAY_CURRENCY = "$MIA_APP_ID.extra.MIA_PAY_CURRENCY" private const val EXTRA_MIA_PAY_STATUS = "$MIA_APP_ID.extra.MIA_PAY_STATUS" private const val EXTRA_MIA_PAY_TX_INFO = "$MIA_APP_ID.extra.MIA_PAY_TX_INFO" private const val EXTRA_MIA_PAY_ERROR_REASON = "$MIA_APP_ID.extra.MIA_PAY_ERROR_REASON" } private val launcher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { activityResult -> when (activityResult.resultCode) { RESULT_OK -> handlePaymentResult(activityResult.data) else -> Log.d("PaymentResult", "Operation canceled") } } fun pay(amount: Float, currency: String = "MDL") { try { launcher.launch(Intent().apply { action = ACTION_MIA_PAY putExtra(EXTRA_MIA_PAY_REQUEST_ID, UUID.randomUUID().toString()) putExtra(EXTRA_MIA_PAY_AMOUNT, amount) putExtra(EXTRA_MIA_PAY_CURRENCY, currency) }) } catch (e: ActivityNotFoundException) { // miaPOS app is not installed on this device } } private fun handlePaymentResult(intent: Intent?) { if (intent == null) return val status = intent.getStringExtra(EXTRA_MIA_PAY_STATUS) val requestId = intent.getStringExtra(EXTRA_MIA_PAY_REQUEST_ID) val txInfoJson = intent.getStringExtra(EXTRA_MIA_PAY_TX_INFO) val errorReason = intent.getStringExtra(EXTRA_MIA_PAY_ERROR_REASON) Log.d("PaymentResult", "status=$status requestId=$requestId txInfo=$txInfoJson error=$errorReason") } }
Handling errors
Two failure classes to plan for on the cashier side:
ActivityNotFoundException— the miaPOS app is not installed on this device. Prompt the merchant to install miaPOS from Google Play or (for pre-provisioned Sunmi/SmartOne devices) contact support.MIA_PAY_STATUS = "failed"— miaPOS launched but the payment did not complete. ReadMIA_PAY_ERROR_REASONto decide whether to retry (expired,wait_pay_error) or fail hard (validation_error).
Testing
Point MIA_APP_ID at md.finergy.miapos.debug while you develop against the debug build of miaPOS. Flip to md.finergy.miapos for release. Nothing else in the contract changes between the two builds. The debug build points at the sandbox environment configured on the device.
What this integration does not cover
- Refunds, returns, shift management, receipts — those are cashier operations inside miaPOS itself, not exposed via Intent. Use the POS API if you need programmatic access to those.
- Remote / cross-device flows — Intent is on-device only. Use the POS API or E-comm API for remote payment initiation.
- Currencies other than
MDL— currently the only supported value.