En esta página

Manual de Instalación SDK Android

Integración del SDK Android
Descripción general del SDK de procesamiento de pagos

El SDK de procesamiento de pagos es una herramienta de desarrollo proporcionada por nuestra empresa que permite a los desarrolladores integrar funcionalidades de pago en sus aplicaciones Android. El SDK facilita el procesamiento seguro de transacciones financieras, incluidos pagos con tarjeta de crédito, débito y otros métodos de pago electrónicos.

  • Transacciones bancarias con tarjetas Master Card, VISA y AMEX – Ventas
  • Cancelación de transacciones
  • Consulta de transacciones
  • Consulta de transacciones por referencia única
Audiencia objetivo

Este manual está dirigido a desarrolladores de aplicaciones que trabajan en proyectos que requieren integración de pagos en terminales punto de venta Android. Se espera que los usuarios tengan conocimientos básicos de desarrollo de aplicaciones móviles y estén familiarizados con el entorno de desarrollo de Android.

Convenciones utilizadas

En este manual, se utilizan convenciones estándar de documentación técnica, como estilos de texto específicos para resaltar comandos o fragmentos de código, notación de teclas y términos técnicos que se definen previamente en un glosario para una comprensión clara y coherente.

Ejemplo de llamada a componente para realizar una venta:

 

La constante SMART_PACKAGE es el nombre del paquete de la aplicación de medios de pago y tiene el valor de “com.smart.smart” .

La variable suffix es el nombre del tipo de versión de medios de pago que se desea invocar, puede variar su valor, por ejemplo: “.qa.debug” , “.client.debug”, “.debug”, “”.

				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout..activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "SALE",
            tip = "150.00",
            print = false,
            cancel = false,
            reference = "",
            date = "",
            uniqueReference = "1234",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "card",
            promotionPay = "withoutPromotions",
            promotionSkip = "monthWithoutInterest",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}

				
			
Conocimientos técnicos básicos

Se detallarán los conocimientos de programación en Kotlin y Android necesarios para comprender y utilizar efectivamente el SDK. Además, se mencionarán conceptos importantes como la arquitectura de aplicaciones Android y la manipulación segura de datos sensibles.

  • Conocimientos en el lenguaje de programacion Kotlin
  • Conocimientos de programacion en aplicaciones móviles Android
Hardware y software requeridos

Se proporcionará una lista detallada de requisitos de hardware y software, incluyendo la versión mínima de Android requerida para la integración del SDK, la capacidad de memoria necesaria y la compatibilidad con versiones específicas de Android Studio y SDK de Android.

  1. Terminal MPOS Urovo modelo i9000/i9000S
  2. Mínimo sistema operativo Android 8.1.0 (API 27)
  3. Tener la última actualización de firmware V2.1.0
  4. Configuración correcta de fecha GMT-06:00 Hora estándar central
Firmware

Un dispositivo actualizado cumple con las características descritas en la imagen, en caso contrario se debe instalar la última actualización de firmware, para más información ponerse en contacto con Smart ya que la actualización que necesita puede variar dependiendo del modelo de dispositivo.

Glosario

Término

Significado

Autentication


Api key o número de serie de la terminal.

Amount

Monto de la transacción

Aperation

Tipo de operación a realizar.

Ejemplo: Venta, Consulta, etc.

Cancel

Indicador para saber si es una cancelación.

Reference

Referencia de la transacción. SG_REFERENCE_FOLIO

Unique_reference

Referencia única de la transacción.

Tip

Propina de la transacción

From

Path de retorno hacia la integración

Json

Formato de texto consumible desde el aplicativo

Date

Fecha / Dáa de la transacción.

TP

Aplicación Third Party o aplicación del integrador

N/A

No Aplica

O

Opcional

M

Mandatorio

TPV

Terminal Punto de Venta

SDK

Software Developer Kit (conjunto de herramientas integradas al aplicativo)

Periférico

Producto adicional a la venta o consumo, como por ejemplo un producto extra: aceite, esponja, limpiador, etc.

Fleetcards

Es la aplicación de Smart que se usa para poder realizar cobros referentes a la industria del combustible o gasolina

Se proporcionarán enlaces directos y pasos detallados para descargar el SDK desde el sitio web oficial del proveedor. Además, se incluirán instrucciones para la instalación del SDK utilizando diferentes métodos, como la integración de Gradle o Maven en el proyecto de la aplicación.

 

Agregar liga de SDK

 

1. Dirigirse al dispositivo donde está guardado el APK

2. Copiar el APK “SmartWrapper _{LAST_VERSION}.apk” al directorio de su preferencia del dispositivo android.

3. Abrir el manejador de archivos del dispositivo y dirigirse a la carpeta donde anteriormente guardo el apk para instalar

4. Instalar o reinstalar en el dispositivo Android el apk copiado previamente.

5. Se visualiza la aplicación de SmartWrapper en la lista de aplicaciones del dispositivo.

6. Icono de la aplicación SmartWrapper en el dispositivo Android

Instale el idioma de su TPV a español, para ello, siga los siguientes pasos:

 

  1. Diríjase al menú principal de su TPV
  2. Seleccione Configuración
  3. Seleccione Sistema
  4. Seleccione idiomas y entradas
  5. Seleccione idiomas
  6. Seleccione “Agregar un idioma”
  7. Seleccione el idioma donde se encuentra la TPV
  8. Desplace el idioma principal de su preferencia
  9. Listo, el idioma está configurado. 

Instale el idioma de su TPV a español, para ello, siga los siguientes pasos:

  1. Diríjase al menú principal de su TPV
  2. Seleccione Configuración
  3. Seleccione sistema
  4. Seleccione fecha y hora
  5. Seleccione fecha y hora automática
  6. Seleccione Zona horaria GMT-06:00 hora estándar central o la zona horaria de su ubicación
  7. Es a su elección el formato de 24 horas, si lo desea selecciónelo,
  8. Su configuración está lista.

 Se proporcionarán instrucciones específicas para agregar el SDK como una dependencia en el archivo de configuración del proyecto, así como cualquier configuración adicional necesaria, como la inicialización del SDK y la configuración de parámetros de conexión.

