Headless SDK (Pago Android)


👍

SDK recomendado

Para una experiencia de integración sin problemas, recomendamos utilizar el  Android Seamless SDK. Esta opción proporciona una solución pago flexible con componentes de interfaz de usuario preconstruidos y opciones de personalización.

Esta página proporciona una guía del SDK Yuno Headless Android para pagos.

Este SDK es ideal para comerciantes que:

  • Necesitas control total sobre la interfaz de usuario de pago y la experiencia del usuario
  • ¿Quieres crear flujos de pago personalizados?
  • Requiere capacidades de integración avanzadas

El SDK Headless incluye características principales como:

  • Acceso directo a la API para pago
  • Generación de Token para métodos de pago
  • Gestión de la autenticación 3DS
  • Recogida de datos para la prevención del fraude

Los comerciantes que prefieran una solución de interfaz de usuario preconstruida, pueden utilizar nuestro Full SDK o Lite SDK en su lugar.

Requisitos

Antes de comenzar la integración de Yuno Android SDK, asegúrate de que tu proyecto cumple los requisitos técnicos. Además, asegúrate de que se cumplen los siguientes requisitos previos:

  • Debes tener una cuenta Yuno activa.
  • Necesitas tus credenciales de la API de Yuno (account_id, public-api-keyy private-secret-key), que puedes obtener en Sección de desarrolladores del panel de Yuno. Estas credenciales son necesarias para autenticar las solicitudes a la API de Yuno. La API se utiliza para:
    • Cree un customer, que se requiere antes de iniciar los pagos
    • Cree un checkout_session, que inicialice el flujo de pago
    • Crear el pago asociado a la sesión
📘

Última versión del SDK

Comprueba las notas de la versión o visita el repositorio Yuno Android SDK para verificar la versión actual del SDK disponible.

Paso 1: Crea un cliente

Cree un cliente utilizando el endpoint Crear cliente antes de iniciar los pagos. Este paso es necesario para:

  • Identificar a la persona que realiza el pago
  • Activar la función de método de pago guardado (si está activada)
  • Seguimiento del historial de pagos

El ID de cliente devuelto desde este endpoint se utilizará al crear el checkout_session.

Paso 2: Crea una sesión de pago

Crear un nuevo checkout_session utilizando la función del endpoint Crear sesión de pago para inicializar el flujo de pago. Asegúrese de que:

  • Incluya el ID de cliente obtenido en el paso anterior
  • Almacenar lo devuelto checkout_session ID para su uso en pasos posteriores

El objeto checkout_session es único para cada intento de pago y no se puede reutilizar.

Paso 3: Incluye la biblioteca en tu proyecto

Incluye el SDK de Yuno en tu proyecto a través de Gradle. Añade la fuente del repositorio:

maven { url "https://yunopayments.jfrog.io/artifactory/snapshots-libs-release" }

Añade la dependencia del SDK de Yuno a tu aplicación en el archivo build.gradle archivo:

dependencies {
    implementation 'com.yuno.payments:android-sdk:{last_version}'
}

El SDK de Yuno incluye, por defecto, el INTERNET permiso, que se requiere para realizar solicitudes de red.

<uses-permission android:name="android.permission.INTERNET" />

Paso 4: Initialize headless SDK la clave pública.

Importa Yuno y proporciona una clave API pública válida. PUBLIC_API_KEY para initialize Headless SDK. Si no tienes tus credenciales API, consulta la página Desarrolladores (Credenciales) para ver cómo recuperarlas del panel de control.

Cree una aplicación personalizada si aún no lo ha hecho. En la onCreate() método de la clase de tu aplicación, initialize SDK llamando a la función Yuno.initialize() función:

class CustomApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    Yuno.initialize(
      this,
      PUBLIC_API_KEY,
      config: YunoConfig,
    )
  }
}

Paso 5: Iniciar el proceso de pago

Llame al apiClientPayment después de que tu cliente selecciona un método de pago para iniciar el proceso de pago. Esta función requiere parámetros de configuración e inicia la recopilación de la información necesaria para las herramientas de autenticación 3DS y de prevención del fraude configuradas en tu enrutamiento.

