Full SDK (iOS)
SDK recomendadoRecomendamos utilizar el Seamless SDK iOS para una experiencia de integración sin problemas. Esta opción ofrece una solución de pago flexible con componentes de interfaz de usuario predefinidos y opciones de personalización.
Esta página proporciona todos los pasos para añadir, configurar y utilizar el SDK completo de iOS en tu proyecto.
Requisitos
Para implementar el SDK de Yuno iOS, necesitas cumplir los siguientes requisitos:
- Añade CocoaPods o Swift Package Manager a tu proyecto.
- Utiliza iOS versión 14.0 o superior.
Paso 1: Incluya la biblioteca en tu proyecto
Puede agregar la biblioteca usando CocoaPods o Swift Package Manager.
CocoaPods
Para añadir el SDK de Yuno a tu proyecto iOS, necesitas instalar el SDK de Yuno. Si no tienes un Podfile, sigue la guía de CocoaPods para crear uno. Después de crear el Podfile, integrarás el SDK de Yuno con Cocoapods añadiendo la siguiente línea a tu Podfile.
pod 'YunoSDK', '~> 1.1.22'Después, necesita ejecutar la instalación:
instalar pod
Administrador de Paquetes Swift
Para añadir el SDK de Yuno a tu proyecto iOS, necesitas instalar el archivo Administrador de Paquetes Swift. Con el paquete Swift configurado, añade YunoSDK como dependencia, tal y como se presenta en el siguiente bloque de código:
dependencias: [
.package(url: "https://github.com/yuno-payments/yuno-sdk-ios.git", .upToNextMajor(from: "1.1.17"))
]Paso 2: Initialize el SDK con la clave pública
Para empezar a ejecutar la comprobación completa de Yuno para iOS, primero obtén el ID de tu aplicación Yuno y la Clave Pública de la API. Después, importa e initialize Yuno como se muestra a continuación:
import YunoSDK
Yuno.initialize(
apiKey: "PUBLIC_API_KEY",
config: YunoConfig(),
callback: { (value: Bool) in }
)
CredencialesPara más información, consulte la página de credenciales: https://docs.y.uno/reference/authentication
Uso de UISceneDelegateSi su aplicación utiliza un UISceneDelegate, asegúrese de colocar el código de inicialización de Yuno dentro de su SceneDelegate.
La comprobación completa le permite configurar la apariencia y el proceso. Se trata de un paso opcional que se configura a través de la clase YunoConfig. Si desea establecer las configuraciones, el siguiente bloque de código muestra los elementos que pueden configurarse:
final class YunoConfig {
let cardFormType: CardFormType,
let appearance: Yuno.Appearance,
let saveCardEnabled: Bool,
let keepLoader: Bool
}Configura el SDK con las siguientes opciones:
| Parámetro | Descripción |
|---|---|
cardFormType | Este campo se puede utilizar para elegir el flujo de pago y Tarjeta de Inscripción. Es una propiedad opcional y considera .oneStep por defecto. |
appearance | Este campo opcional define la apariencia de la caja. De forma predeterminada, utiliza los estilos de Yuno. |
saveCardEnabled | Este campo opcional se puede utilizar para elegir si la casilla de verificación Guardar tarjeta se muestra en los flujos de tarjetas. Por defecto es falso. |
keepLoader | Este campo opcional proporciona control sobre cuándo ocultar el cargador. Si se establece en true, la hideLoader() se debe llamar a la función para ocultar el cargador. De forma predeterminada, está configurado en false. |
hideCardholderName | Este campo opcional te permite ocultar el campo del nombre del titular de la tarjeta en el formulario de la tarjeta. Cuando se establece en true, el campo del nombre del titular de la tarjeta no se muestra. Cuando no se especifica o se establece en false, se muestra el campo del nombre del titular de la tarjeta (comportamiento predeterminado). Ocultar el campo no afecta al PAN, la caducidad, la recopilación del CVV, la lógica BIN ni las validaciones 3DS/proveedor. El comerciante es responsable de garantizar que se proporcione el nombre del titular de la tarjeta cuando lo requiera tu pago . |
Acceda a su clave APIRecupera tu Clave API de la sección de Desarrolladores en el Panel de Control de Yuno.
Paso 3: Iniciar el proceso de pago
La clase ViewController se define como una subclase de UIViewController y también adopta el protocolo YunoPaymentDelegate protocolo.
DeprecaciónEl objeto
startCheckoutha quedado obsoleto en las últimas versiones del SDK de iOS.
protocol YunoPaymentDelegate: AnyObject {
var checkoutSession: String { get }
var countryCode: String { get }
var language: String? { get }
var viewController: UIViewController? { get }
func yunoCreatePayment(with token: String)
func yunoCreatePayment(with token: String, information: [String: Any])
func yunoPaymentResult(_ result: Yuno.Result)
}
class ViewController: YunoPaymentDelegate {
func viewDidLoad() {
super.viewDidLoad()
}
}Parámetros
| Parámetro | Descripción |
|---|---|
checkoutSession | Se refiere a la sesión de checkout del pago actual. |
countryCode | Este parámetro determina el país para el que se está configurando el proceso de pago. La lista completa de países admitidos y su código de país está disponible en la página Cobertura de países. |
language | Define el idioma que se utilizará en los formularios de pago. Puede establecerlo en una de las opciones de idioma disponibles:
|
viewController | Esta propiedad representa la UIViewController utilizado para presentar el flujo de pago . Aunque la propiedad sigue siendo opcional por compatibilidad con versiones anteriores, debes proporcionar un controlador visible para que el SDK pueda presentar su interfaz de usuario correctamente. |
yunoCreatePayment(with token: String) | Este método es responsable de crear un pago con el token proporcionado. Toma un parámetro String llamado token, que representa el token de pago. |
yunoCreatePayment(with token: String, information: [String: Any]) | Este método es responsable de crear un pago con el token proporcionado. Toma un parámetro String llamado token, que representa el token de pago. Además, devuelve toda la información de respuesta del token en un diccionario. |
yunoPaymentResult(_ result: Yuno.Result) | Este método se llama cuando se completa el proceso de pago, proporcionando el resultado del pago como parámetro de tipo Yuno.Result. |
Nota importante sobre yunoCreatePaymentPuedes llamar
yunoCreatePaymentcon o sin elinformationParámetro según sus necesidades. Sin embargo, utiliza solo una versión en tu código, ya que llamar a ambas no es obligatorio y podría causar problemas.
Requisitos de concurrencia de Swift 6Si está utilizando Swift 6, deberá implementar el
YunoPaymentDelegateProtocolo con consideraciones específicas de concurrencia. Swift 6 introduce requisitos de seguridad de subprocesos más estrictos que afectan la implementación de delegados. Consulte ImplementandoYunoPaymentDelegatecon concurrencia Swift 6 Sección para opciones de implementación detalladas y mejores prácticas.
Paso 4: Añadir la vista SDK a la caja
Su punto de vista debe adoptar la YunoPaymentFullDelegate protocolo. Esto permite que su aplicación responda a acciones pago, como cuando el usuario selecciona un método de pago.
He aquí cómo definir el delegado:
protocol YunoPaymentFullDelegate: YunoPaymentDelegate {
func yunoDidSelect(paymentMethod: YunoSDK.PaymentMethodSelected)
func yunoDidUnenrollSuccessfully(_ success: Bool)
func yunoUpdatePaymentMethodsViewHeight(_ height: CGFloat)
}Parámetros
| Función | Descripción |
|---|---|
yunoDidSelect(paymentMethod: YunoSDK.PaymentMethodSelected) | Llamada cuando el usuario selecciona un método de pago. - paymentMethod: El método elegido por el usuario. |
yunoDidUnenrollSuccessfully(_ success: Bool) | Llamada cuando finaliza una acción de desinscripción. - success: true si funcionara, false si no lo hiciera. |
yunoUpdatePaymentMethodsViewHeight(_ height: CGFloat) | Llamado cuando getPaymentMethodViewAsync() Se invoca siempre que cambia la altura de la vista. |
Para mostrar los métodos de pago, llame al siguiente método y pase su modelo de vista o controlador como delegado.
await Yuno.getPaymentMethodViewAsync(delegate:)Este método devolverá automáticamente el tipo correcto de vista dependiendo del framework de interfaz de usuario que esté utilizando:
- Si utiliza UIKit, devuelve un
UIView. - Si utiliza SwiftUI, devuelve un
some View.
Esto facilita la integración del SDK en cualquier proyecto iOS, independientemente del framework de interfaz de usuario que se utilice.
Paso 5: Iniciar el proceso de pago
Para iniciar un pago después de mostrar los métodos de pago, llame a la función startPayment :
Yuno.startPaymentshowPaymentStatus:Bool)Paso 6: Obtener el OTT ( token de un solo uso)
Puedes obtener el token único para realizar el pago consecutivo al final de este proceso. Recibirás el token único en la función. yunoCreatePayment() que implementa al adoptar el YunoPaymentDelegate. A continuación se muestra un ejemplo de recuperación del token de un solo uso:
func yunoCreatePayment(with token: String) { ... }Paso 7: Crear el pago
Una vez completados los pasos descritos anteriormente, puede crear un pago. La creación de pagos consecutivos debe realizarse utilizando el endpoint Create Payment . El comerciante debe llamar a su backend para crear el pago dentro de Yuno, utilizando el token de un solo uso y la sesión de pago.
Continuar con el método de pagoPara garantizar una experiencia de pago fluida, es fundamental integrar el método
continuePaymentdespués de crear un pago. Este paso es especialmente importante para los métodos de pago asíncronos que requieren acciones adicionales del cliente. Esto es lo que necesita saber:
- Manejo de pagos asincrónicos:La API indicará la necesidad de tomar medidas adicionales con el
sdk_action_requiredcampo establecido en verdadero.- Funcionalidad: El
yuno.continuePayment()Esta función está diseñada para administrar y mostrar cualquier pantalla adicional necesaria para que el cliente complete el pago.- Simplificación del proceso: Al utilizar este método, puede agilizar el proceso de pago, ya que maneja automáticamente varios escenarios para usted.
YunocontinuePayment()Paso 8: Gestionar pago (opcional)
Enlaces profundos y Mercado Pago Checkout ProEste paso solo es necesario si utilizas un método de pago que utiliza enlaces profundos o Mercado Pago Checkout Pro. Si tus métodos de pago no utilizan enlaces profundos, puedes omitir este paso.
Algunos métodos de pago sacan a los usuarios de la app para completar la transacción. Una vez finalizado el pago, se redirige al usuario a la app mediante un enlace profundo. El SDK utiliza este enlace profundo para comprobar qué ha sucedido, verificando si el pago se realizó correctamente, falló o se canceló, y puede mostrar una pantalla de estado al usuario.
Para solucionar esto, necesita actualizar su AppDelegate Para devolver la URL entrante al SDK de Yuno. Esto permite que el SDK lea el resultado y, opcionalmente, muestre el estado del pago. El siguiente fragmento de código muestra cómo añadirlo a la aplicación:
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard url.scheme == "yunoexample" else { return false }
return Yuno.receiveDeeplink(url)
}Este código detecta enlaces profundos que abren tu aplicación. Al recibir una URL, comprueba si el esquema coincide con el que usaste en el callback_url durante la configuración de la sesión de pago. Si coincide, la URL se pasa al SDK de Yuno mediante Yuno.receiveDeeplink(...)Luego, el SDK lee el resultado del pago y muestra la pantalla de estado correspondiente al usuario.
Asegúrese de que url.scheme En este código coincide con el callback_url que usted proporcionó al crear el checkout_session.
Llamar de vuelta
Una vez que se completa el pago, el SDK puede devolver diferentes estados de transacción: success, fail, processing, reject, internalErrory userCancell. Las descripciones de cada estado de transacción se presentan en la siguiente tabla.
| Estado de la transacción | Descripción |
|---|---|
succeeded | Indica que el proceso de transacción o pago se ha completado con éxito. |
fail | Este estado indica que la transacción o el proceso de pago ha fallado. Significa que hubo un error o problema durante el proceso de pago, impidiendo que se completara exitosamente. |
processing | Indica que el proceso de transacción o pago se está procesando actualmente. Por lo general, se usa cuando hay un retraso en el procesamiento del pago, como esperar la aprobación de un servicio de terceros o una institución financiera. |
reject | Este estado indica que la transacción ha sido rechazada. El rechazo puede ocurrir por varios motivos, como fondos insuficientes, actividad fraudulenta o solicitudes que violen reglas o políticas específicas. |
internalError | Significa que ocurrió un error inesperado dentro del sistema o la infraestructura que maneja el proceso de pago. Este estado sugiere un problema en el servidor o en el backend en lugar de un problema con la entrada o solicitud del usuario. |
userCancell | Este estado indica que el usuario ha cancelado o abortado voluntariamente la transacción o proceso de pago. Este estado generalmente se usa cuando existe una opción para que el usuario cancele o abandone el proceso de pago. |
Validación pago
En esta sección se explica cómo gestiona el SDK pago cuando los usuarios cancelan o abandonan pago , y cómo se relaciona el estado del SDK con pago del backend en estos casos.
Sincronizar pago (Apple Pay)
En el caso de pago sincrónicos, como Apple Pay, cuando tú cancelas o cierras la interfaz de usuario de la cartera antes de recibir la respuesta del proveedor pago (PSP):
- Estado del SDK: Devoluciones
userCancell(CANCELLED) - pago en el backend: Restos
PENDINGhasta el tiempo de espera de PSP o la cancelación por parte del comerciante - ImportanteEl SDK no devolverá
rejectoprocessingen este escenario
Esto garantiza que el pago backend pago en estado pendiente y pueda ser gestionado correctamente por el sistema del comerciante.
pago asíncronos (métodos basados en PIX y QR)
Para pago asíncronos como PIX, cuando tú cierras la ventana del código QR (haces clic en X) antes de completar el pago:
- Estado del SDK: Devoluciones
PENDING, opcionalmente con un subestado comoCLOSED_BY_USER - pago en el backend: Restos
PENDINGy el código QR sigue siendo válido hasta su fecha de caducidad. - Reutilización de la sesión de pago: al volver a abrir la misma sesión de pago, se puede mostrar el mismo código QR válido.
- Sin cancelación automática: El pago PIX no pago cancela automáticamente cuando tú cierras la ventana QR.
Este comportamiento permite a los usuarios volver al pago y completar la transacción utilizando el mismo código QR antes de que caduque.
Pagos asíncronos caducados
Si un código QR PIX caduca de forma natural:
- Estado del backendActualizado a
EXPIRED - Estado del SDK: Las devoluciones de llamada del SDK y endpoints de sondeo endpoints
EXPIREDde manera constante
Esto garantiza que los comerciantes reciban información precisa sobre el estado cuando un pago ha caducado.
Para obtener el estado de la transacción, tienes que implementar el delegado que se presenta en el siguiente fragmento de código:
enum Result {
case reject, success, fail, processing, internalError, userCancell
}
func yunoPaymentResult(_ result: Yuno.Result) { ... }
func yunoEnrollmentResult(_ result: Yuno.Result) { ... }Características complementarias
Yuno iOS SDK proporciona servicios y configuraciones adicionales que puedes utilizar para mejorar la experiencia de los clientes. Utiliza las personalizaciones del SDK para cambiar la apariencia del SDK para que coincida con tu marca o para configurar el cargador.
- Cargador: Controla el uso del cargador mediante las opciones de configuración del SDK.
- Guardar tarjeta para futuros pagos: Además, puede mostrar una casilla de verificación para guardar o inscribir tarjetas usando
cardSaveEnable: true. A continuación encontrará ejemplos de la casilla de verificación para ambos renders de formulario de tarjeta.
- También puede elegir una de las opciones de renderizado para la forma de la tarjeta. A continuación encontrará capturas de pantalla que presentan la diferencia entre las opciones
cardFormTypeONE_STEPySTEP_BY_STEP.
- Personalizaciones del SDK: Cambia la apariencia del SDK para que coincida con tu marca.
Integración del modo de renderizado
El modo de renderizado del SDK de Yuno ofrece mayor flexibilidad en la interfaz de usuario, lo que permite a los desarrolladores integrar flujos de pago con control total sobre la interfaz de usuario, conservando al mismo tiempo toda la funcionalidad del SDK. Este modo proporciona vistas SwiftUI que se integran perfectamente en la interfaz de usuario existente.
Función principal: startPaymentRenderFlow
startPaymentRenderFlowEl objeto startPaymentRender Esta función es una característica del SDK de Yuno que permite a los comerciantes integrar el proceso de pago de forma más detallada y personalizable. Esta función ofrece control total sobre cuándo y cómo se muestran los formularios de pago, lo que facilita una integración más fluida con la interfaz de usuario de la aplicación del comerciante.
Esta función está diseñada para ofrecer un mayor control sobre el flujo de pago, permitiendo a los comerciantes:
- Integre formularios de pago de forma personalizada dentro de su propia interfaz de usuario.
- Controle con precisión cuándo se muestran los formularios de datos de pago.
- Obtenga un control detallado sobre el proceso de confirmación de pago.
- Proporcionar una experiencia de usuario más fluida y consistente dentro de la aplicación del comerciante.
Sintaxis
La sección de sintaxis proporciona la firma del método startPaymentRender Función. Esta función es fundamental para integrar el proceso de pago en tu aplicación, ofreciendo un enfoque personalizable y detallado para gestionar los formularios y flujos de pago.
@MainActor static func startPaymentRenderFlow(
pagoMétodoSeleccionado: PaymentMethodSelected,
con delegado: YunoPaymentDelegate
) async -> algún YunoPaymentRenderFlowProtocoloParámetros
El objeto startPaymentRender requiere parámetros específicos para operar con eficacia. Estos parámetros son esenciales para definir el método de pago y manejar las respuestas del proceso de pago.
| Parámetro | Tipo | Descripción |
|---|---|---|
paymentMethodSelected | PaymentMethodSelected | El método de pago seleccionado por el usuario. Debe incluir el vaultedToken (si existe) y el paymentMethodType |
delegate | YunoPaymentDelegate | El delegado que gestionará las respuestas del proceso de pago, incluida la creación del token y el resultado final. |
Valor de retorno
Devuelve una instancia que cumple con YunoPaymentRenderFlowProtocol, que proporciona métodos para gestionar el flujo de procesamiento de pagos.
Protocolo YunoPaymentRenderFlowProtocol
La instancia devuelta por startPaymentRender se ajusta a este protocolo que incluye los siguientes métodos:
formView(método de pago seleccionado:con:)
func formularioVer(
métodoPagoSeleccionado: PaymentMethodSelected,
con delegado: YunoPaymentDelegate
) async -> ¿CualquierVista?- Finalidad: Obtiene la vista del formulario para capturar los datos de pago
- Comportamiento:
- Si el método de pago requiere mostrar un formulario, devuelve un
AnyViewcon el formulario correspondiente - Si el método de pago no necesita mostrar ningún formulario (por ejemplo, métodos ya configurados), devuelve
nil
- Si el método de pago requiere mostrar un formulario, devuelve un
- Cuándo utilizarlo: Llamar inmediatamente después de crear la instancia de flujo de pago
enviarFormulario()
func submitForm()- Finalidad: Enviar los datos del formulario para su validación
- Comportamiento: Ejecuta todas las validaciones necesarias y, si tiene éxito, procede a generar un nuevo token de un solo uso.
- Cuándo utilizar: Cuando el usuario ejecuta la acción "pagar" en la aplicación del comerciante.
continuePayment()
func continuePayment() async -> ¿CualquierVista?- Finalidad: Continúa el proceso de pago después de que se haya generado el token de un solo uso.
- Comportamiento:
- Si es necesario mostrar alguna vista adicional (por ejemplo, autenticación 3DS), devuelve un icono
AnyView - Si no se requiere ninguna vista adicional, devuelve
nil
- Si es necesario mostrar alguna vista adicional (por ejemplo, autenticación 3DS), devuelve un icono
- Cuándo utilizarlo: Tras recibir el token de un solo uso a través del delegado y crear el pago.
Flujo de implementación
Esta sección describe la secuencia de pasos necesarios para implementar el proceso de procesamiento de pagos utilizando el SDK de Yuno.
Paso 1: Configuración inicial
Para comenzar a utilizar startPaymentRenderAsegúrese de que el SDK esté inicializado correctamente y que tenga un archivo válido. checkoutSessionSiga los pasos a continuación para configurar su entorno:
await Yunoinitialize(apiKey: "tu_clave_api")Paso 2: Crear una instancia de flujo de pago
Cree una instancia de flujo de pago para administrar y representar el proceso de pago utilizando el método seleccionado.
let paymentFlow = await Yuno.startPaymentRenderFlow(
métodoPagoSeleccionado: métodoPagoSeleccionado,
con: yo
)Paso 3: Obtener y mostrar el formulario
Recupere y presente el formulario de pago para recopilar la información de pago del usuario de manera eficiente.
let formView = await paymentFlow.formView(
paymentMethodSelected: selectedPaymentMethod,
with: self
)
if let formView = formView {
VStack {
Text("Payment Information")
formView
Button("Pay") {
paymentFlow.submitForm()
}
}
} else {
paymentFlow.submitForm()
}Paso 4: Gestionar el token de un solo uso
Implemente el método delegado para recibir el token:
extension MyViewController: YunoPaymentDelegate {
var checkoutSession: String {
return "your_checkout_session"
}
var countryCode: String {
return "CO"
}
var viewController: UIViewController? {
return self
}
func yunoCreatePayment(with token: String, information: [String: Any]) {
createPaymentInBackend(token: token) { [weak self] success in
if success {
Task {
let additionalView = await self?.paymentFlow?.continuePayment()
if let additionalView = additionalView {
self?.showAdditionalView(additionalView)
}
}
}
}
}
func yunoPaymentResult(_ result: Yuno.Result) {
switch result {
case .succeeded:
showSuccessMessage()
case .reject:
showRejectionMessage()
case .fail:
showErrorMessage()
case .processing:
showProcessingMessage()
case .userCancell:
handleCancellation()
case .internalError:
showInternalErrorMessage()
}
}
}Ejemplo completo
import SwiftUI
import YunoSDK
struct PaymentRenderView: View {
@State private var paymentFlow: YunoPaymentRenderFlowProtocol?
@State private var formView: AnyView?
@State private var additionalView: AnyView?
let selectedPaymentMethod: PaymentMethodSelected
let delegate: YunoPaymentDelegate
var body: some View {
VStack(spacing: 20) {
Text("Complete Purchase")
.font(.title2)
.fontWeight(.bold)
OrderSummaryView()
if let formView = formView {
VStack(alignment: .leading) {
Text("Payment Information")
.font(.headline)
formView
}
}
if let additionalView = additionalView {
additionalView
}
Spacer()
Button(action: {
paymentFlow?.submitForm()
}) {
Text("Confirm Payment")
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
.padding()
.onAppear {
setupPaymentFlow()
}
}
private func setupPaymentFlow() {
paymentFlow = await Yuno.startPaymentRenderFlow(
paymentMethodSelected: selectedPaymentMethod,
with: delegate
)
Task {
formView = await paymentFlow?.formView(
paymentMethodSelected: selectedPaymentMethod,
with: delegate
)
}
}
}
class PaymentDelegate: YunoPaymentDelegate {
let checkoutSession: String
let countryCode: String
weak var viewController: UIViewController?
init(checkoutSession: String, countryCode: String, viewController: UIViewController?) {
self.checkoutSession = checkoutSession
self.countryCode = countryCode
self.viewController = viewController
}
func yunoCreatePayment(with token: String, information: [String: Any]) {
PaymentService.createPayment(token: token) { [weak self] result in
switch result {
case .success:
Task {
await self?.continuePaymentProcess()
}
case .failure(let error):
print("Error creating payment: \(error)")
}
}
}
func yunoPaymentResult(_ result: Yuno.Result) {
DispatchQueue.main.async {
switch result {
case .succeeded:
NotificationCenter.default.post(name: .paymentSucceeded, object: nil)
case .reject:
NotificationCenter.default.post(name: .paymentRejected, object: nil)
}
}
}
private func continuePaymentProcess() async {
}
}Casos de uso comunes
Esta sección describe escenarios típicos en los que se puede utilizar el SDK de Yuno para gestionar diversos métodos de pago, proporcionando flexibilidad y facilidad de integración.
1. Pago con tarjeta de crédito
En este caso de uso, demostramos cómo procesar pagos utilizando nueva información de tarjeta de crédito, requiriendo que el usuario complete un formulario para capturar los detalles necesarios de la tarjeta.
let pagoTarjeta = MétodoPagoTarjetapaymentMethodType: "TARJETA")
let flujo = Yuno.startPaymentRender(metodoPagoSeleccionado: pagoTarjeta, con: delegado)
let form = await flow.formView(paymentMethodSelected: cardPayment, with: delegate)2. Pago con método guardado
Este escenario demuestra el uso de un método de pago guardado, lo que permite a los usuarios pagar sin tener que volver a ingresar los detalles mediante el uso de un token almacenado.
let tarjetaguardada = TarjetaPagoGuardada(
paymentMethodType"TARJETA",
vaultedToken: "saved_token_123"
)
let flow = Yuno.startPaymentRender(paymentMethodSelected: savedCard, with: delegate)
let form = await flow.formView(paymentMethodSelected: savedCard, with: delegate)3. Pago con autenticación 3DS
3D Secure (3DS) añade un paso de verificación adicional para mayor seguridad. El SDK de Yuno integra este proceso en tu flujo de pago a la perfección.
func yunoCreatePayment(with token: String, information: [String: Any]) {
createPayment(token: token) { [weak self] success in
if success {
Task {
let authView = await self?.paymentFlow?.continuePayment()
if let authView = authView {
self?.show3DSView(authView)
}
}
}
}
}Consideraciones importantes
Esta sección destaca los puntos clave para integrar el SDK de Yuno de manera efectiva, garantizando un proceso de pago seguro y sin problemas.
Prerrequisitos
- Asegúrese de que el SDK esté inicializado antes de usarlo
startPaymentRender - El delegado debe implementar todos los métodos requeridos de
YunoPaymentDelegate - El objeto
checkoutSessiondebe ser válido y activo
Gestión estatal
- Compruebe siempre si
formView()devolucionesnilantes de mostrar la vista - Manejar adecuadamente el caso donde
continuePayment()devolucionesnil - Implementar estados de carga durante operaciones asincrónicas
Seguridad
- Nunca guarde tokens de un solo uso: úselos inmediatamente
- Valide siempre los resultados de pago en su backend
- Implementar tiempos de espera adecuados para las operaciones de red
Actuación
- Llamadas a
formView()ycontinuePayment()son asincrónicos - Considere mostrar indicadores de carga durante estas operaciones
- Reutiliza la instancia del flujo de pago cuando sea posible
Solución de problemas
Esta sección ofrece soluciones rápidas a problemas comunes surgidos durante la integración del SDK de Yuno, garantizando un proceso de pago más fluido.
Problemas comunes
-
formView()siempre regresanil- Verificar que el método de pago seleccionado requiera un formulario
- Asegúrese de que el SDK se inicialice correctamente
-
El delegado no recibe
yunoCreatePayment- Verificar que
submitForm()se está llamando correctamente - Confirmar que el formulario tiene datos válidos
- Verificar que
-
continuePayment()No devuelve la vista cuando se espera- Algunos métodos de pago no requieren vistas adicionales
- Comprueba la configuración del método de pago en tu panel de Yuno
Registros de depuración
Yuno.config.environment = .stagingMigración desde otros métodos
Si estás migrando desde startPayment() o startPaymentLite():
Yuno.startPaymentshowPaymentStatus: true)
let flow = Yuno.startPaymentRender(paymentMethodSelected: method, with: delegate)
let formulario = await flujo.formularioVista(metodoPagoSeleccionado: método, con: delegado)El principal beneficio de utilizar el nuevo método es el control detallado que proporciona tanto sobre la interfaz de usuario como sobre el proceso de pago.
App DemoAdemás de los ejemplos de código proporcionados, puedes acceder al repositorio de Yuno para una implementación completa de Yuno iOS SDKs.
Implementando YunoPaymentDelegate con concurrencia Swift 6
YunoPaymentDelegate con concurrencia Swift 6Swift 6 introduce requisitos de concurrencia más estrictos que afectan la forma en que se implementa el YunoPaymentDelegate Protocolo. Esta sección explica los desafíos y ofrece soluciones para diferentes escenarios de implementación.
Comprensión de la concurrencia en Swift 6La concurrencia es la capacidad de tu aplicación para gestionar múltiples tareas simultáneamente. Con Swift 6, las reglas de concurrencia se han vuelto más estrictas para mejorar la estabilidad de la aplicación y evitar fallos. Esto significa que tu código debe estar estructurado con mayor cuidado para garantizar la seguridad de los subprocesos y una gestión adecuada de las tareas.
El problema
Con Swift 6, los protocolos que heredan de Sendable Requieren que todas sus implementaciones sean seguras para subprocesos. Esto genera advertencias al implementar el delegado en clases marcadas como @MainActor.
Seguro para subprocesos significa que tu código puede llamarse de forma segura desde múltiples subprocesos sin provocar fallas o comportamientos inesperados. @MainActor garantiza que el código se ejecute en el hilo principal (hilo de UI).
Nuestra decisión de diseño
No marcamos los protocolos como @MainActor porque:
- Obligaría a todas las implementaciones a ser
MainActor-compatible - Reduciría la flexibilidad para los comerciantes que no utilizan
MainActor - Cada implementación tiene diferentes necesidades de concurrencia
Responsabilidad del comerciante
Es responsabilidad del comerciante gestionar la concurrencia según su implementación. A continuación, se presentan tres enfoques diferentes que puede utilizar según sus necesidades específicas.
Opción 1: Propiedades inmutables
Este enfoque utiliza propiedades inmutables que son automáticamente seguras para subprocesos, lo que las hace ideales para configuraciones simples. Es ideal para aplicaciones sencillas con valores de configuración fijos que no cambian durante la ejecución.
@MainActor
class MyViewController: UIViewController, YunoPaymentDelegate {
private let _countryCode = "CO"
private let _language = "EN"
nonisolated var countryCode: String { _countryCode }
nonisolated var language: String? { _language }
nonisolated var checkoutSession: String { _checkoutSession }
nonisolated func yunoPaymentResult(_ result: Yuno.Result) {
Task { @MainActor in
}
}
}Opción 2: Propiedades mutables con MainActor.assumeIsolated
MainActor.assumeIsolatedEste enfoque, ideal para aplicaciones en las que los valores de configuración pueden cambiar durante el tiempo de ejecución (como las preferencias del usuario), permite propiedades mutables y al mismo tiempo mantiene la seguridad de los subprocesos mediante el uso de MainActor.assumeIsolated.
@MainActor
class MyViewController: UIViewController, YunoPaymentDelegate {
@Published var configLanguage: String = "EN"
@Published var configCountryCode: String = "CO"
nonisolated var language: String? {
MainActor.assumeIsolated { configLanguage }
}
nonisolated var countryCode: String {
MainActor.assumeIsolated { configCountryCode }
}
}Opción 3: Para noMainActor clases
MainActor clasesEste enfoque es adecuado para clases de servicio que no requieren MainActor por lo que es ideal para servicios en segundo plano o clases utilitarias que no interactúan con la interfaz de usuario.
class MyService: YunoPaymentDelegate {
let countryCode: String
let language: String?
let checkoutSession: String
let viewController: UIViewController?
init(countryCode: String, language: String?, checkoutSession: String, viewController: UIViewController?) {
self.countryCode = countryCode
self.language = language
self.checkoutSession = checkoutSession
self.viewController = viewController
}
func yunoPaymentResult(_ result: Yuno.Result) {
}
}⚠️ Consideraciones importantes
Al implementar la concurrencia en su delegado, tenga en cuenta estos puntos clave:
MainActor.assumeIsolated: Utilízalo sólo cuando garantices que se llama desdeMainActor. Se trata de un mecanismo de seguridad que le dice a Swift "confía en mí, sé que esto se está ejecutando en el hilo principal".nonisolated: Significa que se puede acceder a él desde cualquier subproceso, por lo que debe ser seguro para subprocesos. Utilízalo cuando tus propiedades o métodos no dependan del estado de la interfaz de usuario.viewController: Permanece como@MainActorporque siempre se debe acceder desde el hilo principal. Los componentes de la interfaz de usuario siempre deben ejecutarse en el hilo principal para evitar fallos.
Actualizado hace 27 días