Antes de llevar a cabo un intent, hay que asegurarnos que el paquete de la aplicación corresponde a la versión que queremos abrir. Actualmente en Smart Wrapper hay varios Application ID posibles, por ejemplo:

Versión Productiva modo Debug

“com.smart.smart.debug"

Versión QA modo Debug

“com.smart.smart.qa.debug”

Versión Client modo Debug

“com.smart.smart.client.debug”

Por lo tanto, el paquete debe ser llamado con la cadena correspondiente dependiendo de la versión de la aplicación. Esto puede ser comprobado revisando el nombre de las carpetas, revisando, en el almacenamiento como se guarda la aplicación.

Un ejemplo de una llamada mediante un intent en Kotlin:
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "SALE",
            tip = "150.00",
            print = false,
            cancel = false,
            reference = "",
            date = "",
            uniqueReference = "1234",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "card",
            promotionPay = "withoutPromotions",
            promotionSkip = "monthWithoutInterest",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}


				
			
Ejemplo en versiones anteriores
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "SALE",
            tip = "150.00",
            print = false,
            cancel = false,
            reference = "",
            date = "",
            uniqueReference = "1234",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "card",
            promotionPay = "withoutPromotions",
            promotionSkip = "monthWithoutInterest",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}


				
			

 Se proporcionarán instrucciones específicas para agregar el SDK como una dependencia en el archivo de configuración del proyecto, así como cualquier configuración adicional necesaria, como la inicialización del SDK y la configuración de parámetros de conexión.

Antes de llevar a cabo un intent, hay que asegurarnos que el paquete de la aplicación corresponde a la versión que queremos abrir. Actualmente en Smart Wrapper hay varios Application ID posibles, por ejemplo:

Versión Productiva modo Debug

“com.smart.smart.debug"

Versión QA modo Debug

“com.smart.smart.qa.debug”

Versión Client modo Debug

“com.smart.smart.client.debug”

Por lo tanto, el paquete debe ser llamado con la cadena correspondiente dependiendo de la versión de la aplicación. Esto puede ser comprobado revisando el nombre de las carpetas, revisando, en el almacenamiento como se guarda la aplicación.

Un ejemplo de una llamada mediante un intent en Kotlin:
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "SALE",
            tip = "150.00",
            print = false,
            cancel = false,
            reference = "",
            date = "",
            uniqueReference = "1234",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "card",
            promotionPay = "withoutPromotions",
            promotionSkip = "monthWithoutInterest",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}


				
			
Ejemplo en versiones anteriores
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "SALE",
            tip = "150.00",
            print = false,
            cancel = false,
            reference = "",
            date = "",
            uniqueReference = "1234",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "card",
            promotionPay = "withoutPromotions",
            promotionSkip = "monthWithoutInterest",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}


				
			

Se detallarán los pasos para generar claves de acceso y tokens de autenticación en el panel de control del proveedor del SDK. Esto incluirá la creación de una cuenta de desarrollador, la solicitud de credenciales API y la gestión de claves y tokens.

Clase destino

Descripción

AuthenticationBroadcast

Realiza la autenticación con los servicios de Smart para poder transaccionar en un lapso de 12 horas

Figura 2.1.1 Flujo de Autenticación
  1. La aplicación cliente manda a llamar la operación de autenticación de la aplicación financiera SmartWrapper mediante un Intent de autenticación.
  2. La aplicación financiera SmartWrapper recibe el llamado, recopila el número de serie de la terminal Urovo y realiza un llamado de autenticación hacia la plataforma de Smart.
  3. La plataforma de Smart valida el número de serie recibido por la aplicación SmartWrapper, y procede a realizar los procesos internos de autenticación de la terminal.
  4. La aplicación SmartWrapper recibe el resultado de la autenticación de la plataforma Smart, procesa el resultado y lo retorna a la aplicación de terceros.

Parámetro

Parámetro

Tipo

Petición

Ejemplo

Authentication

String

O

“1234-5678-901234”, “PRUEBAS”, ”SMART”

Respuesta

Parámetro

Tipo

Petición

Ejemplo

Json

String

O

{“response_code”:”200”,”response_message”:”You have acces –VALID KEY 12HRS”}

Un ejemplo de una llamada
				
					package com.smart.thirdpartysample
 

import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
 
class ExampleAuthActivity : AppCompatActivity(), PermissionBroadcast.PermissionBroadcastListener {
 
    private var permissionBroadcast: PermissionBroadcast? = null
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        registerBroadCast()
        authenticate(
            apikey = "63485399-802d-47b8-8547-01f39ffb2b28",
            idCommerce = "",
            idIntegrator = "d9b5297ab84c31aaa98565558593f8411a3002ce",
            folio = "98262151010504_SQA"
        )
    }
 
    override fun onDestroy() {
        super.onDestroy()
        permissionBroadcast?.let {
            unregisterReceiver(it)
        }
    }
 
    private fun registerBroadCast() {
        permissionBroadcast = PermissionBroadcast(this)
        val filter = IntentFilter().apply {
            addAction(RECEIVER_ACTION_AUTHENTICATE)
        }
        registerReceiver(permissionBroadcast, filter)
    }
 
    private fun authenticate(
        apikey: String,
        idCommerce: String,
        idIntegrator: String,
        folio: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent().apply {
                putExtra("authentication", apikey) // prueba f6012bb1-fb84-40ff-8839-22a50aa0a672
                putExtra("commerce_id", idCommerce)
                putExtra("integrator_id", idIntegrator)
                putExtra("invoice_id", folio)
                putExtra("force_validate_authentication", true)
                addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
                component =
                    ComponentName(SMART_PACKAGE.plus(suffix),
                        "${SMART_PACKAGE}.thirdparty.broadcast.AuthenticationBroadcast",
                    )
            }
            CoroutineScope(Dispatchers.IO).launch {
                sendBroadcast(intent)
            }
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
    override fun showMessage(message: String) {
        Log.d("TAG1", message)
    }
 
}
 