La tabla siguiente describe los parámetros necesarios:

Parámetro

Descripción

country_code

  • Este parámetro determina el país para el que se está configurando el proceso de pago.
  • La lista completa de países admitidos y sus country_code está disponible en la Cobertura de países .

checkout_session

  • Example: '438413b7-4921-41e4-b8f3-28a5a0141638'

El siguiente bloque de código muestra un ejemplo de configuración de parámetros:

 val apiClientPayment = Yuno.apiClientPayment(
   country_code = "US",
 checkoutSession "74bf4b96-6b35-42a6-8c73-2fe094c34ca9",
   context = this
)

Paso 6: Generar token

Tras recopilar la información del usuario, crea un token de un solo uso (OTT) utilizando la función apiClientPayment.generateToken . Dado que se trata de una función asincrónica, utiliza una try/catch para gestionar los errores que puedan producirse. Los siguientes ejemplos muestran dos escenarios diferentes para crear un token un solo uso:

  1. Ejemplo 1: Crea un token un solo uso utilizando una tarjeta como método de pago e incluyendo toda la información requerida de la tarjeta.
  2. Ejemplo 2:Crea un token de un solo uso usando el vaulted_token .

Ventajas de utilizar una token acorazada

Cuando utilizas un token bóveda con el SDK, toda la información sobre fraude de los proveedores que configuraste en el enrutamiento de tu tarjeta se recopila y se adjunta al token un solo uso. También puedes añadir información sobre la cuota y un código de seguridad si el proveedor lo requiere.


apiClientPayment.generateToken(
   collectedData = TokenCollectedData(
 checkoutSession "checkout_session",
       métodoDePago = MétodoDePago (
           tipo = "TARJETA",
 vaultedToken  nulo,
           tarjeta = DatosDeTarjeta(
               guardar = verdadero,
               detalle = Detalle(
                   mesDeCaducidad = 11,
                   añoDeCaducidad = 55,
                   número = "4111111111111111",
                   securityCode = "123",
                   holderName = "Nombre Apellido",
                   type = CardType.DEBIT
               ),
               installment = Installment(
                   id = "id",
                   value = 12
               )
           ),
cliente = Cliente(
id = "id",
merchantCustomerId = "merchant_customer_id",
nombre = "nombre",
apellidos = "apellidos",
sexo = Sexo.NB,
fechaDeNacimiento = "DD/MM/AAAA",
 email "[email ]",
               país = "EE. UU.",
   documento = Documento(
    tipoDeDocumento = "PAS",
    númeroDeDocumento = "PAS12312"
   ),
   teléfono = Teléfono(
    número = "321123321123",
    códigoDePaís = "1"
   )
   )
   )),

   contexto = esto
)

apiClientPayment.generateToken(
   collectedData = TokenCollectedData(
 checkoutSession "checkout_session",
       paymentMethod = PaymentMethod(
           type = "CARD",
 vaultedToken "a1c7c5d1-b260-4dc6-909a-8368704233cf",
           card = CardData(
               save = true,
               detail = Detail(
                   expirationMonth = 11,
                   expirationYear = 55,
                   number = "4111111111111111",
                   securityCode = "123",
                   holderName = "Nombre Apellido",
                   type = CardType.DEBIT
               ),
               installment = Installment(
                   id = "id",
                   value = 12
               )
           ),
           customer = Customer(
               id = "id",
               merchantCustomerId = "merchant_customer_id",
               firstName = "firstName",
               lastName = "lastName",
               lastName = "lastName",
               sexo = Sexo.NB,
               fechaDeNacimiento = "DD/MM/AAAA",
 email "[email ]",
               país = "CO",
               documento = Documento(
                   tipoDeDocumento = "PAS",
                   númeroDeDocumento = "PAS12312"
               ),
               phone = Phone(
                   number = "321123321123",
 countryCode "57"
               )
           )
       )
   ),
   context = this
)

