> For the complete documentation index, see [llms.txt](https://docs.payments.thalescloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payments.thalescloud.io/classic-push-provisioning/es/guia-del-desarrollador/configuracion-del-sdk/android.md).

# Android

Push Provisioning SDK se utiliza para tokenizar tarjetas para Google Pay y Samsung Pay. Este SDK gestiona la comunicación con los SDK de Google Pay y Samsung Pay. También simplifica el flujo de tokenización para las aplicaciones emisoras.

Esta sección está dirigida a desarrolladores de aplicaciones emisoras de Android que desean integrar Push Provisioning SDK en su aplicación.

### Servicios disponibles <a href="#available-services" id="available-services"></a>

Thales Push Provisioning SDK proporciona los siguientes servicios:

* Le permite integrar una aplicación emisora con las API de Push Provisioning SDK, como `isCardDigitized` y `addCard` (Google Pay y Samsung Pay).
* Reduce la necesidad de comprender los SDK de Google Pay y Samsung Pay.
* Reutilice los servicios de Push Provisioning SDK en proyectos existentes.
* Inscriba el FPAN en Google Pay o Samsung Pay.
* Acceda a las API del servidor TSH.

### Requisitos previos <a href="#prerequisites" id="prerequisites"></a>

* Versión de Java: 11
* Versión de Android Studio: Chipmunk o posterior.
* Un dispositivo con Google Play Services (para Google Pay).

> <i class="fa-info-circle">:info-circle:</i>
>
> Para la funcionalidad completa de Google Pay, se recomienda ejecutarlo en dispositivos móviles.

### Integración con la app emisora <a href="#integrating-with-issuer-app" id="integrating-with-issuer-app"></a>

* Cree una carpeta llamada `libs` dentro del directorio del módulo (normalmente 'app'), como se muestra en la siguiente figura:

<figure><img src="/files/3b223d7ab6cbc4c21b8f5d9dd98fc3651aa8cd9a" alt=""><figcaption></figcaption></figure>

* Copie el archivo AAR de Push Provisioning SDK en la `libs` carpeta.
* Desde Push Provisioning SDK v1.12.2, copie el archivo JAR de Samsung Pay SDK en la  `libs` carpeta.
* Abra el `build.gradle` o `build.gradle.kts` de la aplicación y agregue las siguientes dependencias:

{% tabs %}
{% tab title="Groovy" %}

```groovy
android {
  defaultConfig {
    ndk {
      abiFilters 'arm64-v8a', 'x86_64', 'armeabi-v7a', 'x86'
    }
  }
  buildTypes {
        debug {
            // para Samsung Pay
            manifestPlaceholders = [DEBUG_MODE: 'Y', SPAY_API_LEVEL: 2.22]
        }
        release {
            // para Samsung Pay
            manifestPlaceholders = [DEBUG_MODE: 'N' , SPAY_API_LEVEL: 2.22]
        }
    }
}

dependencies {
    debugImplementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' // la versión de depuración contiene el registrador
    releaseImplementation 'com.squareup.okhttp3:okhttp:4.9.1'
    implementation "com.google.android.gms:play-services-base:18.5.0"
    implementation "com.google.android.gms:play-services-basement:18.5.0"
    implementation files('libs/tpcsdk.aar') // use el nombre de archivo más reciente de Push Provisioning SDK 
    implementation files('lib/samsungpay_2.22.00.jar') // desde la versión 1.12.2 del SDK
    implementation 'net.java.dev.jna:jna:5.17.0@aar'
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
android {
  defaultConfig {
    ndk {
      abiFilters += listOf("arm64-v8a", "x86_64", "armeabi-v7a", "x86")
    }
  }
}

dependencies {
    debugImplementation ("com.squareup.okhttp3:logging-interceptor:4.9.1") // la versión de depuración contiene el registrador
    releaseImplementation ("com.squareup.okhttp3:okhttp:4.9.1")
    implementation ("com.google.android.gms:play-services-base:18.2.0")
    implementation (files("libs/tpcsdk.aar")) // use el nombre de archivo más reciente de Push Provisioning SDK 
    implementation ("net.java.dev.jna:jna:5.17.0@aar")
}
```

{% endtab %}
{% endtabs %}

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Nota <a href="#note" id="note"></a>
>
> * Desde Push Provisioning SDK V1.7.0, la biblioteca JNA se usa como dependencia. Se recomienda usar JNA V5.5.0 porque no se garantiza que otras versiones funcionen con Push Provisioning SDK.
> * Desde Push Provisioning SDK V1.12.0, es obligatorio usar JNA V5.17.0 para admitir tamaños de página de 16 KB.

* Para importar una dependencia de árbol de archivos en la compilación de Gradle, abra el `build.gradle` o `build.gradle.kts` y agregue la siguiente dependencia:

{% tabs %}
{% tab title="Groovy" %}

```groovy
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
}
```

{% endtab %}
{% endtabs %}

* Consulte la aplicación de ejemplo y la documentación de Java para aprender a usar las API de Push Provisioning SDK.

> <i class="fa-exclamation-circle">:exclamation-circle:</i>
>
> #### Compatibilidad con tamaños de página de 16 KB <a href="#supporting-16-kb-page-sizesbr" id="supporting-16-kb-page-sizesbr"></a>
>
> A partir del 1 de noviembre de 2025, todas las apps recién desarrolladas y las actualizaciones de apps existentes enviadas a Google Play, y destinadas a dispositivos con Android 15 o posterior, deben admitir tamaños de página de 16 KB. Esta compatibilidad está disponible para Push Provisioning SDK V1.12.0 y posteriores.
>
> Al compilar un APK que admita tamaños de página de 16 KB:
>
> * Actualice a Push Provisioning SDK V1.12.0 o posterior.
> * Actualice la dependencia JNA a la versión 5.17.0 o posterior. Para JNA 5.17.0, la versión requerida de Android Gradle Plugin (AGP) es 8.0.2 o posterior. Si usa una versión de AGP anterior a 8.0.2, puede encontrar problemas de compilación.
> * Cuando la versión de AGP es 8.5.1 o posterior, la app se alinea automáticamente con tamaños de página de 16 KB. Si es anterior a 8.5.1, establezca las [opciones de empaquetado heredadas](https://developer.android.com/guide/practices/page-sizes#agp_version_85_or_lower) en el `build.gradle` archivo.

### Configuración <a href="#configuration" id="configuration"></a>

Use el siguiente fragmento para configurar Push Provisioning SDK en su aplicación móvil:

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Nota <a href="#note-1" id="note-1"></a>
>
> Desde Push Provisioning SDK V1.9.0, su aplicación puede establecer un `Contexto` en lugar de una `Activity` al configurar Push Provisioning SDK para Google Pay y Samsung Pay. Un `Activity` solo es requerido por la nueva API, `addCard(Activity activity, CardInfo cardInfo, TPCSDKListener<T> listener)`, para el aprovisionamiento push de Google Pay.

{% tabs %}
{% tab title="Java" %}

```java
protected static final int HTTP_TIMEOUT = 60;

protected CountDownLatch mCountDownLatch;

protected void awaitCountDownLatch() {
    try {
        mCountDownLatch.await(HTTP_TIMEOUT, TimeUnit.SECONDS);
    } catch (Exception e) { // Ignorado.
    }
}

protected void resetCountDownLatch() {
    mCountDownLatch = new CountDownLatch(1);
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    Config config = new Config();
    config.setIssuerId("ISSUERID");
    config.setUrl("URL"); // URL correspondiente
    
    // La lista se puede actualizar en consecuencia. Por ejemplo, puede que solo necesite tener un tipo de OEMPayType.
    List<OEMPayType> oemPayTypes = Arrays.asList(
        OEMPayType.NONE,
        OEMPayType.GOOGLE_PAY,
        OEMPayType.SAMSUNG_PAY,
        OEMPayType.HUAWEI_PAY);

    for (OEMPayType oemPayType:oemPayTypes) {
        if (oemPayType == OEMPayType.SAMSUNG_PAY) {
            config.setContext(getApplicationContext());
            config.setServiceId("SERVICEID");
            config.setVisaClientAppId("VisaClientAppID");
        } else if (oemPayType == OEMPayType.HUAWEI_PAY) {
            String callbackUrl = "tpcsdk://com.thalesgroup.tpc.demo/tokenRequestorsPage";
            config.setCallbackUrl(callbackUrl);
            config.setActivity(getActivity());
        } else if (oemPayType == OEMPayType.GOOGLE_PAY) {
            //Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context` en lugar de `Activity` durante la configuración de Push Provisioning SDK para Google Pay
            config.setContext(getApplicationContext());
        } else if (oemPayType == OEMPayType.NONE) {
            //Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context` en lugar de `Activity` durante la configuración de Push Provisioning SDK para el aprovisionamiento de esquema
            config.setContext(getApplicationContext());
        }
        configSdk(oemPayType, config);
    }
}