class PermissionBroadcast(val permissionBroadcastListener: PermissionBroadcastListener) : BroadcastReceiver() {
    override fun onReceive(p0: Context?, p1: Intent?) {
        val bundle = p1?.extras ?: return
        val status = bundle.getBoolean("TX_STATUS", false)
        val error = bundle.getString("TX_ERROR", "")
        val jsonReturn = bundle.getString("TX_JSON_RETURN", "")
        permissionBroadcastListener.showMessage(jsonReturn)
    }
 
    interface PermissionBroadcastListener {
        fun showMessage(message: String)
    }
}
 
				
			
Ejemplo en la terminal
Intents

Esta sección del manual técnico se dedica a profundizar en los Intents específicos que nuestro SDK ofrece para facilitar y optimizar las operaciones de su aplicación. Cada uno de estos Intents ha sido diseñado con un enfoque en la eficiencia, seguridad y facilidad de uso, asegurando que pueda integrarlos sin contratiempos en su proyecto. A continuación, se describen los Intents que abordaremos en detalle:

Clase destino

Descripción

AuthenticationBroadcast

Realiza la autenticación con los servicios de Smart para poder transaccionar en un lapso de 12 horas

Figura 2.1.2. Flujo de Autenticación.
  1. La aplicación cliente manda a llamar la operación de autenticación de la aplicación financiera SmartWrapper mediante un Intent de autenticación.
  2. La aplicación financiera SmartWrapper recibe el llamado, recopila el el api key ,id integrador(no debe ser mas de 40 posiciones) el id commerce  y el folio de la terminal Urovo y realiza un llamado de autenticación hacia el core smart.
  3. La plataforma de Smart valida los datos enviados recibido por la aplicación SmartWrapper, y procede a realizar los procesos internos de autenticación de la terminal.
  4. La aplicación SmartWrapper recibe el resultado de la autenticación de la plataforma Smart, procesa el resultado y lo retorna a la aplicación de terceros.

Parámetro

Tipo

Petición

authentication

String

Longitud Máx: 36 carácteres

M

Integrator_id

String

 
Longitud Máx: 40 carácteres

M

Invoice_id

String

 
Longitud Máx: 50 carácteres

M

Commerce_id

String


Longitud Máx: 50 carácteres

O

Parámetro

Tipo

Petición

Ejemplo

Json

String

O

{“response_code”:”200”,”response_message”:”You have acces –VALID KEY 12HRS”}

Configuración de parámetros de conexión:

Se proporcionarán instrucciones para configurar parámetros de conexión, como la URL del servidor de pagos, el puerto y los protocolos de seguridad, en la aplicación. Esto garantizará una conexión segura y confiable entre la aplicación y los servidores de procesamiento de pagos.

Para garantizar la correcta comunicación entre la aplicación integradora y la aplicación SmartWrapper Financiera es necesario integrar los siguientes permisos en el archivo AndroidManifest.xml como se muestra en la Figura 1.1

Un ejemplo de una llamada
				
					import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
 
class ExampleAuthActivity : AppCompatActivity(), PermissionBroadcast.PermissionBroadcastListener {
 
    private var permissionBroadcast: PermissionBroadcast? = null
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        registerBroadCast()
        authenticate(
            apikey = "63485399-802d-47b8-8547-01f39ffb2b28",
            idCommerce = "",
            idIntegrator = "d9b5297ab84c31aaa98565558593f8411a3002ce",
            folio = "98262151010504"
        )
    }
 
    override fun onDestroy() {
        super.onDestroy()
        permissionBroadcast?.let {
            unregisterReceiver(it)
        }
    }
 
    private fun registerBroadCast() {
        permissionBroadcast = PermissionBroadcast(this)
        val filter = IntentFilter().apply {
            addAction(RECEIVER_ACTION_AUTHENTICATE)
        }
        registerReceiver(permissionBroadcast, filter)
    }
 
    private fun authenticate(
        apikey: String,
        idCommerce: String,
        idIntegrator: String,
        folio: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent().apply {
                putExtra("authentication", apikey) // prueba f6012bb1-fb84-40ff-8839-22a50aa0a672
                putExtra("commerce_id", idCommerce)
                putExtra("integrator_id", idIntegrator)
                putExtra("invoice_id", folio)
                putExtra("force_validate_authentication", true)
                addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
                component =
                    ComponentName(SMART_PACKAGE.plus(suffix),
                        "${SMART_PACKAGE}.thirdparty.broadcast.AuthenticationBroadcast",
                    )
            }
            CoroutineScope(Dispatchers.IO).launch {
                sendBroadcast(intent)
            }
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
    override fun showMessage(message: String) {
        Log.d("TAG1", message)
    }
 
}
 
class PermissionBroadcast(val permissionBroadcastListener: PermissionBroadcastListener) : BroadcastReceiver() {
    override fun onReceive(p0: Context?, p1: Intent?) {
        val bundle = p1?.extras ?: return
        val status = bundle.getBoolean("TX_STATUS", false)
        val error = bundle.getString("TX_ERROR", "")
        val jsonReturn = bundle.getString("TX_JSON_RETURN", "")
        permissionBroadcastListener.showMessage(jsonReturn)
    }
 
    interface PermissionBroadcastListener {
        fun showMessage(message: String)
    }
}
 
 
				
			
Ejemplo en la terminal

 Se proporcionarán ejemplos de código y explicaciones detalladas sobre cómo inicializar y configurar el SDK en la aplicación. Esto incluirá la configuración de opciones de configuración, la gestión de eventos de inicialización y la integración con el ciclo de vida de la aplicación Android.

				
					<permission
    android:name="thirdparty.smart.permission.DATA"
    android:protectionLevel="signature" />
<uses-permission android:name="thirdparty.smart.permission.DATA" />

				
			

Detallaremos cómo implementar el proceso de venta en línea, permitiendo que su aplicación procese transacciones de manera eficaz y segura, abriendo las puertas a un sinfín de posibilidades comerciales.

Clase destino

Descripción

ContainerActivity

Realiza un cobro con los parámetros de entrada especificados

Parámetro

Tipo

Petición

Ejemplo

Amunt

String

0

“3000.45” o

“40000” o

“25.34”

Operation

String

M

“SALE”

Cancel

String

O

N/A

Unique_reference

String

O

“1234” o

“22345” o

“5567890”

Reference

String

O

N/A

Tip