El objeto apiClientPayment.generateToken devuelve un tipo Observable, que es una subclase de LiveData. Puedes observar la respuesta como una LiveData con el siguiente tipo SingleLiveEvent<Map<String, Any?>>que es un LiveData que sólo se emite una vez. El tipo de respuesta es un Map que contiene toda la respuesta. El siguiente bloque de código muestra ejemplos de respuestas tras llamar a la función apiClientPayment.generateToken .

["token": "9ee44ac7-9134-4598-ae28-a26fec03099d",
     "type": "CARD",
     "customer": ["billing_address": null,
                  "first_name": null,
                  "gender": "",
                  "phone": nil,
                  "browser_info": ["color_depth": null,
                                   "language": "en",
                                   "accept_header": "*/*",
                                   "browser_time_difference": null,
                                   "accept_content": null,
                                   "accept_browser": null,
                                   "java_enabled": null,
                                   "user_agent": "YunoSDK_Example/1 CFNetwork/1406.0.4 Darwin/22.6.0",
                                   "screen_height": "844.0",
"screen_width": "390.0",
"javascript_enabled": null],
                  "document": null,
                  "last_name": null,
                  "device_fingerprint":null,
                  "email": null],
     "country": "US",
     "vaulted_token": null,
     "installment": ["rate": "",
                     "id": "cca80084-961b-4212-9c34-54f03f4f10ae",
                     "value": 24,
                     "amount": null],
     "card_data": null]
["token": "9ee44ac7-9134-4598-ae28-a26fec03099d",
     "type": "CARD",
     "customer": ["billing_address": null,
                  "first_name": null,
                  "gender": "",
                  "phone": nil,
                  "browser_info": ["color_depth": null,
                                   "language": "en",
                                   "accept_header": "*/*",
                                   "browser_time_difference": null,
                                   "accept_content": null,
                                   "accept_browser": null,
                                   "java_enabled": null,
                                   "user_agent": "YunoSDK_Example/1 CFNetwork/1406.0.4 Darwin/22.6.0",
                                   "screen_height": "844.0",
"screen_width": "390.0",
"javascript_enabled": null],
"document": null,
"last_name": null,
"device_fingerprint":null,
                  "email": null],
     "country": "BR",
     "vaulted_token":"a1c7c5d1-b260-4dc6-909a-8368704233cf",
     "installment": ["rate": "",
                     "id": "cca80084-961b-4212-9c34-54f03f4f10ae",
                     "value": 24,
                     "amount": null],
     "card_data": null]

La respuesta del endpoint proporciona el parámetro sdk_action_required que define si son necesarias acciones adicionales.

El siguiente bloque de código muestra un ejemplo de observación de la respuesta:

