# Integrate SDK

Integrate with Tyro Embedded Payments SDK to accept in-person payments using a compatible Android device.
You will first need to implement [Account Authorisation](/pos/embedded-payments/account-authorisation).
An open-source example app is available at [https://github.com/tyro/tyro-tap-to-pay-sdk-android](https://github.com/tyro/tyro-tap-to-pay-sdk-android).

## Overview of Embedded Payments Android SDK Flow

p
img
## Integration

### Github access

Tyro Embedded Payments SDK is distributed via Github Packages, so you will need a [Github account](https://github.com/join).
Follow [these steps](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) to create a Personal Access Token (PAT).
A 'classic' token with (at least) `public_repo` and `read:packages` scope are sufficient.
Once you have created your PAT, you will need to reference it from your Android project.
You can do this using environment variables, as in the example below.

### In settings.gradle add the Tyro repository:


```kotlin kotlin
dependencyResolutionManagement {
    repositories {
        maven {
            url = uri("https://maven.pkg.github.com/tyro/tyro-tap-to-pay-sdk-android")
            credentials {
                username = System.getenv("GITHUB_PACKAGES_USER")
                password = System.getenv("GITHUB_PACKAGES_PASSWORD")
            }
        }
    }
}
```


```groovy groovy
dependencyResolutionManagement {
    repositories {
        maven {
            url 'https://maven.pkg.github.com/tyro/tyro-tap-to-pay-sdk-android'
            credentials {
                username System.getenv("GITHUB_PACKAGES_USER")
                password System.getenv("GITHUB_PACKAGES_PASSWORD")
            }
        }
    }
}
```

### In build.gradle add the Tyro dependency:


```kotlin kotlin

dependencies {
    // ...
    debugImplementation("com.tyro:tyro-tap-to-pay-sdk-debug:latest.release")
    releaseImplementation("com.tyro:tyro-tap-to-pay-sdk-release:latest.release")
}
```


```groovy groovy

dependencies {
    // ...
    debugImplementation "com.tyro:tyro-tap-to-pay-sdk-debug:latest.release"
    releaseImplementation "com.tyro:tyro-tap-to-pay-sdk-release:latest.release"
}
```

### Accept tyroDebug build type

Tyro publishes two dependencies:

- `tyro-tap-to-pay-sdk-debug`
- `tyro-tap-to-pay-sdk-release`


The `release` dependency includes some additional security checks.
Most notable of these is that it requires [on-device developer mode](https://developer.android.com/studio/debug/dev-options) to be **disabled**.

### R8 Support

Tyro Embedded Payments SDK does not currently support [R8 full mode](https://r8.googlesource.com/r8/+/refs/heads/master/compatibility-faq.md#r8-full-mode).
You may need to include the following line in `gradle.properties`.


```properties
android.enableR8.fullMode=false
```

### Demonstration App

The demo app has three build flavors:

- stub
- dev
- prd


The app should run in `stub` flavor out of the box.

To run against the development environment:

- Change the `applicationId` in `build.gradle` to `com.tyro.taptopay.sdk.demo`.
- Use [the sample app keystore](https://github.com/tyro/tyro-tap-to-pay-sdk-android/blob/master/SampleApp/app/sampleappkeystore.jks) password you have been provided during onboarding.
- Implement authentication with Tyro on your own server.


To run in a production environment:

- Change the `applicationId` in `build.gradle` to your own
- Include [your own keystore](https://developer.android.com/studio/publish/app-signing#generate-key), and update the `signingConfigs` part of `build.gradle` with your keystore details
- Export a public certificate from your keystore, and provide it to Tyro along with your `applicationId`


See below for more detail on these requirements.

### Verification data

Tyro requires the following in order to verify the integrity of your app.
These must be provided even to run the app against the Tyro test environment.

* Your application ID
* Your upload public certificate


#### Application ID

This is the `applicationId` as defined in your `build.gradle` file.


```kotlin
android {
    // ...
    defaultConfig {
        // ...
        applicationId = "com.example.my.app" // <-
    }
}
```

#### Public certificate

The public certificate is derived from the upload keystore specified in `build.gradle`:


```kotlin
android {
    // ...
    signingConfigs {
        create("my_signing_config") {
            keyAlias = "my_key"
            keyPassword = "p@ssw0rd"
            storeFile = file("my.keystore")
            storePassword = "p@ssw0rd"
        }
    }
}
```

Follow [these instructions](https://developer.android.com/studio/publish/app-signing#generate-key) to create your own upload keystore if required.
You can export the public certificate from the keystore using keytool:


```bash
keytool -export -keystore tyro.keystore -alias my_alias -rfc -file public.pem
```

### Your server — add an endpoint to create a connection

When the Android App is first initialised, a request must be sent to your server to establish a Tyro Embedded Payments connection.
Upon receiving the client request, authenticate your user and send the request to Tyro with the `readerId` in the request body (obtained from [Account Authorisation](/pos/embedded-payments/account-authorisation)).
The Embedded Payments connection response will return a `connectionSecret`, this should be returned to your App.


```javascript
// Node sample code
const express = require("express");
const app = express();
const axios = require('axios');

// ...

app.post("/create-connection", async (req, res) => {
  const { userIdOrDeviceId } = req.body; // You can associate a user or device to the reader.
  // You will manage the authentication between your server and App.

  const readerId = await this.findReaderIdForUser(userIdOrDeviceId);

  // Create a Embedded Payments connection by providing the location Id
  const connectionResponse = await axios.post('https://api.tyro.com/connect/tap-to-pay/connections',
  {
    "readerId": readerId // e.g. 2688fcf2-44dd-4c72-88ac-79d0910f2933
  },
  {
    headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer exampleJwt'
    }
  });

  res.send({
    connectionSecret: connectionResponse.connectionSecret
  });
});
```

### Implement `ConnectionProvider`

The `ConnectionProvider` is responsible for fetching the Tyro connection secret from your server and providing it to the SDK for authentication. Override the `createConnection()` method to return the connection secret.
The following example uses a Ktor client and kotlinx serialisation.


```kotlin
class SdkDemoConnectionProvider: ConnectionProvider {

    @Serializable
    private data class MyResponse(
        val connectionSecret: String
    )

    private val client = HttpClient(CIO) {
        install(ContentNegotiation) { json() }
    }

    override suspend fun createConnection(): String {
        val url = "https://<YOUR-API-DOMAIN>/create-connection"
        val response: MyResponse = client.get(url).body()
        return response.connectionSecret
    }
}
```

### Create an instance of TapToPaySdk

Define the sdk as a variable in your `Application` class and create an instance inside the `onCreate()` method.


```kotlin
class SdkDemoApplication : Application() {
    lateinit var tapToPaySDK: TapToPaySdk

    override fun onCreate() {
        super.onCreate()
        tapToPaySDK = createTapToPaySdk()
    }

    @Suppress("KotlinConstantConditions")
    private fun createTapToPaySdk(): TapToPaySdk {
        val tyroEnv: TyroEnv =
            when (BuildConfig.FLAVOR) {
                "stub" -> TyroEnvStub()
                "dev" ->
                    TyroEnvDev(
                        connectionProvider = SdkDemoConnectionProvider(),
                    )
                else ->
                    TyroEnvProd(
                        connectionProvider = SdkDemoConnectionProvider(),
                    )
            }
        return createInstance(tyroEnv, applicationContext, TyroOptions(TyroScreenOrientation.PORTRAIT, TyroThemeMode.SYSTEM, hapticFeedbackEnabled = true)).apply {
            setPosInfo(
                PosInfo(
                    posName = "Demo",
                    posVendor = "Tyro Payments",
                    posVersion = "1.0",
                    siteReference = "Sydney",
                ),
            )
        }
    }
}
```

There are three environments available:

- stub (TyroEnvStub)
- development (TyroEnvDev)
- production (TyroEnvProd)


The stub environment does not interact with the Tyro backend at all, so does not require a `ConnectionProvider`.
It may be useful for UI development etc. Return values and delays can be customised to help with testing.

### In the onCreate method of your activity

**Important: your Activity will need to be a [ComponentActivity](https://developer.android.com/reference/androidx/activity/ComponentActivity) (or one of its subclasses)**


```kotlin

private lateinit var transactionLauncher: ActivityResultLauncher<TransactionRequest>
// ...

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    // register a handler for transaction results
    tapToPaySdk.registerTransactionResultHandler(this) { transactionResult ->
        when (transactionResult.status) {
            TransactionStatus.TXN_SUCCESS -> handleTransactionSuccess(transactionResult)
            else -> handleTransactionFailure(transactionResult)
        }
    }

    // initialise the Tyro Embedded Payments SDK
    // this could take some time - you will need to show a loading screen or similar
    showLoadingScreen()
    tapToPaySdk.init(this) { initResult ->
        hideLoadingScreen()
        when (initResult.status) {
            InitStatus.INIT_SUCCESS -> handleInitSuccess(initResult)
            else -> handleInitFailure(initResult)
        }
    }
}
```

### Admin Settings

Create a button in your screen, use `updateAdminSettings` method to start the admin settings activity.
This screen allows your POS administrators to set a mandatory refund passcode and additional settings in the future.


```kotlin
tapToPaySdk.updateAdminSettings(activity)
```

### Making Payments

Start a new transaction


```kotlin
val transactionRequest = TransactionRequest(
    type = TransactionType.TRANSACTION,
    amountInCents = amountInCents,
    reference = "my-unique-transaction-reference",
)
tapToPaySdk.startTransaction(activity, transactionRequest)
```

Start a new refund


```kotlin
val transactionRequest = TransactionRequest(
    type = TransactionType.REFUND,
    amountInCents = amountInCents,
    reference = "my-unique-transaction-reference"
)
tapToPaySdk.startTransaction(activity, transactionRequest)
```

### Register Webhooks

[Webhook events](/pos/apis/embedded-payments/events) are sent once a payment has occurred. Your server should listen to these events and handle them as required, for example to send a payment receipt email.

### Tyro UI

A Tyro UI will be visible from when a transaction is initiated until it is complete.
Please note final designs are still pending.

p
img
p
img
p
img