String

O

“30.00” o

“100.45”

From

String

M

“ThirdPartySample”

Json

String

M

Json enviado como string con este formato

{

"activityStr":

"com.smart.thirdpartysample.DetailActivity",

"packageStr":"com.smart.thirdpartysample",

"print”: false

}

o

{

"activityStr":

"com.smart.thirdpartysample.DetailActivity",

"packageStr":"com.smart.thirdpartysample",

"print”: true

}

IdCommerce

String

O

commerceId

UserNumber

String

O

“12” o

“1334” o

“1”

UserName

String

O

“Carlos” o

“UserNam1” o

“Use1345”

FuelType

String

O

“verde” o

“VERDE” o

“Verde”

Liters

String

O

“5.45” o

“100.00” 0

“0.100”

pricePerLiters

String

O

“5.45” o

“100.00” 0

“0.100”

periphericals

String

O

“Limpiador|sku10|4000” o

“Esponja|uni12|3000”

paymentMethods

String

M

“TARJETA” o “EFECTIVO” o “MONEDERO” o “QR” o “NINGUNO”

promotionPay

String

O

“monthWithoutInterest” o

“inSinglePay”

monthsToPay

String

O

“03” o ”06” o ”09” o ”12” o ”15” o “99”

monthsToStartPaying

String

O

“03” o ”06” o ”09” o ”12” o ”15” o “99”

json

String

M

Campos ISO{“Nombre”:”valor”}

Parámetro

Tipo

Petición

Ejemplo

Json

String

O

{“response_code”:”200”,”response_message”:”You have acces –VALID KEY 12HRS”}

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "SALE",
            tip = "150.00",
            print = false,
            cancel = false,
            reference = "",
            date = "",
            uniqueReference = "1234",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "card",
            promotionPay = "withoutPromotions",
            promotionSkip = "monthWithoutInterest",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }

				
			

El putExtra operation recibe el valor de “SALE”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando la venta.
  • Una vez finalizado el cobro se retornará un JSON de respuesta con la información detallada de la transacción.

En esta subsección, explicaremos cómo implementar la funcionalidad de cancelación, permitiéndole a sus usuarios revertir operaciones de manera controlada y segura.

Clase destino

Descripción

ContainerActivity

Realiza una cancelación con la referencia SG_REFERENCE de la transacción y los parámetros de entrada especificados

Parámetro

Tipo

Petición

Ejemplo

Amunt

String

0

“0.00”

Operation

String

M

“CANCEL”

Cancel

Bolean

O

True

Unique_reference

String

O

N/A

Tip

String

O/M

“0.00”

From

String

M

N/A

Json

String

O

N/A

IdCommerce

String

O

commerceId

Parámetro

Tipo

Petición

Ejemplo

Json

String

M

Campos ISO{“Nombre”:”valor”}

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "CANCEL",
            tip = "150.00",
            print = false,
            cancel = true,
            reference = "123456789012",
            date = "",
            uniqueReference = "",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "",
            promotionPay = "",
            promotionSkip = "",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}


				
			

El putExtra operation recibe el valor de “CANCEL”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando la cancelación de la transacción.
  • Una vez finalizada la cancelación de la transacción por referencia SG_REFERENCE  se retornará un JSON de respuesta con la información detallada de la transacción.

La devolución manual permite que el usuario pueda realizar n veces la cantidad de una venta aprobada, fuera de tiempo al origen de una venta, siempre y cuando no rebase el monto total de una venta,

Para integrar la devolución en una aplicación de tercero cerciorarse que cuanta con los permisos necesarios para su terminal integradora:

  • PERMITIR_CANCELACION
  • CUSTOM_REFUND_ENABLE
  • SAME_DAY_REFUND_ENABLE
  • ENABLE_REFUND

Clase destino

Descripción

ContainerActivity

Realiza una devolución con la referencia TXN_APPROVAL_CODE de la transacción.

Parámetro

Tipo

Petición

Ejemplo

Amunt

String

M

“$0.00”

Operation

String

M

“TH_REFUND”

Cancel

Bolean

O

True

Reference

String

M

“12345a” alfanumerico

From

String

M

N/A

Json

String

O

N/A

date

String

M

N/A

Los campos referencia y monto no son obligatorios, pero la integración con la aplicación medios de pago, solicitara el ingreso de los datos si no se insertan en la llamada INTENT, para visualizar el ejemplo funcional, visite el manual de usuario de la aplicación medios de pago, “devolución manual”.

Parámetro

Tipo

Petición

Ejemplo

TX_JSON_RETURN

String

Campos ISO{“Nombre”:”valor”}

TX_ERROR

String

Código de error 10005

Cuando se salga de la app financiera, usando el botón de back, se regresará un mensaje de error (“TX_ERROR”) con el código 10005. Véase la sección de códigos de error.

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "3000.00",
            operation = "TH_REFUND",
            tip = "",
            print = true,
            cancel = true,
            reference = "SBT50",
            date = "",
            uniqueReference = "",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "",
            promotionPay = "",
            promotionSkip = "",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}

				
			

El putExtra operation recibe el valor de “TH_REFUND”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando la devolución de la transacción.
  • Una vez finalizada la devolución de la transacción se retornará un JSON de respuesta con la información detallada de la transacción.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Clase destino

Descripción

ContainerActivity

Realiza una consulta de las transacciones realizadas en la terminal.

Parámetro

Tipo

Petición

Ejemplo

Operation

String

M

BALANCE

from

String

M

N/A

print_report

String

M

“false”

Para el parámetro print_report, si se envía como “true” se permitirá la impresión de transacciones y reportes desde la aplicación “financiera”, si se envía como “false”, no se permitirá la impresión de reportes y en cuanto a las transacciones, nuestra aplicación devolverá un json con los datos de la transacción (“TX_JSON_RETURN”) en lugar de imprimir el pagaré fisico. Esto cuando se dé al botón de imprimir transacciones como se ve en la siguiente imagen:

Parámetro

Tipo

Petición

Ejemplo

TX_JSON_RETURN

String

Campos ISO{“Nombre”:”valor”}

TX_ERROR

String

Código de error 10005