apiClientPayment.generateToken(datos, contexto).observe(contexto) { respuesta ->
   val token = respuesta[token"] como String?
   val error = respuesta["error"] como String?
}

Paso 7: Crear el pago

Tras generar el token de un solo uso, cree el pago llamando a la función endpoint de Crear pago. Incluye el token un solo uso obtenido en Paso 6 en el payment_method.token de tu pedido. El siguiente bloque de código muestra un ejemplo de un pedido de creación de pago:

{
  "merchant_order_id": "0000022",
  "country": "US",
  "account_id": "<Your account_id>",
  "description": "Test",
  "amount": {
    "currency": "USD",
    "value": 500
  },
  "customer_payer": {
    "id": "cfae0941-7234-427a-a739-ef4fce966c79"
  },
  "checkout": {
    "session": "<checkout session>"
  },
  "workflow": "SDK_CHECKOUT",
  "payment_method": {
    "type":"CARD",
    "token": "2cd31999-e44e-4de3-bbe4-179981ff4295"
  }
}

La respuesta endpoint incluye sdk_action_required que indica si se necesitan acciones adicionales para completar el pago:

  • En los métodos de pago síncronos, el pago se completa instantáneamente. En este caso sdk_action_required será false en la respuesta de la API y finaliza el proceso de pago
  • Para los flujos de pago que requieren una interacción SDK adicional, sdk_action_required será true. Cuando esto ocurra, proceda a Paso 8 para los próximos pasos

Paso 8: Obtener la URL del desafío 3DS (si es necesario)

Cuando un pago requiere autenticación 3DS, puede ser necesario un desafío adicional para verificar la identidad del cliente. Para más detalles sobre este proceso, consulta la página de 3D Secure. Si se requiere una impugnación de verificación 3DS, la respuesta del endpoint Create Payment incluirá lo siguiente:

  • Un tipo de transacción THREE_D_SECURE tipo de transacción
  • Estado igual a PENDING y subestado igual a WAITING_ADDITIONAL_STEP
  • sdk_action_required = true

Llame al getThreeDSecureChallenge y proporcionar la función checkoutSession utilizado para crear el pago para obtener la URL del reto 3DS. Tras obtener la URL, redirige a tu cliente para que complete el reto. El siguiente bloque de código muestra cómo utilizar la función getThreeDSecureChallenge función:

fun ApiClientPayment.getThreeDSecureChallenge(
   context: Context,
   checkoutSession: String? = null,
): SingleLiveEvent<ThreeDSecureChallengeResponse>

El objeto getThreeDSecureChallenge devuelve la función ThreeDSecureChallengeResponse descrita en el siguiente bloque de código:

datos clase ThreeDSecureChallengeResponse(
   val tipo: String,
   val datos: String,
)

El objeto type puede devolver ERROR o URLdefine si la función devuelve una URL válida para el reto:

  • Si el type = URL, data contendrá la URL a la que debe acceder su cliente para completar el reto 3DS.
  • Si el type = ERROR, data contendrá el mensaje de error, informando del origen del problema.

El siguiente bloque de código muestra un ejemplo de cómo puedes observar la respuesta de ThreeDSecureChallengeResponse:

apiClientPayment.getThreeDSecureChallenge(this)?.observe(this) {
   si (it.type == "URL") {
   } else 
}

Cuando el tipo de respuesta es "URL", puede cargar la URL de la impugnación 3DS en la vista que prefiera (WebView, pestaña personalizada o navegador). Si el tipo de respuesta no es "URL", indica que se ha producido un error y debe gestionarlo adecuadamente mostrando un mensaje de error al usuario.

Para completar el reto 3DS, redirige a los clientes a la URL devuelta por getThreeDSecureChallenge(context). Una vez completado con éxito, los clientes son redirigidos automáticamente a la página callback_url que especificó al crear el checkout_session utilizando la función del endpoint Crear Sesión de Checkout endpoint. El siguiente ejemplo muestra cómo cargar la URL del reto 3DS en una WebView:

val webView = WebView(this)
webViewContainer.addView(
   webView,
   ConstraintLayout.LayoutParams(
       ConstraintLayout.LayoutParams.MATCH_PARENT,
       ConstraintLayout.LayoutParams.MATCH_PARENT
   )
)
webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(
   object {
       @JavascriptInterface
       fun messageFromWeb(data: String?) {
       }
   },
   "Android"
)
webView.loadUrl(url)

La interfaz JavaScript debe utilizar el nombre messageFromWeb(data : String?) y se añadirá con el nombre Android. Esto le permite capturar eventos de desafío y determinar cuándo se completan.

Para completar el flujo de pago Headless SDK :

  1. Utiliza Yuno Webhooks para recibir notificaciones sobre:

    • El resultado del desafío 3DS
    • El estado final del pago
  2. Opcionalmente, recupera los detalles del pago utilizando el endpoint Recuperar pago por ID.

Para ver la guía completa de implementación de pago, consulta Headless SDK (pago).

Características complementarias

Yuno Android SDK proporciona servicios y configuraciones adicionales que puedes utilizar para mejorar la experiencia de los clientes. Utiliza la personalización del SDK para cambiar la apariencia del SDK para que coincida con tu marca o para configurar el cargador.

Loader

La funcionalidad del cargador se controla a través del keepLoader en el parámetro YunoConfig que se documenta en línea en la sección de configuración del SDK.

Personalización del SDK

Puede cambiar el aspecto del SDK para adaptarlo a su marca. Para obtener más información, consulte la página de personalización del SDK.

📘

Acceder a la aplicación de demostración

Además de los ejemplos de código proporcionados, puedes ver el repositorio de Yuno para completar la implementación de Yuno Android SDKs.