# Installation

Install the POS+ SDK to process payments from your Castles device.

## Before you start

### Pre-requisites

To integrate the POS+ SDK, you need the following:

* **Merchant credentials:** Get your PXP POS listener URL and account credentials (username and password).
* **Network connectivity:** Confirm connectivity to the specified POS URL.
* **Android SDK compatibility:** Ensure that your Android project's SDK level (both the minimum and target SDK versions) aligns with the SDK requirements. Check the documentation or release notes of the SDK to confirm the required Android SDK levels, as using an unsupported SDK level could cause compatibility issues. If necessary, update your project's `build.gradle` file to meet these requirements.


### Minimum requirements

Before you start, make sure your project's `build.gradle` file has the correct SDK levels:

|  |  |  |
|  --- | --- | --- |
| Minimum SDK | 26 (Android 8.0 API level 26). | Required for POS+ SDK functionality. |
| Compile SDK | 34 (Android 14 API level 34). | Ensures access to latest Android features and security updates. |
| Target SDK | Should match compile SDK (34). | Recommended for Google Play Store compliance. |



```kotlin
android { 
  compileSdk = 34 
  defaultConfig { 
    minSdk = 26 
    targetSdk = 34 
    // ... Other configurations 
  } 
}
```

## Step 1: Add the AAR file to your project

Place the downloaded `.aar` file into the `libs` folder of your project.

If the libs folder doesn't already exist, you may need to create it:

1. In Android Studio, right-click on the app directory.
2. Select **New > Directory**, then name the new directory `libs`.
3. Copy the `.aar` file into this `libs` directory.


## Step 2: Add the AAR as a dependency

In `settings.gradle`, add the `libs` folder as a dependency source so the AAR file is included:


```kotlin
 repositories {
   flatDir {
     dirs 'libs'
   }
 }
```

In `app/build.graddle`, add the AAR file as an implementation dependency:


```kotlin
implementation(files("libs/pxp.pos.sdk-v1.0.0.aar"))
```

## Step 3: Sync the project

Click **Sync Now** at the top of the Android Studio window to ensure the project includes the AAR library properly.

Once the sync completes successfully, you should be able to reference and use the SDK classes and functions provided by the AAR in your project.

## Step 4: Initialise the SDK

Before using any SDK functionalities, initialise the SDK by configuring `SdkConfig` with the necessary parameters.

The SDK supports two authentication methods:

* Credentials-based authentication (username and password).
* API key authentication.


If unsure, contact your PXP representative to determine which authentication method you should use for your integration.

To initialise the SDK, use one of the following snippets:


```kotlin Credentials
private fun initSDK(): InitResponse {
  try {
    // Use credentials
    val sdkConfig = SdkConfig.Builder()
      .setPosListenerUrl("http://192.168.204.39:8181")
      .setCredential(Credentials("testusername", "testpassword"))
      .setMerchant("ACME")
      .setSite("ACM000000001")
      .build()

    val initResponse = PxpPosSdk.getInstance().init(sdkConfig)

    if (initResponse.code == InitCode.Success) {
      Log.i("MainActivity", "SDK Initialisation Success")
      return true
    }

    if (initResponse.code == InitCode.Error) {
      Log.i("MainActivity", "SDK Initialisation Error")
      return false
    }

  } catch (e: Exception) {
    // Handle exceptions
    Log.e("MainActivity", "SDK Initialisation Error", e)
    return false
  }
  return false
}
```


```kotlin API key
private fun initSDK(): InitResponse {
  try {
    // Use an API key
    val sdkConfig = SdkConfig.Builder()
      .setPosListenerUrl("http://192.168.204.39:8181")
      .setApiKey("your-api-key-here")
      .setMerchant("ACME")
      .setSite("ACM000000001")
      .build()

    val initResponse = PxpPosSdk.getInstance().init(sdkConfig)

    if (initResponse.code == InitCode.Success) {
      Log.i("MainActivity", "SDK Initialisation Success")
      return true
    }

    if (initResponse.code == InitCode.Error) {
      Log.i("MainActivity", "SDK Initialisation Error")
      return false
    }

  } catch (e: Exception) {
    // Handle exceptions
    Log.e("MainActivity", "SDK Initialisation Error", e)
    return false
  }
  return false
}
```

| Property | Description |
|  --- | --- |
| `setCredentials`Credentials | Your username and password. This is required if `setApiKey` isn't provided. |
| `setApiKey`string | Your API key. This is required if `setCredentials` isn't provided. |
| `setPosListenerUrl`string | The local HTTP endpoint to use for communication between your merchant application and POS+. |
| `setMerchant`string | Your merchant identifier, as assigned by PXP. |
| `setSite`string | Your site identifier, as assigned by PXP. |


## Step 5: Add dependencies to your project

To use the POS+ SDK, add the necessary dependencies to your project's `build.gradle`:


```kotlin
plugins {
  ……
  kotlin("kapt")
}

dependencies {
  implementation("org.jetbrains.kotlin:kotlin-reflect")

  // Gson for JSON parsing
  implementation("com.google.android.material:material:1.12.0")
  implementation ("com.google.code.gson:gson:2.10.1")

  // OkHttp for networking
  implementation("com.squareup.okhttp3:okhttp:4.11.0") 

  implementation("org.mapstruct:mapstruct:1.5.2.Final")
  kapt("org.mapstruct:mapstruct-processor:1.5.2.Final")
    
  ……
}
```

### ProGuard configuration (optional)

If you're using ProGuard, add the following rules to prevent issues with obfuscation:


```kotlin
# Keep PXP POS SDK classes 

-keep class com.pxp.pos.sdk.** { *; } 
-dontwarn com.pxp.pos.sdk.** 

# Keep transaction response models 
-keep class * implements java.io.Serializable { *; }
```

## Step 6: Initiate a transaction

After initialisation, you can initiate a transaction using the `processPayment` method, which requires a `TransactionRequest` object containing transaction details.


```kotlin
private fun MakeInitTransaction( 
  intentType: IntentType, 
  amount: BigDecimal, 
): InitiateTransactionRequest { 
  return InitiateTransactionRequest( 
    merchantTransactionId = "Purchase-001", 
    merchantTransactionDate = OffsetDateTime.now(), 
    pointOfInteraction = PointOfInteraction( 
      pointOfSaleId = "001", 
      language = "en", 
      storeAndForwardType = StoreAndForwardType.None 
    ), 
    amounts = Amounts( 
      currencyCode = "GBP", 
      transaction = amount, 
      gratuity = BigDecimal(0) 
    ), 
    transactionMethod = TransactionMethod( 
      intent = intentType 
    ), 
    merchantDeeplink = "app://merchantsimulator/main" 
  ) 
}
```