Cuando se salga de la app financiera, usando el botón de back, se regresará un mensaje de error (“TX_ERROR”) con el código 10005. Véase la sección de códigos de error.

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
 
class ReportActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        doCallBalance(
            print = true
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun doCallBalance(print: Boolean) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            CoroutineScope(Dispatchers.IO).launch {
                val intent = Intent()
                intent.setClassName(SMART_PACKAGE.plus(suffix), "${SMART_PACKAGE}.activities.ContainerActivity")
                intent.putExtra("operation", OPERATION_BALANCE)
                intent.putExtra("from", resources.getString(R.string.app_name))
                intent.putExtra("print_report", print.toString())
                startActivityForResult.launch(intent)
            }
        } else {
            Toast.makeText(
                this,
                resources.getString(R.string.message_error_dont_exists_financial),
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
}

				
			

El putExtra operation recibe el valor de “BALANCE”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando el reporte de transacciones
  • Una vez seleccionada una transacción se retornará un JSON de respuesta con la información detallada de la transacción.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Clase destino

Descripción

ContainerActivity

Realiza una reimpresión de ticket con la referencia de plataforma SG_REFERENCE de la transacción.

Parámetro

Tipo

Petición

Ejemplo

Operation

String

M

“REPRINT”

Reference

String

M

“123456789012”

No aplica campo de respuesta

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "",
            operation = "REPRINT",
            tip = "",
            print = false,
            cancel = false,
            reference = "12345",
            date = "",
            uniqueReference = "",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "",
            promotionPay = "",
            promotionSkip = "",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}

				
			

El putExtra operation recibe el valor de “QUERY_UNIQUE”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando la reimpresión de la transacción por referencia SG_REFERENCE.
  • Una vez finalizada la reimpresión de la transacción se retornará un JSON de respuesta con el estatus de la transacción.

La consulta de última transacción es una función que le permite a usted saber el estatus general de una transacción solicitada, usted podrá ejecutar dicha operación en cualquier momento que así lo determine.

  • Se sugiere que dicha función sea ejecutada cuando el aplicativo smartWrapper no responda durante una transacción y usted como integrador ejecute un time out en su aplicación, en este caso usted deberá ejecutar la operación para saber cuál fue el estatus final de la transacción antes de realizar una nueva transacción, una vez que usted tenga la información, usted tendrá que tomar acciones para dicha transacción
  • Si usted recibe como respuesta de la transacción en el campo TX_ERROR algún código entre el rango 40001 a 45000 usted tendrá que ejecutar esta función nuevamente antes de realizar una segunda transacción, puesto que ha ocurrido algún error en la operación, si requiere más información sobre como recuperar la información, consulte “Como recibir la respuesta de una transacción” de este manual.

Clase destino

Descripción

ContainerActivity

Realiza una consulta basada en la referencia de la última transacción y con los parámetros de entrada especificados

Parámetro

Tipo

Petición

Ejemplo

Amount

String

0

“3000.45” o

“40000” o

“25.34”

Operation

String

M

“SALE”

Cancel

String

O

N/A

Unique_reference

String

O

“1234” o

“22345” o

“5567890”

Reference

String

O

N/A

Tip

String

O

“30.00” o

“100.45”

From

String

M

“ThirdPartySample”

Json

String

M

Json enviado como string con este formato

{

"activityStr":

"com.smart.thirdpartysample.DetailActivity",

"packageStr":"com.smart.thirdpartysample",

"print”: false

}

o

{

"activityStr":

"com.smart.thirdpartysample.DetailActivity",

"packageStr":"com.smart.thirdpartysample",

"print”: true

}

date

String

M

"ddmmaaaa"

Parámetro

Tipo

Petición

Ejemplo

Json

String

M

Campos ISO{“Nombre”:”valor”}

Ejemplo de llamado
				
					val intent = Intent ()
intent.setClassName(SMART_PACKAGE, "$SMART_PACKAGE.activities.ContainerActivity")
intent.putExtra("operation","QUERY_TX")
intent.putExtra("reference",reference)
intent.putExtra("from",this.resources.getString(R.string.app_name))
intent.putExtra("json",createJson(print))
intent.put_Extra("date",date)
startActivityForResult.launch(intent)
				
			

El putExtra operation recibe el valor de “QUERY_TX”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera la búsqueda de la transacción por referencia.

  • Una vez finalizada la búsqueda de la transacción por referencia se retornará un JSON de respuesta con la información detallada de la transacción.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Clase destino

Descripción

ContainerActivity

Realiza una cancelación con la referencia SG_REFERENCE de la transacción y los parámetros de entrada especificados

Parámetro

Tipo

Petición

Ejemplo

Amunt

String

0

“”

Operation

String

M

“QUERY_TX”

Cancel

String

O

False

Reference

String

M

“123456789012”

Unique_reference

String

O

""

Tip

String

O/M

""

From

String

M

N/A

Json

String

O

N/A

date

String

M

“ddmmaaaa”

Parámetro

Tipo

Petición

Ejemplo

Json

String

M

Campos ISO{“Nombre”:”valor”}

Ejemplo de llamado
				
					package com.smartpackage com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "",
            operation = "QUERY_TX",
            tip = "",
            print = false,
            cancel = false,
            reference = "123456789012",
            date = "22022024",
            uniqueReference = "",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "",
            promotionPay = "",
            promotionSkip = "",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}

				
			

El putExtra operation recibe el valor de “QUERY_TX”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando la búsqueda de la transacción por referencia SG_REFERENCE_FOLIO.
  • Una vez finalizada la búsqueda de la transacción por referencia se retornará un JSON de respuesta con la información detallada de la transacción.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Clase destino

Descripción

ContainerActivity

Realiza una consulta con la referencia única TXN_UNIQUE_REF de la transacción y con los parámetros de entrada especificados.

Parámetro

Tipo

Petición

Ejemplo

Operation

String

M

“”

Unique_reference

String

M

“QUERY_UNIQUE”

From

String

M

N/A

Json

String

O

N/A

date

String

M

“ddmmaaaa”

Parámetro

Tipo

Petición

Ejemplo

Json

String

M

