Integration via local network
MineSec SoftPOS Application integrates a simple web server which accepts http request from local LAN network.
Pay Server Http Call
The Pay Server provides end points for the following MSA operations:
| Operation | Method | Route | Description | 
|---|---|---|---|
| Activation | POST | /api/v1/activation | Activate the app and load configs from the backend | 
| WarmUp | GET | /api/v1/warmup | Warm up the SoftPOS app, perform the runtime checking on device and application | 
| Transaction | POST | /api/v1/trans | Perform a transaction like sale, void, or refund | 
| Enquiry | GET | /api/v1/trans/{transId} | Check the previous transaction status | 
Generally you'll want to create HTTP client to request server.
val client = HttpClient(Android) {
  install(ContentNegotiation) {
    gson {
      registerTypeAdapter(PosRequest::class.java, PosRequestDeserializer())
    }
  }
}
 
// default pay server port: 8000
val result =
  client.post("http://${remoteIpAddress.value}:${remotePort.value}/api/v1/trans") {
    contentType(ContentType.Application.Json)
    setBody(request)
  }// Custom Deserializer
class PosRequestDeserializer : JsonDeserializer<PosRequest> {
  override fun deserialize(
    json: JsonElement,
    typeOfT: Type,
    context: JsonDeserializationContext
  ): PosRequest {
    val jsonObject = json.asJsonObject
    val name = jsonObject.get("name").asString
 
    return when (name) {
      "WARM_UP" -> PosRequest.WarmUp
      "ACTIVATION" -> context.deserialize<PosRequest.Activation>(
        jsonObject,
        PosRequest.Activation::class.java
      )
 
      "ENQUIRY_STATUS" -> PosRequest.EnquiryDeviceStatus
      "RELOAD_CONFIGS" -> PosRequest.ReloadConfiguration
      "ENQUIRY_BLUETOOTH_CONNECT_STATUS" -> PosRequest.EnquiryBTStatus
      "SALE" -> context.deserialize<PosRequest.Transaction.Sale>(
        jsonObject,
        PosRequest.Transaction.Sale::class.java
      )
 
      "AUTH" -> context.deserialize<PosRequest.Transaction.Auth>(
        jsonObject,
        PosRequest.Transaction.Auth::class.java
      )
 
      "VOID" -> context.deserialize<PosRequest.Transaction.Void>(
        jsonObject,
        PosRequest.Transaction.Void::class.java
      )
 
      "REFUND" -> context.deserialize<PosRequest.Transaction.Refund>(
        jsonObject,
        PosRequest.Transaction.Refund::class.java
      )
 
      "ENQUIRY_TRANSACTION_STATUS" -> context.deserialize<PosRequest.EnquiryTranStatus>(
        jsonObject,
        PosRequest.EnquiryTranStatus::class.java
      )
 
      "SETTLEMENT" -> context.deserialize<PosRequest.Settlement>(
        jsonObject,
        PosRequest.Settlement::class.java
      )
 
      else -> throw JsonParseException("Unknown type: $name")
    }
  }
}Warm Up
The WarmUp calls the MSA to perform a series of runtime checking. It takes no argument.
 val result =
  client.get("http://${remoteIpAddress.value}:${remotePort.value}/api/v1/warmup")
val response = result.body<PosResponse<Unit>>()Activation
The Activation calls the MSA to activate the app, loads the necessary configs, like store information and EMV configs for later transaction.
Required the activationCode
val request = PosRequest.Activation("activation code")
 
val result =
  client.post("http://${remoteIpAddress.value}:${remotePort.value}/api/v1/activation") {
    contentType(ContentType.Application.Json)
    setBody(request)
  }
val response = result.body<PosResponse<Unit>>()Transaction
Initiate a transaction request, including the SALE, VOID, or REFUND.
For new transaction SALE, requires amount field.
For void & refund request, requires the orgTranId.
val cardSaleRequest = PosRequest.Transaction.Sale(
  amount = BigDecimal(amount),
  posMessageId = viewModel.posMessageId,
  autoDismissResult = true
)
 
val qrMerchantScanRequest = PosRequest.Transaction.Sale(
  amount = BigDecimal(amount),
  posMessageId = viewModel.posMessageId,
  autoDismissResult = true,
  // initiate QR transaction with merchant scan mode
  preferredInstrument = PreferredInstrument.QR_MERCHANT_SCAN
)
 
val qrGuestScanRequest = PosRequest.Transaction.Sale(
  amount = BigDecimal(amount),
  posMessageId = viewModel.posMessageId,
  autoDismissResult = true,
  // initiate QR transaction with guest scan mode
  preferredInstrument = PreferredInstrument.QR_GUEST_SCAN,
  // optional,in QR guest scan mode, if no QR payment method is specified, the MSA will display a list of supported QR payment methods for the user to select from
  qrPaymentMethods = QRPaymentMethods.ALIPAY_PLUS
)
 
val voidRequest = PosRequest.Transaction.Void(
  orgTranId = "Original Trans ID",
  posMessageId = "xxxx",
  adminPwd = "yyyy"
)
 
val result =
  client.post("http://${remoteIpAddress.value}:${remotePort.value}/api/v1/trans") {
    contentType(ContentType.Application.Json)
    setBody(request)
  }
val response = result.body<PosResponse<TransactionResponse>>()Enquiry Transaction Status with orignalTranId
To enquiry previous transaction by the transaction ID
val result = client.get("http://${remoteIpAddress.value}:${remotePort.value}/api/v1/trans/${request.orgTranId}")
val response = result.body<PosResponse<TransactionResponse>>()Enquiry Transaction Status with posMessageId
To enquiry previous transaction by the posMessageId
val result =
  client.get("http://${remoteIpAddress.value}:${remotePort.value}/api/v1/trans/status/${request.posMessageId}")
val response = result.body<PosResponse<TransactionResponse>>()Reload configuration
Force to reload EMV configurations and payment keys
val result = client.get("http://${remoteIpAddress.value}:${remotePort.value}/api/v1/reload")
val response = result.body<PosResponse<Unit>>()Response Code & Data Model
Refer to Response code for more details
Refer to Data Model for more details