Before you start
Keep the first test small and repeatable.
- An approved security owner and a defined test fixture or card set.
- A clear boundary for keys, PINs, APDU data, certificates and payment host integration.
- A private test environment with redacted logs and no customer credentials.
Step by step
Build it in 4 deliberate passes.
Each pass produces a checkable result. Keep device-specific calls in the adapter and keep the workflow portable.
- 01
Name the card and security boundary
ICC, PSAM, PICC, magnetic stripe, PIN pad and secure element are different workflows. Record card type, slot, protocol, owner and target device instead of calling everything “card support”.
- 02
Keep secrets outside the demo
Use opaque test handles and redacted outcomes in the public pattern. Keys, PIN blocks, track data, KSN values, certificates and customer fixtures stay in the approved private integration.
- 03
Make activation and release symmetrical
Activate one session, validate the response length and status, then deactivate in a finally path. A failed transaction must not leave a card or secure module open.
- 04
Require security review before hardware claims
The local SDK samples are useful for module discovery, but they do not establish compliance, payment approval or production compatibility. Those claims need a separate evidence record.
Copyable pattern / Kotlin
Start with the boundary, then bind the device.
This deliberately uses an opaque test handle. It is not a payment implementation and does not contain keys or credentials.
data class SecureRequest(
val operation: String,
val testHandle: String,
)
sealed interface SecureResult {
data object Accepted : SecureResult
data class Declined(val reason: String) : SecureResult
data class Failed(val reason: String) : SecureResult
}
interface SecurePort {
suspend fun execute(request: SecureRequest): SecureResult
}
suspend fun executeApprovedOperation(port: SecurePort): SecureResult =
runCatching {
port.execute(SecureRequest("approved-test", "fixture-01"))
}.getOrElse {
SecureResult.Failed("secure-operation-failed")
}When the happy path breaks
Make recovery part of the first implementation.
Operators experience the failure state, not the API call. Translate device signals into a useful next action.
Discard the response from the public workflow, record a redacted failure and release the session.
Stop the test, rotate the affected credential and remove the artifact from the test environment.
Split the compatibility record and request a device-specific security review.
Before you ship
Use this checklist on the target configuration.
- 01
Use approved test credentials and fixtures only in a private environment.
- 02
Verify activation, success, timeout, failure and release paths.
- 03
Run a redacted-log scan before sharing any report or sample.
- 04
Record the security owner, device, firmware, SDK and approval scope.
Further reading
Use platform guidance for the parts the device SDK does not own.
These references cover Android lifecycle, broadcast, testing and architecture patterns. Device-specific compatibility still needs a model-level validation record.