Campos ISO{“Nombre”:”valor”}

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "",
            operation = "QUERY_UNIQUE",
            tip = "",
            print = false,
            cancel = false,
            reference = "",
            date = "22022024",
            uniqueReference = "12345",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "",
            promotionPay = "",
            promotionSkip = "",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager

				
			

El putExtra operation recibe el valor de “QUERY_UNIQUE”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando la búsqueda de la transacción por referencia única TXN_UNIQUE_REF.
  • Una vez finalizada la búsqueda de la transacción por referencia única se retornará un JSON de respuesta con la información detallada de la transacción.

Se proporcionarán estrategias y ejemplos para manejar errores y excepciones durante el proceso de pago, incluyendo la gestión de errores de comunicación, errores de autenticación y errores de procesamiento de transacciones. Esto ayudará a garantizar una experiencia de usuario sin problemas y confiable durante el proceso de pago

Errores enviados por la TPV cuando existe alguna excepción por parte de la app y no se existe interacción con plataforma o el SDK

Error Code 

Error Message

Posible solución

10000 

Error en ingreso de datos 

20000

Errores en flujos de la aplicación 

10001

El monto de la transacción no fue proporcionado.

Se debe proporcionar el monto en el Intent para realizar una transacción.

10003

Propina no soportada

El parámetro de propina debe
estar configurado como true.

10004

Excedes el monto maximo

No debe exceder el monto
configurado en el parámetro de límite de techo.

10005

Cancelada por el usuario

Tx cancelada por el usuario.

10006

Id del comercio invalido

Se debe proporcionar un ID de comercio valido por Smart.

10007

Id del integrador invalido

Se debe proporcionar un ID de integrador valido por Smart.

10008

Folio único de la transacción invalido

El sg_reference folio es invalido.

10009

Transaccion no soportada

El parametro cancelación debe estar en true.

10010

Identificador invalido

Se debe ingresar la referencia única.

10011

Referencia no propocionada

Se debe ingresar la referencia.

10012

Fecha no proporcionada

Se debe ingresar la fecha.

10013

El valor de usuario recibido es inválido, favor de configurarlo correctamente

Proporcionar un usuario válido, con una longitud de caracteres valida de acuerdo con la configurada y tiene que ser de tipo numérico el dato de entrada.

10014

Folio único de la transacción no proporcionado

Ingresar el dato de folio único.

10015

Folio único de la transacción no proporcionado

Ingresar el dato de folio único.

10016

Medio seleccionado no soporta periféricos y/o propina

Se debe seleccionar un medio de pago distinto que soporte el tipo de venta con los datos correspondientes o revisar la configuración de los medios de pago.

10017

Periféricos requeridos

Se debe ingresar el dato de periféricos.

10018

Los datos de entrada de periférico son incorrectos

Ingresar un formato valido de datos de periférico.

10019

El monto de la transacción es requerido para poder agregar propina

Agregar un monto de la transacción al momento de realizar la venta.

10020

Propina no permitida para esta aplicación

Seleccionar un medio de pago distinto o revisar la configuración de los medios de pago.

10021

Monto propina supera el máximo permitido

Ingresar un monto menor o revisar la configuración de propina máxima.

10022

La cantidad de litros es inválida

Ingresar un monto menor de cantidad de litros.

10023

El precio por litro es inválido

Ingresar un monto menor de cantidad de litros.

10024

Los periféricos son inválidos

Longitud incorrecta de periféricos.

10025

El tipo de combustible es inválido

Ingresar un nombre de un combustible sin caracteres especiales ni números.

10026

Los datos de entrada son inválidos

Ingresar una venta con montos mayores a 0 en los campos de monto, propina y precio de periférico.

10027

Medios de pago disponibles no admiten periféricos y/o propina

Cambiar la configuración de los medios de pago o seleccionar un medio de pago que admita las características requeridas.

10028

Nombre de usuario inválido

Ingresar un dato que solo contenga números y letras, sin caracteres especiales a o acentos, además de verificar que el campo no exceda la longitud máxima.

10029

El monto ingresado no es correcto

Verificar el monto ingresado, resultado de la multiplicación de precio por litro de combustible y cantidad de combustible.

10030

La cantidad de meses a diferir el pago es invalida

Ingresar una cantidad correcta, superior a 1, pero inferior a 99 de meses.

10031

La cantidad de meses para comenzar a pagar es invalida

Ingresar una cantidad correcta, superior a 1, pero inferior a 99 de meses.

10032

El Json de configuración de medios de pago tiene formato incorrecto

Ingresar un Json correcto, con las comillas dobles escapadas ” y con los parámetros bien escritos.  

20001

Para continuar recargue la batería de su terminal

La terminal deberá de tener mínimo una carga de batería del 17% para transaccionar.

20003

Referencia inexistente

Se debe ingresar una referencia valida.

20004

La impresora no tiene papel. Recargue por favor para continuar

Se debe reemplazar el insumo del papel térmico por uno nuevo.

20005

Falló en inicialización de la terminal

Ingresar un api key, identificador de comercio, identificador de integrador, folios válidos, además verificar si la terminal se encuentra con la configuración correcta de descarga de parámetros en el sistema.

20006

Error de red, verifique su conexión

Revisar el correcto funcionamiento de la red de internet o datos móviles, en caso contrario buscar una alternativa de conexión a internet.

20007

Falló la autenticación

Ingresar un api key, identificador de comercio, identificador de integrador, folios válidos, además verificar si la terminal se encuentra con la configuración correcta de autenticación en el sistema.

20008

Pago con Monedero requerido

Utilizar la aplicación de fleetcards para realizar el pago o seleccionar un medio de pago diferente que admita las características del pago a realizar.

20009

Operación no válida en este dispositivo

Habilitar la opción de devolución y verificar la configuración correcta en la descarga de parámetros de la terminal.

Manejo de errores

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Clase destino

Descripción

ContainerActivity

Realiza una consulta de las transacciones realizadas en la terminal.

Parámetro

Tipo

Petición

Ejemplo

Operation

String

M

BALANCE

from

String

M

N/A

print_report

String

M

“false”

