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:
- Traditional Activity / Fragment UI
- 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
Type | Description |
---|---|
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
Field | Description |
---|---|
tranType | SALE / VOID / REFUND / AUTH |
tranStatus | Approved / Declined / Processing / Voided / Reversed |
rrn | Host-generated reference number (ARN) |
tranId | Unique ID from backend |
posMessageId | Your reference ID for tracking |
approvalCode | Approval code from issuer |
maskedAccount | Masked card number |
Card Data Object
data class CardData(
val aid: String,
val appName: String,
val tc: String,
val tsi: String,
val tvr: String,
)
Updated 1 day ago