public void configSdk(OEMPayType oemPayType, Config configs) throws InterruptedException {
    // para push a esquema
    configs.setOemPayType(oemPayType);
    resetCountDownLatch();
    TPCManager.getInstance().config(configs, new TPCSDKListener<Boolean>() {
        @Override
        public void onStart() {
        }

        @Override
        public void onSuccess(TPCResult<Boolean> result) {
            Log.d("CONFIG_SDK", "Configuración exitosa..." + oemPayType.getOemType());
            mCountDownLatch.countDown();
        }

        @Override
        public void onError(TPCSDKException exception) {
            Log.e("CONFIG_SDK", "La configuración falló con el error: " + exception.getMessage());
            mCountDownLatch.countDown();
        }
    });
    awaitCountDownLatch();
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
class MainViewModel : ViewModel() {
    fun configureMultipleOEM(activity: Activity){
        viewModelScope.launch {
            val config = Config()
            config.issuerId = "ISSUERID"
            config.url = "URL" // URL correspondiente

            // La lista se puede actualizar en consecuencia. Por ejemplo, puede que solo necesite tener un tipo de OEMPayType.
            val oemPayTypes: List<OEMPayType> = listOf(
                OEMPayType.NONE,
                OEMPayType.GOOGLE_PAY,
                OEMPayType.SAMSUNG_PAY,
                OEMPayType.HUAWEI_PAY
            )
            for (oemPayType in oemPayTypes) {
                when (oemPayType) {
                    OEMPayType.SAMSUNG_PAY -> {
                        config.serviceId = "SERVICEID"
                        config.context = applicationContext
                        config.visaClientAppId = "VisaClientAppID";
                    }
                    OEMPayType.HUAWEI_PAY -> {
                        val callbackUrl = "tpcsdk://com.thalesgroup.tpc.demo/tokenRequestorsPage"
                        config.callbackUrl = callbackUrl
                        config.activity = activity
                    }
                    OEMPayType.GOOGLE_PAY -> {
                        //Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context` en lugar de `Activity` durante la configuración de Push Provisioning SDK para Google Pay
                        config.context = applicationContext
                    }
                    OEMPayType.NONE -> {
                        //Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context` en lugar de `Activity` durante la configuración de Push Provisioning SDK para el aprovisionamiento de esquema
                        config.context = applicationContext
                    }
                }
                configSdk(oemPayType, config).collect{
                    println(it)
                }
            }
        }
    }

    private fun configSdk(oemPayType: OEMPayType, configs: Config): Flow<TPCResult<Boolean>> =  callbackFlow {
        val callBack = object : TPCSDKListener<Boolean?> {
            override fun onStart() {}
            override fun onSuccess(result: TPCResult<Boolean?>) {
                Log.d("CONFIG_SDK", "Configuración exitosa..." + oemPayType.oemType)
                channel.close()
            }

            override fun onError(exception: TPCSDKException) {
                Log.e("CONFIG_SDK", "La configuración falló con el error: " + exception.message)
                channel.close()

            }
        }
        TPCManager.getInstance().config(configs, callBack)
        
    }
}
```

{% endtab %}
{% endtabs %}

#### Configuración de Samsung Pay <a href="#samsung-pay-configurations" id="samsung-pay-configurations"></a>

A partir de Android R (SDK de destino 30), debe declarar `<queries>` en el archivo de manifiesto de Android.

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools" 
  package="xxx.xxx.xxx.xxx">
  
  <application>
    <!-- para Samsung Pay -->
    <meta-data
      android:name="debug_mode"
      android:value="${DEBUG_MODE}" />
    <!-- para Samsung Pay -->
    <meta-data
      android:name="spay_sdk_api_level"
      android:value="${SPAY_API_LEVEL}" />
  </application>
  
  <queries>
    <package android:name="com.samsung.android.spay" />
    <package android:name="com.samsung.android.samsungpay.gear" />
  </queries>
```

### Ofuscación <a href="#obfuscation" id="obfuscation"></a>

Si su app tiene problemas de ProGuard con Samsung Pay, use las siguientes reglas:

```
# Samsung Pay
-keep class com.samsung.android.sdk.** { *; }
-keep interface com.samsung.android.sdk.** { *; }
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.payments.thalescloud.io/classic-push-provisioning/es/guia-del-desarrollador/configuracion-del-sdk/android.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