Para el parámetro print_report, si se envía como “true” se permitirá la impresión de transacciones y reportes desde la aplicación “financiera”, si se envía como “false”, no se permitirá la impresión de reportes y en cuanto a las transacciones, nuestra aplicación devolverá un json con los datos de la transacción (“TX_JSON_RETURN”) en lugar de imprimir el pagaré fisico. Esto cuando se dé al botón de imprimir transacciones como se ve en la siguiente imagen:

Parámetro

Tipo

Petición

Ejemplo

TX_JSON_RETURN

String

Campos ISO{“Nombre”:”valor”}

TX_ERROR

String

Código de error 10005

Cuando se salga de la app financiera, usando el botón de back, se regresará un mensaje de error (“TX_ERROR”) con el código 10005. Véase la sección de códigos de error.

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
 
class ReportActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        doCallBalance(
            print = true
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun doCallBalance(print: Boolean) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            CoroutineScope(Dispatchers.IO).launch {
                val intent = Intent()
                intent.setClassName(SMART_PACKAGE.plus(suffix), "${SMART_PACKAGE}.activities.ContainerActivity")
                intent.putExtra("operation", OPERATION_BALANCE)
                intent.putExtra("from", resources.getString(R.string.app_name))
                intent.putExtra("print_report", print.toString())
                startActivityForResult.launch(intent)
            }
        } else {
            Toast.makeText(
                this,
                resources.getString(R.string.message_error_dont_exists_financial),
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
}

				
			

El putExtra operation recibe el valor de “BALANCE”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando el reporte de transacciones
  • Una vez seleccionada una transacción se retornará un JSON de respuesta con la información detallada de la transacción.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Clase destino

Descripción

ContainerActivity

Realiza una reimpresión de ticket con la referencia de plataforma SG_REFERENCE de la transacción.

Parámetro

Tipo

Petición

Ejemplo

Operation

String

M

“REPRINT”

Reference

String

M

“123456789012”

No aplica campo de respuesta

Ejemplo de llamado
				
					package com.smart.thirdpartysample
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.gson.GsonBuilder
 
class ExampleActivity : AppCompatActivity() {
 
    private lateinit var startActivityForResult: ActivityResultLauncher<Intent>
 
    private val SMART_PACKAGE = "com.smart.smart"
    private val DEBUG_SUFFIX = ".debug"
    private val QA_SUFFIX = ".qa"
    private val suffix = QA_SUFFIX + DEBUG_SUFFIX
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        setupCallbackForResult()
        callSmartComponent(
            amount = "",
            operation = "REPRINT",
            tip = "",
            print = false,
            cancel = false,
            reference = "12345",
            date = "",
            uniqueReference = "",
            idCommerce = "",
            userNumber = "",
            userName = "",
            typeFuel = "",
            liters = "",
            pricePerLiters = "",
            periphericals = "",
            paymentMethod = "",
            promotionPay = "",
            promotionSkip = "",
            monthsToPay = "",
            monthsToStartPaying = ""
        )
    }
 
    private fun setupCallbackForResult() {
        startActivityForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val bundle = result.data
                    if (bundle!!.getBooleanExtra("TX_STATUS", false)) {
                        if (bundle.getStringExtra("TX_JSON_RETURN") == null) {
                            finish()
                        } else {
                            Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                        }
                    } else {
                        Log.d("TAG1", bundle.getStringExtra("TX_JSON_RETURN") ?: EMPTY_VALUE)
                    }
                }
            }
    }
 
    private fun callSmartComponent(
        amount: String,
        operation: String,
        tip: String,
        print: Boolean,
        cancel: Boolean,
        reference: String,
        date: String,
        uniqueReference: String,
        idCommerce: String,
        userNumber: String,
        userName: String,
        typeFuel: String,
        liters: String,
        pricePerLiters: String,
        periphericals: String,
        paymentMethod: String,
        promotionPay: String,
        promotionSkip: String,
        monthsToPay: String,
        monthsToStartPaying: String,
    ) {
        if (appInstalledOrNot(SMART_PACKAGE.plus(suffix), this)) {
            val intent = Intent()
            intent.setClassName(SMART_PACKAGE.plus(suffix), "$SMART_PACKAGE.activities.ContainerActivity")
            intent.putExtra("amount", amount)
            intent.putExtra("operation", operation)
            intent.putExtra("cancel", cancel)
            intent.putExtra("reference", reference)
            intent.putExtra("unique_reference", uniqueReference)
            intent.putExtra("tip", tip)
            intent.putExtra("from", this.resources.getString(R.string.app_name))
            intent.putExtra("json", createJson(print))
            intent.putExtra("date", date)
            intent.putExtra("idCommerce", idCommerce)
            intent.putExtra("userNumber", userNumber)
            intent.putExtra("userName", userName)
            intent.putExtra("fuelType", typeFuel)
            intent.putExtra("liters", liters)
            intent.putExtra("pricePerLiters", pricePerLiters)
            intent.putExtra("periphericals", periphericals)
            intent.putExtra("paymentMethod", paymentMethod)
            intent.putExtra("promotionPay", promotionPay)
            intent.putExtra("promotionSkip", promotionSkip)
            intent.putExtra("monthsToPay", monthsToPay)
            intent.putExtra("monthsToStartPaying", monthsToStartPaying)
            startActivityForResult.launch(intent)
        } else {
            Toast.makeText(
                this,
                "Es necesario installar la aplicación financiera para operar",
                Toast.LENGTH_LONG,
            ).show()
        }
    }
 
    private fun appInstalledOrNot(uri: String, context: Context): Boolean {
        val pm: PackageManager = context.packageManager
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            return true
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return false
    }
 
 
    private fun createJson(print: Boolean): String {
        val jsonData = JsonData()
        jsonData.activityStr = "${this.packageName}.DetailActivity"
        jsonData.packageStr = this.packageName
        jsonData.print = print
        return getJsonString(jsonData) ?: EMPTY_VALUE
    }
 
    private fun getJsonString(json: JsonData): String? {
        val gson = GsonBuilder()
            .create()
        return gson.toJson(json)
    }
 
    class JsonData {
        var packageStr: String? = null
        var activityStr: String? = null
        var print: Boolean? = null
    }
 
}

				
			

El putExtra operation recibe el valor de “QUERY_UNIQUE”.

