SDK de iOS
Instale el SDK de iOS de DEUNA e integre los flujos de pago modal, embebido, con billetera, con vales y de "siguiente acción".
En esta página
- Requisitos
- Instalación
- Inicialización
- Abrir widget de pago
- Experiencias disponibles
- Incorporar un widget con SwiftUI
- Filtrar y configurar métodos de pago
- Estilo dinámico y actualización del pedido
- Almacén de pagos y Pago con un clic
- Apple Pay nativo
- Continúe con una acción pendiente
- Abrir un cupón
- Datos del dispositivo y huella digital para fraude
- Referencia del ciclo de vida y llamadas de retorno
- Ejemplos y código fuente oficiales
Requisitos#
Revise los requisitos para integrar el SDK de iOS de DEUNA:
- Versión de Swift: 5.8 o superior
- Versión de Xcode: 16.0 o superior
- Objetivo de despliegue: iOS 13.0 o superior para experiencias modales principales; iOS 14.0 o superior para SwiftUI incrustado
DeunaWidget - e: Cuenta activa y credenciales válidas (contacte a support@deuna.com si experimenta demoras para obtener credenciales)
Instalación#
Existen dos métodos compatibles para instalar el SDK de iOS de DEUNA:
Swift Package Manager (Recomendado)
- En Xcode, navega a Archivo → Agregar Dependencias de Paquete...
- En la barra de búsqueda, ingresa la URL del repositorio:
Plain text
https://github.com/deuna-developers/deuna-sdk-ios - Fija la regla de dependencia del paquete a la versión
2.12.6(o superior). - Cuando aparezca el diálogo Elegir Productos del Paquete :
- Seleccione
DeunaSDKy vincúlalo a tu objetivo de aplicación. - Establece todos los demás productos (
DeunaSDKCybersource,DeunaSDKKount,DeunaSDKRiskified,DeunaSDKSift,DeunaSDKSignifyd,DeunaSDKMercadoPago,DeunaSDKAccertify) en Ninguno a menos que tu integración use ese proveedor antifraude específico.
- Seleccione
CacaoPods
Si tu proyecto de iOS usa CocoaPods:
- Especifica el objetivo de implementación mínimo y agrega
DeunaSDKa tuPodfile:
platform :ios, '14.0'
target 'YourApp' do
use_frameworks!
pod 'DeunaSDK', '~> 2.12.6'
# Add ONLY the optional fraud provider subspecs you need:
# pod 'DeunaSDK/MercadoPago'
# pod 'DeunaSDK/Riskified'
# pod 'DeunaSDK/Cybersource'
# pod 'DeunaSDK/Signifyd'
# pod 'DeunaSDK/Kount'
# pod 'DeunaSDK/Sift'
# pod 'DeunaSDK/Accertify'
end- Ejecuta:
pod install- Deshabilitar el Sandbox de Scripts de Usuario: En Xcode, navega a la sección Configuración de Compilaciónde tu objetivo, busca
User Script Sandboxing(ENABLE_USER_SCRIPT_SANDBOXING) y establécelo en No.
Permisos Requeridos para Descargas de Vouchers
Inicialización#
import DeunaSDKPuede inicializar el SDK de dos maneras según la arquitectura de su aplicación:
Instancia global compartida
Inicializa una vez durante el inicio de la aplicación (por ejemplo, en tu inicializador AppDelegate o App ) y accede en cualquier lugar mediante DeunaSDK.shared:
DeunaSDK.initialize(
environment: .sandbox, // .sandbox or .production
publicApiKey: "YOUR_PUBLIC_API_KEY"
)
let deunaSDK = DeunaSDK.sharedInstancia de coordinador o pantalla
Crea y retén una instancia para una pantalla o coordinador específico:
let deunaSDK = DeunaSDK(
environment: .sandbox,
publicApiKey: "YOUR_PUBLIC_API_KEY"
)Abrir widget de pago#
El Widget de Pago ofrece múltiples métodos de pago a los clientes:
- Tarjetas de crédito y débito: Visa, Mastercard, American Express y tarjetas co-branded.
- Métodos de pago alternativos (APMs): OXXO, KueskiPay, Aplazo, Daviplata, Nequi y más.
- Carteras digitales: Apple Pay y PayPal.
Muestra en un modal
llamar initPaymentWidget en tu instancia de DeunaSDK :
deunaSDK.initPaymentWidget(
orderToken: "YOUR_ORDER_TOKEN",
callbacks: PaymentWidgetCallbacks(
onSuccess: { order in
deunaSDK.close() // Close the payment widget modal
// YOUR CODE HERE: Handle successful payment (e.g. navigate to confirmation screen)
},
onError: { error in
// Error handling
if error.type == .initializationFailed {
deunaSDK.close() // Close the widget if initialization fails
// YOUR CODE HERE: Handle initialization failure (e.g. show alert or fallback)
return
}
if error.type == .paymentError {
// YOUR CODE HERE: Handle payment processing failure (e.g. prompt user to retry)
}
},
onClosed: { action in
// Widget closed
// action == .userAction (dismissed manually by customer) or .systemAction (closed via code)
// YOUR CODE HERE: Handle modal dismissal
},
onCardBinDetected: { metadata in
guard metadata != nil else { return }
// YOUR CODE HERE: Handle card brand or BIN detection (e.g. apply discounts)
},
onInstallmentSelected: { installment in
// YOUR CODE HERE: Handle installment plan selection
},
onPaymentProcessing: {
// YOUR CODE HERE: Payment processing started (e.g. disable external buttons)
},
onEventDispatch: { event, payload in
// YOUR CODE HERE: Track analytics event
}
),
userToken: "YOUR_USER_TOKEN", // optional
styleFile: "YOUR_STYLE_FILE_UUID", // optional
language: "en" // optional: "es", "en", "pt"
)Referencia de parámetros
| Parámetro | Tipo | Modal | Integrado | Descripción |
|---|---|---|---|---|
orderToken | String | ✅ | ✅ | Requerido. Token único para la orden creada a través de la API de DEUNA. importante: No defina un redirect_url en la creación del pedido si desea que onSuccess se ejecute dentro de la aplicación. |
callbacks | PaymentWidgetCallbacks | ✅ | ✅ | Requerido. Callbacks que escuchan eventos del widget (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onEventDispatch). |
userToken | String? | ✅ | ✅ | Opcional. Token de portador (bearer) de DEUNA del cliente. importante: Para que aparezcan tarjetas guardadas, el correo electrónico vinculado al userToken deben coincidir con billing_address.email de la creación del pedido. |
styleFile | String? | ✅ | ✅ | Opcional. UUID proporcionado por DEUNA para aplicar personalización de marca de tema personalizado (colores, tipografía, logo). |
paymentMethods | [[String: Any]]? | ✅ | ✅ | Opcional. Array que define un único método de pago para el flujo de formularios directos (por ejemplo, [["paymentMethod": "bnpl", "processors": ["kueski"]]]). |
language | String? | ✅ | ✅ | Opcional. Código de idioma ("es", "en", "pt"). Anula la configuración predeterminada del comerciante. |
behavior | WidgetBehavior? | ✅ | ✅ | Opcional. Personalización del flujo, como WidgetBehavior(paymentMethods: ["flowType": "twoStep"]) para PayPal, o Pagos Divididos WidgetBehavior(paymentMethods: ["creditCard": ["splitPayments": ["maxCards": 2]]]). |
fraudCredentials | [String: Any]? | ✅ | ✅ | Opcional. Credenciales del proveedor de fraude (ej. ["RISKIFIED": ["storeDomain": "yourdomain.com"]]). |
domain | String? | ✅ | ✅ | Opcional. Anula el host base predeterminado (https://pay.deuna.io). |
hidePayButton | Bool | ❌ | ✅ | Opcional. Oculta el botón de pago integrado en modo embebido cuando su aplicación renderiza un botón nativo. |
Experiencias disponibles#
| Experiencia | Método | Tipo de configuración | Información necesaria |
|---|---|---|---|
| Widget de pago | initPaymentWidget(...) | PaymentWidgetConfiguration | orderToken, PaymentWidgetCallbacks |
| Caja de Pago | initElements(...) | ElementsWidgetConfiguration | ElementsCallbacks; types puede omitirse |
| Haga clic para pagar | initElements(...) | ElementsWidgetConfiguration | types: [["name": ElementsWidget.clickToPay]] |
| Siguiente Acción | initNextAction(...) | NextActionWidgetConfiguration | Token para la orden que requiere otra acción |
| vale | initVoucher(...) | VoucherWidgetConfiguration | Token para el pedido de vale |
Incorporar un widget con SwiftUI#
En iOS 14 o posterior, usa DeunaWidget para renderizar la experiencia de pago incrustada en tu jerarquía de SwiftUI.
import DeunaSDK
import SwiftUI
struct EmbeddedCheckoutScreen: View {
let deunaSDK: DeunaSDK
let orderToken: String
var body: some View {
VStack {
DeunaWidget(
deunaSDK: deunaSDK,
configuration: PaymentWidgetConfiguration(
orderToken: orderToken,
callbacks: PaymentWidgetCallbacks(
onSuccess: { order in
// Explicitly release widget resources to prevent memory leaks
deunaSDK.dispose()
// YOUR CODE HERE: Handle successful payment
},
onError: { error in
if error.type == .paymentError {
// YOUR CODE HERE: Handle payment error
}
},
onEventDispatch: { event, payload in
// YOUR CODE HERE: Track analytics event
}
),
userToken: nil,
styleFile: nil
)
)
}
}
}Incrustación con redimensionamiento automático y manejo de teclado
Por defecto, DeunaWidget llena su contenedor con una altura fija. Al pasar autoResizeConfig: AutoResizeConfig(initialHeight: 100), el widget cambia al modo de redimensionamiento automático: crece y se reduce dinámicamente para coincidir con la altura del contenido del WebView.
Cuando se incrusta dentro de un ScrollView, usa ScrollViewFinder para capturar el UIScrollView subyacente y conectar onScrollNeeded para que los campos enfocados se desplacen automáticamente por encima del teclado:
import DeunaSDK
import SwiftUI
import UIKit
struct MyCheckoutView: View {
let deunaSDK: DeunaSDK
let widgetConfig: DeunaWidgetConfiguration
@State private var outerScrollView: UIScrollView?
var body: some View {
ScrollView {
VStack(spacing: 0) {
// Invisible helper capturing the underlying UIScrollView
Color.clear.frame(height: 0)
.background(ScrollViewFinder { sv in outerScrollView = sv })
// Your content above the widget
DeunaWidget(deunaSDK: deunaSDK, configuration: widgetConfig)
.onScrollNeeded { overlap in
guard let sv = outerScrollView else { return }
let newOffset = CGPoint(x: 0, y: sv.contentOffset.y + overlap)
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut) {
sv.setContentOffset(newOffset, animated: false)
}
}
// Your content below the widget
}
}
}
}
/// Traverses UIKit view hierarchy to capture the parent UIScrollView
struct ScrollViewFinder: UIViewRepresentable {
let onFound: (UIScrollView) -> Void
func makeUIView(context: Context) -> UIView {
let view = UIView()
view.isHidden = true
DispatchQueue.main.async {
var parent = view.superview
while let p = parent {
if let sv = p as? UIScrollView { onFound(sv); return }
parent = p.superview
}
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}Botón de pago personalizado (hidePayButton)
Si tu aplicación renderiza su propio botón nativo fuera del widget, pasa hidePayButton: true y ejecuta los pagos manualmente usando isValid y submit:
let configuration = PaymentWidgetConfiguration(
orderToken: orderToken,
callbacks: callbacks,
hidePayButton: true
)
// When the user taps your native pay button:
deunaSDK.isValid { isValid in
guard isValid else {
showValidationWarning()
return
}
deunaSDK.submit { result in
if result["status"] as? String == "error" {
print("Submit failed:", result["message"] ?? "")
}
}
}| Método | Descripción | Valor de retorno |
|---|---|---|
deunaSDK.isValid { valid in ... } | Valida la entrada del usuario en el formulario de pago activo. | Bool |
deunaSDK.submit { result in ... } | Envía el pago equivalente a hacer clic en el botón del widget. | [String: Any] (status: "success" o status: "error") |
Filtrar y configurar métodos de pago#
Flujo de formularios directos (paymentMethods)
Las arquitecturas de checkout de DEUNA admiten lanzarse directamente a un formulario de pago individual, un patrón conocido como flujo de formularios.
Aunque paymentMethods es un tipo de array, los motores de checkout actualmente admiten solo un elemento en esta lista. Proporcionar un único método de pago abre el widget directamente en el formulario de ese método (por ejemplo, Kueski Pay BNPL), omitiendo el selector de métodos.
deunaSDK.initPaymentWidget(
orderToken: orderToken,
callbacks: callbacks,
paymentMethods: [
[
"paymentMethod": "bnpl",
"processors": ["kueski"]
]
]
)Resolución de prioridad de configuración
| Prioridad | Fuente | Comportamiento |
|---|---|---|
| 1 (Mayor prioridad) | paymentMethods en .initPaymentWidget() | Flujo de formularios directos: Se abre inmediatamente en el formulario del método de pago único especificado (por ejemplo, Kueski), omitiendo el selector de métodos. |
| 2 | include_payment_options en la creación de la orden | Selección de múltiples métodos: Muestra solo los métodos de pago especificados durante la creación de la orden que estén activos en tu cuenta. |
| 3 (Respaldo) | Configuración a nivel de comerciante (/payment-methods) | Selector completo: Si se omite tanto en la llamada al SDK como en el payload de la orden, muestra todos los métodos de pago activos configurados para tu cuenta de comerciante. |
Configuraciones de PayPal
Tipo de flujo (flowType)
deunaSDK.initPaymentWidget(
orderToken: orderToken,
behavior: WidgetBehavior(
paymentMethods: [
"flowType": "twoStep" // "twoStep" (summary first) or "singleStep" (direct)
]
)
)Compra automática (express)
Cuando los clientes han autorizado previamente pagos rápidos con PayPal, habilita el procesamiento inmediato:
deunaSDK.initPaymentWidget(
orderToken: orderToken,
callbacks: callbacks,
paymentMethods: [
[
"paymentMethod": "wallet",
"processors": ["paypal_wallet"],
"configuration": ["express": true]
]
]
)Estilo dinámico y actualización del pedido#
Personaliza la apariencia de forma dinámica (setCustomStyle)
Actualiza los estilos del widget dinámicamente (por ejemplo, adaptando la marca al detectar el BIN de la tarjeta):
deunaSDK.setCustomStyle(data: [
"theme": [
"colors": [
"primaryTextColor": "#023047",
"buttonPrimaryFill": "#FFB703",
"buttonPrimaryText": "#000000"
]
]
])Actualiza totales del pedido (refetchOrder)
Al ofrecer promociones específicas de franquicia (por ejemplo, "20% de descuento con Mastercard"), escucha a onCardBinDetected, actualice el pedido en su backend y notifique al widget:
callbacks: PaymentWidgetCallbacks(
onCardBinDetected: { metadata in
guard let brand = metadata?["cardBrand"] as? String, brand == "Mastercard" else { return }
Task {
await applyDiscountOnBackend(orderId, promoCode: "MASTERCARD_20")
deunaSDK.refetchOrder { updatedOrder in
print("Order refreshed with discount:", updatedOrder)
}
}
}
)Almacén de pagos y Pago con un clic#
Payment Vault es un componente de las soluciones de pago DEUNA que permite guardar tarjetas de forma segura y pagar mediante Click to Pay sin procesar pagos regulares.
Muestra en un modal
deunaSDK.initElements(
userToken: "<USER_TOKEN>", // optional if userInfo is provided
userInfo: DeunaSDK.UserInfo(
firstName: "Esteban", // optional if userToken is provided
lastName: "Posada", // optional if userToken is provided
email: "esteban@deuna.com" // required
),
callbacks: ElementsCallbacks(
onSuccess: { response in
deunaSDK.close() // Close the Vault widget
// YOUR CODE HERE: Handle card saved successfully
},
onError: { error in
deunaSDK.close() // Close the Vault widget on error
// YOUR CODE HERE: Handle error
},
onClosed: { action in
// Widget closed: action == .userAction or .systemAction
// YOUR CODE HERE: Handle widget dismissal
},
onEventDispatch: { type, response in
// YOUR CODE HERE: Listen to widget events
}
),
orderToken: "YOUR_ORDER_TOKEN", // optional
widgetExperience: ElementsWidgetExperience( // optional
userExperience: ElementsWidgetExperience.UserExperience(
showSavedCardFlow: true, // optional: show card saving toggle
defaultCardFlow: true // optional: show toggle to save as default
)
)
)Mostrar incrustado (SwiftUI)
DeunaWidget(
deunaSDK: deunaSDK,
configuration: ElementsWidgetConfiguration(
callbacks: ElementsCallbacks(
onSuccess: { response in
deunaSDK.dispose() // Explicitly release widget resources
// YOUR CODE HERE: Handle success
},
onError: { error in
// YOUR CODE HERE: Handle error
},
onEventDispatch: { type, response in
// YOUR CODE HERE: Listen to widget events
}
),
userInfo: DeunaSDK.UserInfo(
firstName: "Esteban",
lastName: "Posada",
email: "esteban@deuna.com"
),
orderToken: "YOUR_ORDER_TOKEN",
autoResizeConfig: AutoResizeConfig(initialHeight: 150)
)
)Haga clic para pagar
deunaSDK.initElements(
userInfo: DeunaSDK.UserInfo( // mandatory for Click To Pay
firstName: "Esteban",
lastName: "Posada",
email: "esteban@deuna.com"
),
callbacks: ElementsCallbacks(
onSuccess: { data in
deunaSDK.close() // Close the widget
// YOUR CODE HERE: Handle Click to Pay success
},
onError: { error in
deunaSDK.close() // Close the widget
// YOUR CODE HERE: Handle error
},
onClosed: { action in
// YOUR CODE HERE: Handle widget dismissal
},
onEventDispatch: { type, data in
// YOUR CODE HERE: Listen to widget events
}
),
types: [
[
"name": ElementsWidget.clickToPay // Pass this to render Click to Pay
]
]
)Referencia de parámetros
| Parámetro | Tipo | Modal | Integrado | Descripción |
|---|---|---|---|---|
callbacks | ElementsCallbacks | ✅ | ✅ | Requerido. Los oyentes de eventos (onSuccess, onError, onClosed, onEventDispatch). |
userInfo | DeunaSDK.UserInfo? | ✅ | ✅ | Del cliente firstName, lastNamey email. Requerido para Click to Pay. |
userToken | String? | ✅ | ✅ | Opcional. Token de portador DEUNA. Si se proporciona, omita userInfo. |
types | [[String: Any]]? | ✅ | ✅ | Opcional. Omitir para renderizar la experiencia predeterminada de Card Vault. Pasar [["name": ElementsWidget.clickToPay]] para renderizar Click to Pay. |
orderToken | String? | ✅ | ✅ | Opcional. Token de pedido único. Los detalles del cliente se pueden extraer de billing_address. |
styleFile | String? | ✅ | ✅ | Opcional. UUID de personalización de tema. |
widgetExperience | ElementsWidgetExperience? | ✅ | ✅ | Opcional. showSavedCardFlow (alternador de guardado de tarjeta) y defaultCardFlow (alternador de guardar como predeterminado). |
domain | String? | ✅ | ✅ | Opcional. Anula el host (https://elements.deuna.com). |
hidePayButton | Bool | ❌ | ✅ | Opcional. Oculta el botón cuando está incrustado. Usar isValid y submit para botones personalizados. |
Apple Pay nativo#
Verifica la configuración del comerciante y la capacidad del dispositivo antes de renderizar un botón de Apple Pay.
let userInfo = DeunaSDK.UserInfo(email: "ada@example.com")
let params = GetWalletsAvailableParams(
orderToken: "YOUR_ORDER_TOKEN",
userInfo: userInfo
)
deunaSDK.getWalletsAvailable(params: params) { wallets, error in
if let error = error {
// YOUR CODE HERE: Handle wallet availability check error
return
}
// Check if Apple Pay is available on this device and merchant account
let isApplePayAvailable = wallets.contains(.applePay)
// YOUR CODE HERE: Update Apple Pay button visibility in UI
}Después de que la verificación de disponibilidad sea exitosa, lanza la hoja nativa de Apple Pay usando initElements:
deunaSDK.initElements(
userInfo: userInfo,
callbacks: ElementsCallbacks(
onSuccess: { data in
// YOUR CODE HERE: Handle Apple Pay authorization success
},
onError: { error in
// YOUR CODE HERE: Handle Apple Pay error
},
onClosed: { action in
// YOUR CODE HERE: Handle Apple Pay sheet dismissal
}
),
types: [
["name": "APPLE_PAY"]
],
orderToken: "YOUR_ORDER_TOKEN"
)La aplicación debe incluir la autorización de Apple Pay y un perfil de aprovisionamiento que contenga el identificador del comerciante. Consulte de Apple Pay para la configuración completa.
Continúe con una acción pendiente#
Utilice el mismo token de pedido cuando DEUNA informe que el pago requiere un desafío o redirección 3DS compatible.
deunaSDK.initNextAction(
orderToken: "YOUR_ORDER_TOKEN",
callbacks: NextActionCallbacks(
onSuccess: { order in
deunaSDK.close()
// YOUR CODE HERE: Handle 3DS or action completion
},
onError: { error in
deunaSDK.close()
// YOUR CODE HERE: Handle error
},
onClosed: { action in
// YOUR CODE HERE: Handle modal dismissal
}
)
)El SDK presenta las URLs externas compatibles y devuelve el control al widget. Utilice el estado de llamada de retorno para la interfaz y el estado de pago final de DEUNA para el cumplimiento.
Abrir un cupón#
deunaSDK.initVoucher(
orderToken: "YOUR_ORDER_TOKEN",
callbacks: VoucherCallbacks(
onSuccess: { order in
// YOUR CODE HERE: Handle voucher display
},
onError: { error in
// YOUR CODE HERE: Handle error
},
onClosed: { action in
// YOUR CODE HERE: Handle modal dismissal
}
)
)Las llamadas de retorno de los vouchers siguen el mismo ciclo de éxito, error, cierre y envío de eventos que las otras experiencias de pago.
Datos del dispositivo y huella digital para fraude#
El SDK de iOS de DEUNA utiliza un arquitectura modular: no incluye SDKs de fraude de terceros por defecto. Solo agregue el(los) proveedor(es) específico(s) que planea usar. Si no usas un proveedor, no pagas ninguna penalización de tamaño de la aplicación.
Proveedores compatibles
| Proveedor | Producto SPM | Subespecificación de CocoaPods | Parámetros requeridos |
|---|---|---|---|
MERCADOPAGO | DeunaSDKMercadoPago | pod 'DeunaSDK/MercadoPago' | (Ninguna requerida - pasar [:]) |
RISKIFIED | DeunaSDKRiskified | pod 'DeunaSDK/Riskified' | storeDomain |
CYBERSOURCE | DeunaSDKCybersource | pod 'DeunaSDK/Cybersource' | orgId, merchantId (Opcional: fpServer) |
SIGNIFYD | DeunaSDKSignifyd | pod 'DeunaSDK/Signifyd' | orgId (Opcional: fpServer) |
KOUNT | DeunaSDKKount | pod 'DeunaSDK/Kount' | merchantId, clientId, dataCollectorUrl, environment |
SIFT | DeunaSDKSift | pod 'DeunaSDK/Sift' | accountId, beaconKey |
ACCERTIFY | DeunaSDKAccertify | pod 'DeunaSDK/Accertify' | Archivos de configuración en los recursos del paquete de Xcode |
Configuración de activos del paquete de Accertify
La integración de Accertify requiere dos archivos de configuración dentro de tu proyecto de Xcode. Asegúrate de que ambos archivos se agreguen a tu objetivo principal y se incluyan bajo Copy Bundle Resources:
server_keys_message_hosted.json: El archivo de claves de cifrado públicas proporcionado por Accertify.InMobile.plist: Archivo de lista de propiedades que contiene los detalles de tu comercio:accountID(String): Tu GUID de cuentaregistrationURL(String): Endpoint de registro de InMobilelogURL(String): Endpoint de registro de InMobileserverKeyData(String):server_keys_message_hosted.json
Llamada directa mediante generateFraudId
llamar deunaSDK.generateFraudId con los parámetros para tus proveedores contratados:
deunaSDK.generateFraudId(params: [
"RISKIFIED": [
"storeDomain": "yourdomain.com"
],
"CYBERSOURCE": [
"orgId": "your_org_id",
"merchantId": "your_merchant_id"
],
"MERCADOPAGO": [:],
"ACCERTIFY": [:]
]) { fraudId in
// fraudId is a Base64-encoded JSON string, or nil if providers failed or none configured
guard let fraudId = fraudId else { return }
print("Base64 Fraud ID:", fraudId)
}Pasar fraudCredentials directamente a los widgets
Al lanzar widgets (initPaymentWidget, PaymentWidgetConfiguration, etc.), puedes pasar tu configuración directamente en fraudCredentials. El SDK genera el ID de fraude internamente en el momento de la compra:
deunaSDK.initPaymentWidget(
orderToken: orderToken,
callbacks: callbacks,
fraudCredentials: [
"RISKIFIED": [
"storeDomain": "yourdomain.com"
],
"CYBERSOURCE": [
"orgId": "your_org_id",
"merchantId": "your_merchant_id"
],
"MERCADOPAGO": [:]
]
)Notas de comportamiento
- Sin inflado y seguro ante fallos: Si un proveedor se incluye en la solicitud del diccionario pero su framework o subespecificación no se vinculó, el SDK lo ignora de forma segura sin lanzar una excepción o fallar.
- Ejecución paralela: Los proveedores solicitados se perfilan concurrentemente en hilos en segundo plano.
- Comportamiento de respaldo: Si no hay proveedores válidos configurados o disponibles en el dispositivo, el manejador de finalización recibe
nil.
Referencia del ciclo de vida y llamadas de retorno#
| Callback / Método | Modal | Integrado | Descripción |
|---|---|---|---|
onSuccess | ✅ | ✅ | Operación de pago o bóveda de tarjetas completada exitosamente. Recibe carga útil de orden o credencial. Llamar deunaSDK.close() (modal) o deunaSDK.dispose() (incrustado). |
onError | ✅ | ✅ | Error ocurrido durante la inicialización o procesamiento del pago. Recibe PaymentsError o ElementsError. |
onClosed | ✅ | ❌ | Modal cerrado. Recibe CloseAction.userAction (cerrado manualmente) o CloseAction.systemAction (cerrado mediante close()). |
onPaymentProcessing | ✅ | ✅ | Se activa cuando el cliente toca pagar y comienza el procesamiento del pago. Úsalo para deshabilitar botones y mostrar indicadores de progreso. |
onCardBinDetected | ✅ | ✅ | Se activa cuando se detecta o se borra un BIN de tarjeta (nil cuando el usuario borra el número). Úselo para descuentos de franquicia. |
onInstallmentSelected | ✅ | ✅ | Se activa cuando el cliente selecciona cuotas diferidas (nil en el pago único completo). |
onEventDispatch | ✅ | ✅ | Emite todas las ocurrencias subyacentes de CheckoutEvent o ElementsEvent ocurrencias con cargas útiles de datos. |
close() | ✅ | ❌ | Descarta la presentación modal activa mientras retiene la instancia del SDK. |
dispose() | ❌ | ✅ | Libera el controlador embebido y el WebView cuando la jerarquía de vistas se desmonta. |
Manejo de errores (onError)
Inspeccionar error.type para distinguir fallos de inicialización de rechazos de procesamiento:
onError: { error in
switch error.type {
case .initializationFailed:
// Widget failed to load; close presentation and notify user
deunaSDK.close()
showToast("Payment service temporarily unavailable")
case .paymentError:
// Transaction declined or processor error
showRetry(error)
@unknown default:
showGenericError(error)
}
}Ejemplos y código fuente oficiales#
Ver WalletsScreen.swift para Apple Pay nativo y EmbeddedScreen.swift para el ciclo de vida de SwiftUI.