DocumentationRecipesAPI ReferenceChangelog
Documentation

Void

Transaction API supports VOID operations and can be used to reverse a previous transaction using the transaction ID from the original Sales/Auth Transaction before settlement.

You can integrate in two UI environments:

  1. Traditional Activity / Fragment UI
  2. Modern Jetpack Compose UI

Void Request

To initiate a Void request, follow the examples below

Option 1 : Payment in Activity or Fragment

class VoidActivity : AppCompatActivity() {

    private val transactionLauncher =
        registerForActivityResult(msaPosApi.transactionContract()) { result ->
            when (result) {
                is PosResponse.Success -> {
                    val txn = result.data
                    // handle success
                }
                is PosResponse.Failed -> {
                    // handle fail
                }
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_void)

        // Example call
        triggerVoidTransaction("ORIGINAL_TRAN_ID_123", "admin1234", "VOID_REF_001")
    }

    private fun triggerVoidTransaction(originalTranId: String, adminPwd: String, posMessageId: String) {
        val voidRequest = PosRequest.Transaction.Void(
            orgTranId = originalTranId,
            posMessageId = posMessageId,
            adminPwd = adminPwd
        )
        transactionLauncher.launch(voidRequest)
    }
}

Option 2 : Payment in Jetpack Compose

@Composable
fun VoidTransactionScreen(msaPosApi: MsaPosApi, originalTranId: String, posMessageId: String, adminPwd: String) {
    val context = LocalContext.current

    val transactionLauncher = rememberLauncherForActivityResult(msaPosApi.transactionContract()) { result ->
        when (result) {
            is PosResponse.Success -> {
                val txn = result.data
                // handle success
            }
            is PosResponse.Failed -> {
                // handle fail
            }
        }
    }

    Button(onClick = {
        val voidRequest = PosRequest.Transaction.Void(
            orgTranId = originalTranId,
            posMessageId = posMessageId,
            adminPwd = adminPwd
        )
        transactionLauncher.launch(voidRequest)
    }) {
        Text("Void Transaction")
    }
}

Payment Response

{
 "rspCode" : "0",
 "rspMsg": "Success",
 "data" : {
  "tranId": "M9279873298",
  "trace": "M9279873298",
  "rrn": "897323",
  "tranType": "SALE",
  "tranStatus": "Approved",
  "approvalCode": "979384",
  "paymentMethod": "Visa",
  "cardData" : {
    "aid": "",
    "appName": "",
    "tc": "",
    "tsi": "",
    "tvr": ""
  },
  "entryMode" : "NFC",
  "maskedAccount": "**** **** **** 1234",
  "cvmPerformed": "NO_CVM",
  "acqMid": "MID98392",
  "acqTid": "0001",
  "posMessageId": "{merchant unique reference no}",
  "mchAddress": "",
  "mchName": "2C2P Pte Ltd",
  "totalAmount": 60.00,
  "createByName": "",
  "createdAt": "1744687184773",
  "updatedAt": "1744687184773"
 }
}

Response: PosResponse<T>

All responses from the POS Lib return as a sealed class:

sealed class PosResponse<T>(val rspCode: String, val rspMsg: String) : Serializable

Sub Types

TypeDescription
Success<Unit>Response: Completed successfully
Failed<Unit>Response: failed. Use rspCode, rspMsg for debugging

Successful Transaction Response

data class TransactionResponse(
    val tranId: String,
    val tranType: String,           // SALE, VOID, etc.
    val tranStatus: String,         // Approved, Declined, etc.
    val rrn: String,                // Reference number
    val approvalCode: String,
    val paymentMethod: String,      // Visa, MasterCard, etc.
    val maskedAccount: String,
    val totalAmount: BigDecimal,
    val posMessageId: String,
    val acqMid: String,
    val acqTid: String,
    val entryMode: String,
    val trace: String,
    val cardData: CardData,
    val cvmPerformed: String,
    val mchName: String,
    val mchAddress: String,
    val createdAt: String,
    val updatedAt: String
)
Status Reference
FieldDescription
tranTypeSALE / VOID / REFUND / AUTH
tranStatusApproved / Declined / Processing / Voided / Reversed
rrnHost-generated reference number (ARN)
tranIdUnique ID from backend
posMessageIdYour reference ID for tracking
approvalCodeApproval code from issuer
maskedAccountMasked card number

Card Data Object

data class CardData(
  val aid: String,
  val appName: String,
  val tc: String,
  val tsi: String,
  val tvr: String,
)