Ejemplo en la terminal
  • Al lanzar el llamado del Intent se visualizará la siguiente pantalla en la aplicación SmartWrapper Financiera mostrando la reimpresión de la transacción por referencia SG_REFERENCE.
  • Una vez finalizada la reimpresión de la transacción se retornará un JSON de respuesta con el estatus de la transacción.
Implementación de funciones de pago:

Se incluirán ejemplos de código y casos de uso para ilustrar cómo utilizar las funciones del SDK para procesar transacciones de pago dentro de la aplicación. Esto incluirá la creación de transacciones, la gestión de carritos de compras, la captura de datos de tarjetas y la integración con métodos de pago específicos.

Inicialización del SDK en la aplicación
Mejores prácticas de seguridad en la integración del SDK

Se describirán las mejores prácticas de seguridad para garantizar la protección de datos sensibles durante la integración del SDK y el procesamiento de transacciones de pago.

Manejo seguro de datos sensibles

Se proporcionarán pautas y recomendaciones para el manejo seguro de datos sensibles, como números de tarjetas de crédito y datos de autenticación, dentro de la aplicación.

Cumplimiento de estándares de seguridad PCI-DSS:

Se explicará cómo cumplir con los requisitos de seguridad establecidos por el estándar de seguridad de datos de la industria de tarjetas de pago (PCI-DSS) al utilizar el SDK de procesamiento de pagos.

Resolución de Problemas
Identificación y diagnóstico de problemas comunes:

Se enumerarán problemas comunes que pueden surgir durante la integración del SDK y se proporcionarán soluciones o sugerencias para resolverlos de manera efectiva.

Recursos de soporte y documentación adicional:

 Se proporcionarán enlaces a recursos de soporte adicionales, como documentación técnica, foros de ayuda y servicio de atención al cliente, para ayudar a los desarrolladores en la resolución de problemas.

Ejemplos y Casos de Uso
Ejemplos de código para diferentes escenarios de pago:

Se incluirán fragmentos de código de ejemplo que ilustren cómo utilizar las funciones del SDK en diferentes situaciones de pago, como pagos únicos, pagos recurrentes y pagos con métodos de pago específicos.

Casos de uso específicos y soluciones implementadas:

Se presentarán casos de uso reales donde se haya implementado el SDK de procesamiento de pagos con éxito en aplicaciones Android para terminales punto de venta. Estos casos de uso proporcionarán información detallada sobre los desafíos enfrentados y las soluciones implementadas por los desarrolladores.

Actualizaciones y Mantenimiento
Procedimientos para la actualización del SDK:

Se explicará cómo los desarrolladores pueden mantener actualizado el SDK con las últimas versiones y parches de seguridad proporcionados por el proveedor. Esto puede incluir instrucciones para actualizar las dependencias en el archivo de configuración del proyecto y comprobar regularmente las actualizaciones disponibles.

Políticas de mantenimiento y soporte a largo plazo:

Se proporcionará información sobre las políticas de mantenimiento y soporte técnico continuo ofrecido por el proveedor del SDK. Esto puede incluir detalles sobre la disponibilidad de actualizaciones de seguridad, resolución de problemas y contacto con el soporte técnico.

Referencias
Enlaces a la documentación oficial del SDK:

Se proporcionarán enlaces a la documentación oficial del SDK de procesamiento de pagos, donde los desarrolladores pueden encontrar información detallada sobre todas las funciones, métodos y parámetros disponibles.

Recursos adicionales para desarrolladores:

Se listarán recursos adicionales útiles, como tutoriales en línea, blogs técnicos, comunidades de desarrolladores y eventos de capacitación, que pueden ayudar a los desarrolladores a aprender más sobre la integración y el uso efectivo del SDK de procesamiento de pagos.

MDM
¿Logramos resolver tu duda?

Preguntas frecuentes

Ventas

  • ¿Cómo genero una venta?

    Unfortunately, it’s not possible to make any changes to an order or cancel it once it has been placed. However, you could ask for a refund.

  • ¿Puedo cobrar con múltiples métodos de pago?

    You will receive an email from us after you have placed the order. You’ll get confirmation in your email when you purchase and we’ll let you know when your order is on the move. You will be able to track your order through your preferred shipping partner.

  • ¿Cuáles son los métodos de pago admitidos?

    We accept all the popular payment methods such as PayPal, Visa, MasterCard, Discover, Amazon Pay, American Express and Google Pay.

Check In / Check Out

  • ¿Puedo modificar el monto del Check In?

    Yes, we ship all over the world. Please note that additional shipping costs will be applied based on your delivery location.

  • ¿Puedo cancelar un Check in?

    Yes, free shipping is available for all the orders that’s placed inside the United States. We charge shipping fees for overseas orders.

  • ¿Cuánto tiempo tarda en reembolsarse el monto de un Check In cancelado?

    We usually take 3-5 business days for your order to be shipped & delivered.

Devoluciones

  • ¿Puedo realizar una devolución parcial?

    Once we receive your return, please allow us 3-5 business days for your refund to process. Refund amount will be automatically debited to the same form of payment originally used for purchase.

  • Si ya realice una devolución parcial, ¿puedo realizar otra devolución sobre la misma transacción?

    To track the status of your refund, kindly refer to your confirmation email that you have received from us.

  • ¿Cuánto tiempo después de realizar la transacción puedo realizar una devolución?

    You can ask for a refund within 30 days of your purchase. Returned items must be in the exact same condition as they were received.

  1. La aplicación cliente manda a llamar la operación de autenticación de la aplicación financiera SmartWrapper mediante un Intent de autenticación.
  2. La aplicación financiera SmartWrapper recibe el llamado, recopila el el api key ,id integrador(no debe ser mas de 40 posiciones) el id commerce  y el folio de la terminal Urovo y realiza un llamado de autenticación hacia el core smart.
  3. La plataforma de Smart valida los datos enviados recibido por la aplicación SmartWrapper, y procede a realizar los procesos internos de autenticación de la terminal.
  4. La aplicación SmartWrapper recibe el resultado de la autenticación de la plataforma Smart, procesa el resultado y lo retorna a la aplicación de terceros.