mSDK
En esta sección se detallan las principales consideraciones y archivos
principales para la implementación en lenguajes Flutter, iOS (Swift) y Android,
como parte de esta documentación recibirá aplicaciones básicas de ejemplo en
estos lenguajes.
Es importante recalcar que la selección del lenguaje, SDK, arquitectura, flujos
a implementar dependerán de las necesidades, flujos, experiencia, prácticas y
políticas de cada empresa.
Implementación en Flutter
Versión de Flutter: 3.0.5
Tipo de proyecto: Flutter Aplication
Dependencias (pubspec.yaml):
- get_ip: 0.4.0 : Usada para la obtención de la ip del dispositivo,
puede usarse otra a conveniencia
- http: ^0.12.2 : Requerida para el consumo del apiServer
Archivos: En este DEMO encontrará clases dart como
HomeScreen.dart,
IntroScreen.dart, TokenizeScreen.dart, entre otros, usados para realizar
la interfaz de este demo, sin embargo, los archivos que debe revisar
para su implementación son:
- Utils/DataWeb.dart: Esta es la clase principal de la integración,
creará y consumirá el canal creado entre Flutter y el intérprete
Android/iOS, disponibiliza las funciones:
- getCheckOutId: Recibe un objeto de tipo DWCheckOutReq y
consume el apiServer expuesto para generación de checkoutId,
retornará un objeto de tipo DWCheckOutRsp.
- ProcessPayment: Recibe el checkoutId y el tipo de pago,
consume el canal con la plataforma correspondiente y finalmente
obtiene el estado de la transacción mediante el apiServer
respondiendo un objeto de tipo DWStatusRsp, tambien es
responsable de la parametrización del widget, los parámetros
expuestos son:
- Config_Ambiente: Ambiente al cual se conectará el widget
(TEST, LIVE)
- Config_Brands: Marcas de tarjeta que soportará el widget,
separados por coma (,), por ejemplo:
VISA,MASTER,AMEX,DINERS,DISCOVER
- Config_MostrarTotal: Flag que indica si el plugin
mostrará el valor total de la transacción (true/false)
- Config_SkipCVV: Flag que indica si las tarjetas
tokenizadas requerirán o no del ingreso de CVV.
- Config_Tokenize: Indica si se debe mostrar la opción de
tokenización de tarjeta (0: Nunca, 1 Mostrar, 2. Siempre
Tokenizar - no recomendado)
- Pago_Diferidos: Instancia los meses diferidos a mostrar,
separados con coma (,), por ejemplo: 3,6,9
- Estilo_Tema: Indica el tema a aplicar al plugin
(Dark/Light)
- Estilo_Idioma: Indica el idioma a aplicar al plugin
(es_ES, en_US)
- Config_TipoPayment: Indica el tipo de crédito
seleccionado
Estas configuraciones se deberán crear en un mapa de strings
para su posterior envío a la plataforma, ejemplo:
Map payParams = new HashMap();
payParams['Config_Ambiente'] = "TEST";
payParams['Config_Brands'] = "VISA,MASTER,AMEX,DINERS,DISCOVER";
payParams['Config_MostrarTotal'] = "true";
payParams['Config_SkipCVV'] = "true";
payParams['Config_Tokenize'] = "1";
payParams['Pago_Diferidos'] = "3,6,9";
payParams['Estilo_Tema'] = "Dark";
payParams['Estilo_Idioma'] = "es_ES";
payParams['Config_TipoPayment'] = "0";
- TokenCheckOutId: Consume el apiServer expuesto para
generación de checkoutId para token, retornará un objeto de tipo
DWCheckOutRsp.
- TokenProcessPayment: Procesa un cobro basado en un token
previamente generado
- TokenDeleteCard: Procesa la eliminación de un token
previamente generado
Podrá cambiar el nombre/funcionalidad/características de estas
funciones conforme considere necesario.
src/models/*:
En esta ruta contiene los modelos (objetos) de tipo clase a usar como objetos de Requerimiento y Respuesta, como: DWCheckOutReq, DWCheckOutRsp, DWStatusReq, DWTokenCheckOutReq, DWTokenCardRsp, DWDeleteCard, DWStatusRsp, DWStatusFlutter
Cabe recalcar que estos objetos podrán ser modificados, cambiando los
nombres de sus elementos, o agregando campos para cumplir con las
necesidades del negocio.
src/models/colors_ios.dart:
Contiene los objetos modificables de diseño (colores) del plugin en iOS (para Android es necesario editar el archivo xml de colores), es muy importante que se respeten los nombres de las variables pues son identificadores.
Un ejemplo de consumo de estos componentes desde la aplicación en flutter (al presionar Pagar) se puede ver en el widget ShoesDetail, donde se invoca la función openPaymentGateway (La función de tokenización openPaymentGatewayTokenize funciona de similar forma), que ejecuta principalmente lo siguiente:
Future openPaymentGateway() async {
DWCheckOutReq req = new DWCheckOutReq();
req.ClienteDocId = "";
req.ClientePNombre = myControllerName.text;
req.ClientePApellido = myControllerApellido.text;
req.ClienteEmail = myControllerEmail.text;
req.ClienteIP = await GetIp.ipAddress;
req.EnvioDireccion = myControllerEnvio.text;
req.Valor_Base0 = TotalBase0;
req.Valor_BaseImp = TotalBaseImp;
req.Valor_IVA = TotalIVA;
req.Valor_Total = Total;
if (tpayment == 0) {
req.Credito_Tipo = 0;
req.Credito_Meses = 0;
} else {
req.Credito_Tipo = tpayment;
}
DWCheckOutRsp rsp = await DataWeb.getCheckOutId(req);
DWStatusRsp status = await DataWeb.ProcessPayment(rsp.checkoutId, tpayment);
String MensajePopUp = "idTrx: " + (status.ResultId ? ? "") +
"\n\nResultCode: " + (status.ResultCode ? ? "") +
"\n\nResultDescription: " + (status.ResultDescription ? ? "") +
"\n\nDetailExtDesc: " + (status.DetailExtDesc ? ? "") +
"\n\nDetailAuth:" + (status.DetailAuth ? ? "--");
}
Donde se arma el objeto DWCheckOutReq para generación del checkoutId y
posterior consumo de ProcessPayment.
Configuración de Android:
Consideración: en caso de usarel callback asíncrono de OTT, se
debe
añadir la siguiente configuración en el archivo manifest esta
configuración debe estar en la actividad principal del proyecto:
<intent-filter>
<data android:scheme="dataweb"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
Cambiar el dataweb por el nombre de su proyecto, que fue colocado
en setShopperResultUrl.
En algunos casos los plugin de terceros devuelven un activity
result,
estos activity result serán ignorados al menos que se especifique lo
contrario, en caso de utilizarlos agregar la siguiente línea al inicio
del método onActivityResult del archivo MainActivity:
Nota: A partir de la versión 4 ya no es necesario agregar esta implementación
super.onActivityResult(requestCode, resultCode, data);
Ejemplo:
Remplazar los parámetros de acuerdo con su implementación.
Nota: Hacer el respectivo clean y get del proyecto.
Importar módulos: en las versiones actuales de Fultter o Android
se
debe agregar en la carpeta principal del proyecto Android app/libs los
archivos oppwa.mobile.aar, ipworks3ds_sdk.aar, oppwa.mobile.threeds.aar.
Agregar dependencias: En el build.gradle (Module App), agregar
las siguientes dependencias:
implementation fileTree(dir: "libs", include: ["*.aar"])
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "androidx.browser:browser:1.3.0"
implementation "com.google.android.material:material:1.4.0"
implementation "com.google.android.gms:play-services-base:17.6.0"
- Versión de compilación: De acuerdo a la versión de
flutter
utilizada en el build.gradle (Module App), agregar como versión
de compilación en el caso de flutter la versión de
compilación es 32.
- Actualizar la versión de Kotlin: En el archivo gradle
principal actualizar la versión de kotlin si se utiliza la
versión 10 de flutter:
buildscript {
ext.kotlin_version = '1.6.0'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.10'
}
}
Agregar las siguientes clases en archivo proguard-rules.pro:
-keep class com.oppwa.mobile.connect.threeds.OppThreeDSService { *; }
-keep class com.nsoftware.ipworks3ds.sdk.ThreeDS2Service { *; }
Agregar tools namespace en root de AndroidManifest.xml:
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
package="com.df.dataweb_flutter">
Agregar exported en la actividad principal del proyecto de
AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
Agregar exported en la actividad del checkout del proyecto, obligatorio apartir del sdk 32, ubicado en el archivo AndroidManifest.xml:
<activity
android:name="com.oppwa.mobile.connect.checkout.dialog.CheckoutActivity"
tools:replace="android:theme"
android:theme="@style/DFTheme"
android:windowSoftInputMode="adjustResize"
android:exported="false"
android:launchMode="singleTop"/>
Declarar servicio de conexión en AndroidManifest.xml: Dentro del
nodo application agregar:
<service
android:name="com.oppwa.mobile.connect.service.ConnectService"
android:exported="false"/>
Implementar bridge: Reemplazar el archivo MainActivity.java
encontrado
en Android/app/src/main/kotlin/com.* con el provisto en esta
documentación y que podrá encontrar en el demo. Considerar que, si
cambia el valor de la variable CHANNEL, deberá también cambiarlo en
flutter, dentro de la función ProcessPayment encontrará la lógica que
presenta el formulario de CheckOut para lo cual se requiere:
- Inicializar el objeto CheckoutSettings:
CheckoutSettings checkoutSettings = new CheckoutSettings(checkoutId, paymentBrands,
Connect.ProviderMode.TEST);
checkoutSettings.setShopperResultUrl("companyname://result");
Iniciar actividad
Nota: Deprecado a partir de la versión 4.x.x del msdk, su nueva implementación se la puede ver en la sección de migración (6.4.2) en el anexo “iniciar actividad”
Intent intent = checkoutSettings.createCheckoutActivityIntent(this);
startActivityForResult(intent, CheckoutActivity.REQUEST_CODE_CHECKOUT);
Cambiar colores: Dentro del archivo de estilos (res/values/styles
y colors) encontrará un tema default, donde podrá cambiar colores en
caso de así requerirlo.
Configuración de iOS:
pod install: Ejecutar un pod install en directorio raiz
Importar sdk: Arrastrar los archivos OPPWAMobile.framework,
OPPWAMobile-Resources.bundle, ipworks3ds_sdk.xcframework y
OPPWAMobile_ThreeDS.xcframework a la carpeta Frameworks (Asegúrese de
tener marcada la opción de copiar elementos de ser necesario)
Nota: usar OPPWAMobile_ThreeDS.xcframework solo para versiones 1.x.x o 2.x.x, para mayor detalle revisar la sección de migración (6.4.1)
Activar configuraciones de compilación: Asegurarse que las
siguientes opciones se encuentren activadas:
- Enable Modules (C and Objective-C)
- Link Frameworks Automatically
Para SWIFT:
- Cargar Archivos base: Copiar archivos Language.swift,
Constant.swift y ColorsCheckout.swift a carpeta Runner del
proyecto.
- Importar header OPPWA: Importar en archivo
Runner-Bridging-Header.h, quedando:
#import "GeneratedPluginRegistrant.h"
#import <OPPWAMobile/OPPWAMobile.h>
@import OPPWAMobile_ThreeDS
@import ipworks3ds_sdk
Implementar bridge: Reemplazar el archivo
AppDelegate.swift en
carpeta Runner del proyecto. Considerar que, si cambia el valor
de la variable CHANNEL, deberá también cambiarlo en flutter,
dentro de la función recivePayment encontrará la lógica que
presenta el formulario de CheckOut para lo cual se requiere:
- Inicializar el objeto CheckoutSettings:
let checkoutSettings = OPPCheckoutSettings()
checkoutSettings.paymentBrands = ["VISA", "DIRECTDEBIT_SEPA"]
checkoutSettings.shopperResultURL = "com.companyname.appname.payments://result"
Iniciar actividad
let checkoutProvider = OPPCheckoutProvider(paymentProvider: provider, checkoutID: checkoutID!, settings: checkoutSettings)
checkoutProvider?.presentCheckout(forSubmittingTransactionCompletionHandler: { (transaction, error) in
guard let transaction = transaction else {
// Handle invalid transaction, check error
return
}
if transaction.type == .synchronous {
// If a transaction is synchronous, just request the payment status
// You can use transaction.resourcePath or just checkout ID to do it
} else if transaction.type == .asynchronous {
// The SDK opens transaction.redirectUrl in a browser
// See 'Asynchronous Payments' guide for more details
} else {
// Executed in case of failure of the transaction for any reason
}
}, cancelHandler: {
// Executed if the shopper closes the payment page prematurely
})
Implementación en Android
Tipo de proyecto: Android Application
Archivos: En este DEMO encontrará clases java como usados para
realizar la
interfaz de este demo, sin embargo, los archivos que debe revisar para su
implementación son:
CheckoutSettings checkoutSettings = new CheckoutSettings(checkoutId, paymentBrands, Connect.ProviderMode.TEST);
checkoutSettings.setShopperResultUrl("companyname://result");
Iniciar actividad
Nota: Deprecado a partir de la versión 4.x.x del msdk, su nueva implementación se la puede ver en la sección de migración (6.4.2) en el anexo “iniciar actividad”
Intent intent = checkoutSettings.createCheckoutActivityIntent(this);
startActivityForResult(intent, CheckoutActivity.REQUEST_CODE_CHECKOUT);
Configuración:
Importar módulos: para importar módulos se debe crear una carpeta libs en la raíz principal del proyecto de Android, luego de ello agregar en la carpeta libs los archivos oppwa.mobile.aar, ipworks3ds_sdk.aar, oppwa.mobile.threeds.aar (Solo para versiones 1.x.x o 2.x.x), para mayor detalle revisar la sección de migración (6.4.2)).
Agregar dependencias: En el build.gradle (Module App), agregar
las siguientes dependencias.
implementation fileTree(dir: "libs", include: ["*.aar"])
implementation "androidx.appcompat:appcompat:1.3.1"
implementation "androidx.browser:browser:1.3.0"
implementation "com.google.android.material:material:1.4.0"
implementation "com.google.android.gms:play-services-base:17.6.0"
implementation 'com.android.support:multidex:2.0.1'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.pixplicity.easyprefs:library:1.9.0'
implementation 'com.vinaygaba:creditcardview:1.0.4'
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
Agregar las siguientes clases en archivo proguard-rules.pro:
-keep class com.oppwa.mobile.connect.threeds.OppThreeDSService { *; }
-keep class com.nsoftware.ipworks3ds.sdk.ThreeDS2Service { *; }
Declarar servicio de conexión en AndroidManifest.xml: Dentro del
nodo application agregar:
Nota: Ya no es necesario agregar el servicio a partir de la versión 4.x.x del msdk
<service
android:name="com.oppwa.mobile.connect.service.ConnectService"
android:exported="false"/>
Agregar exported en la actividad principal del proyecto de AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"/>
Agregar exported en la actividad del checkout del proyecto, obligatorio apartir del sdk 32, ubicado en el archivo AndroidManifest.xml
<activity
android:name="com.oppwa.mobile.connect.checkout.dialog.CheckoutActivity"
tools:replace="android:theme"
android:theme="@style/DFTheme"
android:windowSoftInputMode="adjustResize"
android:exported="true"
android:launchMode="singleTop"/>
Cambiar colores: Dentro del archivo de estilos (res/values/styles
y
colors) encontrará un tema default, donde podrá cambiar colores en caso
de así requerirlo
Pagos asíncronos (OTT)
Modificar el archivo AndroidManifest.xml
- En la actividad principal de la aplicación, agregar el
launchMode como singleTask y agregar un
intent-filter como se
especifica a continuación
<activity
android:name="YOUR_ACTIVITY"
android:launchMode="singleTask">
<intent-filter>
<data android:scheme="companyname"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
NOTA: Es importante que el launchMode tenga
asignado el valor de singleTask.
Agregar URL de pago
Tan pronto como se procesa el pago asíncrono, se abre la URL del
resultado del pago. Para aquello se debe configurarlo en la clase
CheckoutSettings.
Ejemplo de URL: companyname://result.
El esquema debe ser el mismo que has registrado en el paso anterior. El
resto de la URL puede ser cualquier cadena válida (pero no vacía).
(Deprecado a partir de la versión 4.x.x del msdk, su nueva implementación se la puede ver en la sección de migración (6.4.2) en el anexo “iniciar actividad”)
val checkoutSettings = CheckoutSettings(checkoutId, paymentBrands, providerMode)
checkoutSettings.setShopperResultUrl("companyname://result")
Realizar este paso antes de enviar la solicitud de pago, ya que al
hacerlo antes provocara un error de anulación.
Redireccionamiento (Opcional)
Si se desea realizar un redireccionamiento de destino debe anular el
método onNewIntent, este mismo escenario puede ayudar a manejar
transacciones abortadas.
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (intent.scheme == "companyname") {
/* request payment status */
}
}
Implementación en iOS
Tipo de proyecto: iOS Application
Archivos: En este DEMO encontrará clases swift usados para realizar
la
interfaz de este demo, sin embargo, los archivos que debe revisar para su
implementación son:
- Controller/HomeViewController: Esta es la clase principal de la
integración, consumirá el mSDK y presentará el formulario de pago con
las
variables configuradas, el ejemplo de consumo lo podrá encontrar en la
función displayForm donde se obtienen las variables y se inicializa y
presenta el mSDK, podrá encontrar las siguientes variables:
- Config_Ambiente: Ambiente al cual se conectará el widget
(TEST, LIVE)
- Config_Brands: Marcas de tarjeta que soportará el widget,
separados por coma (,), por ejemplo:
VISA,MASTER,AMEX,DINERS,DISCOVER
- Config_MostrarTotal: Flag que indica si el plugin
mostrará el
valor
total de la transacción (true/false)
- Config_SkipCVV: Flag que indica si las tarjetas
tokenizadas
requerirán o no del ingreso de CVV.
- Config_Tokenize: Indica si se debe mostrar la opción de
tokenización de tarjeta (0: Nunca, 1 Mostrar, 2. Siempre
Tokenizar –
no recomendado)
- Pago_Diferidos: Instancia los meses diferidos a mostrar,
separados con coma (,), por ejemplo: 3,6,9
- Estilo_Tema: Indica el tema a aplicar al plugin
(Dark/Light)
- Estilo_Idioma: Indica el idioma a aplicar al plugin
(es_ES,
en_US)
- Config_TipoPayment: Indica el tipo de crédito
seleccionado
Para presentar el formulario de CheckOut se requiere:
- Swift
- Inicializar el objeto CheckoutSettings:
let checkoutSettings = OPPCheckoutSettings()
checkoutSettings.paymentBrands = ["VISA", "DIRECTDEBIT_SEPA"]
checkoutSettings.shopperResultURL = "com.companyname.appname.payments://result"
- Iniciar actividad
let checkoutProvider = OPPCheckoutProvider(paymentProvider: provider, checkoutID: checkoutID!, settings: checkoutSettings)
checkoutProvider?.presentCheckout(forSubmittingTransactionCompletionHandler: { (transaction, error) in
guard let transaction = transaction else {
// Handle invalid transaction, check error
return
}
if transaction.type == .synchronous {
// If a transaction is synchronous, just request the payment status
// You can use transaction.resourcePath or just checkout ID to do it
} else if transaction.type == .asynchronous {
// The SDK opens transaction.redirectUrl in a browser
} else {
// Executed in case of failure of the transaction for any reason
}
}, cancelHandler: {
// Executed if the shopper closes the payment page prematurely
})
Objective-C
- Inicializar el objeto CheckoutSettings:
OPPCheckoutSettings *checkoutSettings = [[OPPCheckoutSettings alloc] init];
checkoutSettings.paymentBrands = @[@"VISA", @"DIRECTDEBIT_SEPA"];
checkoutSettings.shopperResultURL = @"com.companyname.appname.payments://result";
Iniciar actividad
OPPCheckoutProvider *checkoutProvider = [OPPCheckoutProvider checkoutProviderWithPaymentProvider:provider
checkoutID:checkoutID settings:checkoutSettings];
[checkoutProvider presentCheckoutForSubmittingTransactionCompletionHandler:^(OPPTransaction * _Nullable transaction, NSError * _Nullable error) {
if (error) {
// Executed in case of failure of the transaction for any reason
} else if (transaction.type == OPPTransactionTypeSynchronous) {
// Send request to your server to obtain the status of the synchronous transaction
// You can use transaction.resourcePath or just checkout id to do it
} else {
// The SDK opens transaction.redirectUrl in a browser
}
} cancelHandler:^{
// Executed if the shopper closes the payment page prematurely
}];
Configuración:
Importar sdk: Arrastrar los archivos OPPWAMobile.framework,
OPPWAMobile-Resources.bundle, ipworks3ds_sdk.xcframework y
OPPWAMobile_ThreeDS.xcframework a la carpeta Frameworks (Asegúrese de
tener marcada la opción de copiar elementos de ser necesario)
- En la opción Build Phases sección Embed Framework:
Activar el
code sign de los tres sdk copiados en el paso anterior.
Activar configuraciones de compilación: Asegurarse que las
siguientes opciones se encuentren activadas:
- Enable Modules (C and Objective-C)
- Link Frameworks Automatically
Cargar Archivos base: Copiar archivos Language.swift,
Constant.swift y ColorsCheckout.swift a carpeta Runner del proyecto.
Importar header OPPWA: Importar en archivo *-Bridging-Header.h,
quedando:
#include <OPPWAMobile/OPPWAMobile.h>
@import OPPWAMobile_ThreeDS;
@import ipworks3ds_sdk;
Cambiar colores: Se podrán cambiar los colores de la actividad
desde el objeto OPPCheckoutSettings. Encontrará los posibles valores en
la sección de anexos.
let settings = OPPCheckoutSettings()
settings.theme.style = .light
settings.theme.confirmationButtonColor = UIColor.green
Pagos asíncronos (OTT)
Realizar estos pasos en el xcode.
- Registrar un nuevo custom scheme, para ello se debe dirigir a:
- App Target
- Info
- URL Types
El nombre deberá iniciar con el Bundle ID (identificador de la
aplicación), pudiendo quedar por ejemplo
“com.companyname.appname.payments” donde
“com.companyname.appname” es el
Bundle Id de la aplicación, suponiendo que el bundle id de su aplicación
es com.df.data ahora quedaría com.df.data.dataweb, donde
dataweb es el
nombre que se le asigna a la aplicación este mismo debe ser configurado
en el método shopperResultURL.
- Agregar el scheme en el whitelist del archivo Info.plist (Modificar con
URL definido previamente):
- Key: LSApplicationQueriesSchemes
- Value: com.companyname.appname.payments
<key>LSApplicationQueriesSchemes</key>
<array>
<string>com.companyname.appname.payments</string>
</array>
Agregar URL de pago
Tan pronto como se procesa el pago asíncrono, se abre la URL del resultado
del pago. Para aquello se debe configurarlo en la clase
CheckoutSettings.
Ejemplo de URL: com.companyname.appname.payments://result.
El esquema debe ser el mismo que has registrado en el paso anterior. El
resto de la URL puede ser cualquier cadena válida (pero no vacía).
let checkoutSettings = OPPCheckoutSettings()
checkoutSettings.shopperResultURL = "com.companyname.appname.payments://result"
Realizar este paso antes de enviar la solicitud de pago, ya que al hacerlo
antes provocara un error de anulación.
Manejar Solicitudes de URL
Manejar la devolución de llamada específica en AppDelegate o SceneDelegate
según el objetivo de implementación de su aplicació. Asegúrese de que el
esquema de URL sea idéntico al registrado en el paso anterior
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
if url.scheme?.caseInsensitiveCompare("com.companyname.appname.payments") == .orderedSame {
checkoutProvider.dismissCheckout(animated: true) {
// request payment status
}
return true
}
return false
}
Si se utiliza las ultimas versiones de iOS de 13 para se debe agregar el
esquema en la clase scene:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
guard let url = URLContexts.first?.url else {
return
}
if (url.scheme?.caseInsensitiveCompare("com.companyname.appname.payments") == .orderedSame) {
checkoutProvider.dismissCheckout(animated: true) {
// request payment status
}
}
}
Nota Importante: usted es el responsable de cerrar el pago, llamando
al
método dismissCheckoutAnimated de OPPCheckoutProvider. Si no tiene acceso a
la instancia de OPPCheckoutProvider desde el delegado de la aplicación,
puede usar notificaciones de difusión para manejar el resultado en el
controlador de vista, por ejemplo, usar un observable como el
NotificationCenter.
Ejemplo:
- Definir el observable solo cuando el pago sea asíncrono:
if transaction.type == .asynchronous {
NotificationCenter.default.addObserver(self, selector: #selector(self.didReceiveAsynchronousPaymentCallback), name: Notification.Name(rawValue: "AsyncPaymentCompletedNotificationKey"), object: nil)
}
Llamar al método didReceiveAsynchronousPaymentCallback en la solicitudes
de url.
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
if url.scheme?.caseInsensitiveCompare("com.companyname.appname.payments ") == .orderedSame
{
didReceiveAsynchronousPaymentCallback(result: self.chResult!)
return true
}
return false
}
@objc func didReceiveAsynchronousPaymentCallback(result: @escaping FlutterResult) {
NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: "AsyncPaymentCompletedNotificationKey"), object: nil)
self.checkoutProvider?.dismissCheckout(animated: true) {
DispatchQueue.main.async {
// request payment status
}
}
}
Migración msDK 4.X.X
En esta sección se detallara las principales consideraciones
que se debe realizar para actualizar la versión msDK de la versión 3.x.x a la versión 4.x.x
Implementación en iOS
Libreria Obsoleta
La libreria OPPWAMobile_ThreeDS.xcframework
está obsoleta ahora; toda la funcionalidad 3DS está integrada en OPPWAMobile.xcframework.
Así que antes de seguir realiza los siguientes pasos:
-
Eliminar OPPWAMobile_ThreeDS.xcframework de su proyecto.
-
Revise la configuración de su proyecto: pestañas General y Fases de compilación para eliminar los envoltorios de ThreeDS.
Importar biblioteca obligatoria
Como 3DS SDK ahora es parte de Mobile SDK, debe importar el siguiente marco al proyecto:
ipworks3ds_sdk.xcframework // certified 3DS SDK
Nota: Hay dos versiones del ipworks3ds_sdk.xcframework incluido:
una para ser usada para desarrollo y otra para producción. La versión de producción
incluye medidas de seguridad más estrictas que no permitirían que ocurran procesos
de desarrollo comunes, incluida la ejecución con depuradores o el uso de simuladores/emuladores.
La versión de implementación (producción) incluye _deploy en el nombre de archivo.
Pasos por realizar:
- Arrastre y suelte ipworks3ds_sdk.xcframework en la carpeta "Frameworks" de
su proyecto. Asegúrate de que esté marcada la opción "Copiar elementos si es necesario".
-
Incrustar los marcos (Embed the frameworks)
-
Vaya a la página de configuración general de su proyecto.
-
Agregue el objetivo de marcos a la sección Frameworks, Libraries, and Embedded Content haciendo clic en el icono Agregar.
-
Verificar que el ipworks3ds_sdk.xcframework este agregado en "Link Binary With Libraries"
Implementación en Android
Libreria Obsoleta
La libreria oppwa.mobile.threeds.aar está obsoleta ahora; toda la funcionalidad 3DS está integrada en oppwa.mobile.aar.
Importar biblioteca obligatoria
Como 3DS SDK ahora es parte de Mobile SDK, debe importar el siguiente marco al proyecto:
ipworks3ds_sdk.aar // certified 3DS SDK
Arrastre y suelte ipworks3ds_sdk.aar (utilice ipworks3ds_sdk_deploy.aar para producción)
en la carpeta "libs" del módulo donde planea integrar Mobile SDK.
Nota: Hay dos versiones del ipworks3ds_sdk.aar incluido:
una para ser usada para desarrollo y otra para producción. La versión de producción
incluye medidas de seguridad más estrictas que no permitirían que ocurran procesos de desarrollo comunes,
incluida la ejecución con depuradores o el uso de simuladores/emuladores. La versión de implementación (producción) incluye _deploy
en el nombre de archivo.
Iniciar Actividad
A partir de la versión 4, la forma clásica de inicializar la actividad quedo deprecada, por tal motivo se recomienda realizar los siguientes pasos para su migración:
private final ActivityResultLauncher checkoutLauncher = registerForActivityResult(
new CheckoutActivityResultContract(),
this::handleCheckoutResult);
private void handleCheckoutResult(@NonNull CheckoutActivityResult result) {
if (result.isCanceled()) {
// shopper cancelled the checkout process
//agregar tu proceso personalizado
return;
}
if (result.isErrored()) {
// error occurred during the checkout process
PaymentError error = result.getPaymentError();
Log.d("error", "Code Error: " + error.getErrorCode());
_result.error("ERR", error.getErrorMessage(), null);
// Log.d("error", error.getErrorMessage());
// Log.d("error", error.getErrorInfo());
return;
}
Transaction transaction = result.getTransaction();
String resourcePath = result.getResourcePath();
if (transaction != null) {
if (transaction.getTransactionType() == TransactionType.SYNC) {
// request payment status
} else {
// wait for the asynchronous transaction callback in the onNewIntent()
}
}
}
Con esto ya estas casi listo, ahora solo debes llamar al ActivityResultLauncher, creado anteriormente de la siguiente forma:
checkoutLauncher.launch(checkoutSettings);
Al realizar esta migración se recomienda agregar en el gradle lo siguiente:uncher, creado anteriormente de la siguiente forma:
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.3"
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.appcompat:appcompat:1.4.2"
implementation "androidx.webkit:webkit:1.4.0"
implementation "com.google.code.gson:gson:2.8.9"
implementation "androidx.browser:browser:1.4.0"
implementation "com.google.android.material:material:1.6.1"
implementation "androidx.fragment:fragment-ktx:1.4.1"
implementation "com.google.android.gms:play-services-wallet:19.1.0"
implementation "androidx.databinding:viewbinding:7.4.2"
Pagos 3DS
Para pagos con 3DS, algunas tarjetas solicitan un provider adicional para su correcto funcionamiento, para ello se debe agregar en el manifest lo siguiente:
<activity
android:name="com.oppwa.mobile.connect.provider.AsyncPaymentActivity"
tools:replace="android:theme"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize"
android:exported="false"
android:launchMode="singleTop"/>