Quick Start
This section provides a step-by-step guide for creating your first purchase transaction.
Before you begin
The NearPay team is required to create a sandbox account for you using your email and phone number, as well as your Android package name to initiate this integration process.
Additionally, you must possess an Android physical device capable of supporting NFC to test the integration and run the app on it.
Start your first transaction
- Configuring the Secure Maven Repository / Dependencies
To get the private token , you need to contact Nearpay to get the token for the private repository.
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven(url = "https://developer.huawei.com/repo/")
maven {
url = uri("https://gitlab.com/api/v4/projects/37026421/packages/maven")
credentials(HttpHeaderCredentials::class) {
name = "Private-Token"
value = "nearpayPosGitlabReadToken" //will be supported from Nearpay Product Team
}
authentication {
create<HttpHeaderAuthentication>("header")
}
}
}
}
- Include the following dependencies in your Module level
build.gradle
file:
implementation("io.nearpay:terminalsdk-release:0.0.70")
implementation("com.google.android.gms:play-services-location:20.0.0")
implementation("com.huawei.hms:location:6.4.0.300")
-
change the
minSdk
version to 28 in yourbuild.gradle
file: -
Add the following line in your
AndroidManifest.xml
file :
<application
android:allowBackup="true"
tools:replace="android:allowBackup" // Add this line to avoid manifest merger issues
Make sure the following tools namespace is present in your <manifest> tag:// xmlns:tools="http://schemas.android.com/tools"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> // this tools namespace
...
- create a single instance of TerminalSDK, initialize it with the necessary configurations :
// initializing the terminalSDK may throw an exception, so wrap it in a try-catch block
try {
val nearpay = TerminalSDK.Builder()
.activity(this) // Sets the activity context
.environment(SdkEnvironment.SANDBOX) // Choose SANDBOX or PRODUCTION or INTERNAL
.googleCloudProjectNumber(12345678) // Set Google Cloud project number
.huaweiSafetyDetectApiKey("your_api_key") // Set Huawei API key
.country(Country.SA) // Set country SA, TR, USA, KEN ,
.build()
} catch (e: Throwable) {
Timber.e("Error initializing TerminalSDK: $e")
}
- Add required permissions :
Manifest.permission.ACCESS_FINE_LOCATION
Manifest.permission.ACCESS_NETWORK_STATE
Manifest.permission.INTERNET
Manifest.permission.READ_PHONE_STATE
Manifest.permission.NFC
- Send OTP :
val mobileLogin = MobileLogin("+966500000000")
nearpay.sendOTP(mobileLogin, object : SendOTPMobileListener {
override fun onSendOTPMobileSuccess(otpResponse: OtpResponse) {
Log.d("Login", " onSendOTPMobileSuccess ($otpResponse)")
}
override fun onSendOTPMobileFailure(otpMobileFailure: OTPMobileFailure) {
Log.d("Login", " onSendOTPMobileFailure ($otpMobileFailure)")
}
})
- Verify OTP :
After sending the OTP, verify it to authenticate the user.`
val loginData = LoginData(
mobile = "+966500000000",
code = "123456"
)
nearpay.verify(loginData, object : VerifyMobileListener {
override fun onVerifyMobileSuccess(user: User) {
Log.d("Login", " onVerifyMobileSuccess ($user.name)")
}
override fun onVerifyMobileFailure(verifyMobileFailure: VerifyMobileFailure) {
Log.d("Login", " onVerifyMobileFailure ($failure)")
}
})
- List Terminals
Retrieves a paginated list of terminals associated with the user.
lateinit var firstTerminal: Terminal
userInstance.listTerminals(
page = 1,
pageSize = 10,
filter = null, // You can pass the terminal ID to get a specific terminal
object : GetTerminalsListener {
override fun onGetTerminalsSuccess(terminalsConnection: List<TerminalConnection>) {
// Handle success
terminalsConnection.firstOrNull()?.let { terminal ->
// Access terminal data
val terminalName = terminal.terminalConnectionData.name
// Update UI or store reference
firstTerminal = terminal
}
}
override fun onGetTerminalsFailure(getTerminalsFailure: GetTerminalsFailure) {
// Handle failure
Log.d("Terminals", "Terminals list failure: $getTerminalsFailure")
}
},
)
- Connect Terminal
Establishes a connection with a terminal.
firstTerminal.connect(
activity = this,
listener = object : ConnectTerminalListener {
override fun onConnectTerminalSuccess(terminal: Terminal) {
// Terminal connected successfully
// Store terminal instance for future operations
terminalInstance = terminal
}
override fun onConnectTerminalFailure(connectTerminalFailure: ConnectTerminalFailure) {
// Handle failure
Log.d("Terminal", "Terminal connection failed: $connectTerminalFailure")
}
}
)
- Purchase transaction
var amount = 100
var transactionUUID = UUID.randomUUID().toString() // the transaction UUID should be unique for each transaction and managed by the developer to communicate with the SDK
var customerReferenceNumber = "" //[optional] any number you want to add as a refrence
terminal.purchase(
amount = amount,
scheme = null, // eg.PaymentScheme.VISA, specifying this as null will allow all schemes to be accepted
transactionUUID = transactionUUID,
customerReferenceNumber = customerReferenceNumber,
readCardListener = object : ReadCardListener {
override fun onReadCardSuccess() {
// Card read successfully
Log.d("ReadCard", "Card read successfully")
}
// Called when the card reading process fails - issues with the specific card or its interaction
// Examples: card removed too quickly, unreadable card, wrong card orientation
override fun onReadCardFailure(readCardFailure: ReadCardFailure) {
// Handle card read failure
Log.d("ReadCard", "Card read failure: $readCardFailure")
}
@Override
public void onReaderDisplayed() {
Log.d("ReaderCard", "Reader Displayed")
}
@Override
public void onReaderClosed() {
Log.d("ReaderCard", "Reading Closed")
}
override fun onReaderWaiting() {
// Reader waiting for card
Log.d("ReadCard", "Reader waiting for card")
}
override fun onReaderReading() {
// Reading card in progress
Log.d("ReadCard", "Reading card in progress")
}
override fun onReaderRetry() {
// Reader retry needed
Log.d("ReadCard", "Reader retry needed")
}
override fun onPinEntering() {
// PIN entry in progress
Log.d("ReadCard", "PIN entry in progress")
}
override fun onReaderFinished() {
// Card read completed
Log.d("ReadCard", "Card read completed")
}
override fun onReadingStarted() {
// Card read started
Log.d("ReadCard", "Card read started")
}
// Called when the card reader device itself encounters an error
// Examples: hardware malfunction, connection issues, device not ready
override fun onReaderError(error: String?) {
// Handle reader error
Log.d("ReadCard", "Reader error: $error")
}
},
sendTransactionListener = object : SendTransactionListener {
override fun onSendTransactionCompleted(transactionResponse: TransactionResponse) {
// Handle completed transaction
Log.d("Transaction", "Transaction completed: $transactionResponse")
// To got the receipt based on the country you can got it like :
// transactionResponse.events[0].receipt.getMadaReceipt() for Saudi Arabia
// transactionResponse.events[0].receipt.getEPXReceipt() for USA
// transactionResponse.events[0].receipt.getBKMReceipt() for Turkey
}
override fun onSendTransactionFailure(failure: SendTransactionFailure) {
// Handle transaction failure
Log.d("Transaction", "Transaction failure: $failure")
}
}
)
Your setup is complete, allowing you to test the payment feature.