Lite SDK (Payment iOS)
SDK recomendadoRecomendamos o uso do iOS Seamless SDK para uma experiência de integração tranquila. Essa opção oferece uma solução de pagamento flexível com componentes de IU pré-criados e opções de personalização.
Este guia o orienta na integração do SDK Lite iOS da Yuno para pagamentos em seu projeto.
Requisitos
Antes de implementar o SDK do Yuno para iOS, verifique se você atende a esses requisitos:
- Adicione o CocoaPods ou o Swift Package Manager ao seu projeto.
- Use o iOS versão 14.0 ou superior.
Etapa 1: Inclua a biblioteca em seu projeto
Você pode adicionar a biblioteca usando o CocoaPods ou o Swift Package Manager.
CocoaPods
Adicione o Yuno SDK ao seu projeto iOS usando o CocoaPods. Se você não tiver um Podfile, siga o guia do CocoaPods para criar um. Em seguida, adicione a seguinte linha ao seu Podfile:
pod 'YunoSDK', '~> 1.1.22'Em seguida, execute a instalação:
instalação do pod
Gerenciador de pacotes Swift
Adicione o Yuno SDK usando o Swift Package Manager. Adicionar YunoSDK como uma dependência em seu arquivo Package.swift:
dependências: [
.package(url: "https://github.com/yuno-payments/yuno-sdk-ios.git", .upToNextMajor(from: "1.1.17"))
]Etapa 2: Initialize o SDK com a chave pública
Initialize o Yuno iOS SDK com sua chave de API pública:
import YunoSDK
Yuno.initialize(
apiKey: "PUBLIC_API_KEY",
config: YunoConfig(),
callback: { (value: Bool) in }
)
UISceneDelegateSe o seu aplicativo estiver usando um UISceneDelegate, você precisará colocar o código de inicialização do Yuno no SceneDelegate.
Configure a aparência e o comportamento do SDK usando a opção YunoConfig classe. Isso é opcional e permite que você personalize a experiência de checkout:
final class YunoConfig {
let cardFormType: CardFormType,
let appearance: Yuno.Appearance,
let saveCardEnabled: Bool,
let keepLoader: Bool
}Configure o SDK com as seguintes opções:
| Parâmetro | Descrição |
|---|---|
cardFormType | Esse campo pode ser usado para escolher o fluxo do cartão de pagamento e de inscrição. É uma propriedade opcional e considera .oneStep por padrão. |
appearance | Esse campo opcional define a aparência do checkout. Por padrão, ele usa os estilos Yuno. |
saveCardEnabled | Esse campo opcional pode ser usado para escolher se a caixa de seleção Salvar cartão é exibida nos fluxos de cartões. Por padrão, ela é falsa. |
keepLoader | Esse campo opcional fornece controle sobre quando ocultar o carregador. Se definido como true, o hideLoader() deve ser chamada para ocultar o carregador. Por padrão, ela é definida como false. |
hideCardholderName | Este campo opcional permite ocultar o campo do nome do titular do cartão no formulário do cartão. Quando definido como true, o campo do nome do titular do cartão não é exibido. Quando não especificado ou definido como false, o campo do nome do titular do cartão é exibido (comportamento padrão). Ocultar o campo não afeta o PAN, a validade, a coleta do CVV, a lógica do BIN ou as validações 3DS/provedor. O comerciante é responsável por garantir que o nome do titular do cartão seja fornecido quando exigido pelo seu provedor de pagamentos. |
Como acessar sua chave de APIVocê pode recuperar sua chave de API na seção Desenvolvedores no Painel de Controle do Yuno.
Etapa 3: Inicie o processo de checkout
Crie um ViewController que adote o YunoPaymentDelegate protocolo:
DepreciaçãoO
startCheckoutfoi preterido nas versões recentes do SDK do 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 | Descrição |
|---|---|
checkoutSession | Refere-se à sessão de checkout do pagamento atual. |
countryCode | Esse parâmetro determina o país para o qual o processo de pagamento está sendo configurado. A lista completa de países compatíveis e seu código de país está disponível na página Cobertura do país. |
language | Define o idioma a ser usado nos formulários de pagamento. Você pode defini-lo como uma das opções de idioma disponíveis:
|
viewController | Essa propriedade representa o UIViewController usado para apresentar o fluxo de pagamento. Embora a propriedade permaneça opcional para compatibilidade com versões anteriores, você deve fornecer um controlador visível para que o SDK possa apresentar sua IU corretamente. |
yunoCreatePayment(with token: String) | Esse método é responsável por criar um pagamento com o token fornecido. Ele recebe um parâmetro String chamado tokenque representa o token de pagamento. |
yunoCreatePayment(with token: String, information: [String: Any]) | Esse método é responsável por criar um pagamento com o token fornecido. Ele recebe um parâmetro String chamado tokenrepresentando o token de pagamento. Além disso, ele retorna todas as informações de resposta token em um dicionário. |
yunoPaymentResult(_ result: Yuno.Result) | Esse método é chamado quando o processo de pagamento é concluído, fornecendo o resultado do pagamento como um parâmetro do tipo Yuno.Result. |
Observação importanteVocê pode ligar para
yunoCreatePaymentcom ou sem oinformationde acordo com suas necessidades. No entanto, use apenas uma versão em seu código, pois chamar ambas não é necessário e pode causar problemas.
Requisitos de simultaneidade do Swift 6Se estiver usando o Swift 6, você precisará implementar o
YunoPaymentDelegatecom considerações específicas de simultaneidade. O Swift 6 apresenta requisitos mais rigorosos de segurança de thread que afetam a forma como você implementa os delegados. Consulte a seção ImplementaçãoYunoPaymentDelegatecom Swift 6 Concurrency para obter opções de implementação detalhadas e práticas recomendadas.
Etapa 4: Iniciar o processo de pagamento
Para iniciar efetivamente um pagamento após a exibição dos métodos de pagamento, você deve chamar o método startPaymentLiteconforme apresentado no trecho de código abaixo:
startPaymentLite(
com: YunoPaymentDelegate,
paymentSelected: PaymentMethodSelected,
showPaymentStatus: Bool
)Para a versão de checkout Lite, você precisa enviar um parâmetro adicional, que pode ser o token do cofre e/ou o método de pagamento que o cliente usará para fazer o pagamento.
protocol PaymentMethodSelected {
var vaultedToken: String? { get }
var paymentMethodType: String { get }
}
startPaymentLite(with: self, paymentSelected: paymentSelected)Etapa 5: obtenha o OTT ( token de uso único)
Você pode obter o token de uso único para criar o pagamento back-to-back no final desse processo. Você obterá o token de uso único na função yunoCreatePayment() que você obtém ao implementar o YunoPaymentDelegate. Um exemplo de recuperação do token de uso único é apresentado a seguir:
func yunoCreatePayment(with token: String) { ... }Passo 6: Criar o pagamento
Depois de concluir as etapas descritas anteriormente, você poderá criar um pagamento. A criação do pagamento back-to-back deve ser realizada usando o endpoint Create Payment. O comerciante deve chamar seu backend para criar o pagamento dentro do Yuno, usando o token de uso único e a sessão de checkout.
Continuar o métodoYuno requer você integra o
continuePaymentdo SDK depois que o pagamento for criado, porque determinados métodos de pagamento assíncronos exigem uma ação adicional do cliente para concluí-lo. A API informará você sobre esse cenário por meio da funçãosdk_action_requiredda resposta, que será retornado como verdadeiro. O campoyuno.continuePayment()exibirá as telas adicionais para os clientes, onde eles poderão executar as ações necessárias para concluir o pagamento sem precisar que você lide com cada cenário.
YunocontinuePayment()Etapa 7: Lidar com o status do pagamento (opcional)
Deep Links e Mercado Pago Checkout ProEssa etapa só é necessária se você estiver usando um método de pagamento que dependa de links diretos ou do Mercado Pago Checkout Pro. Se seus métodos de pagamento não usarem deep links, você pode pular esta etapa.
Alguns métodos de pagamento levam os usuários para fora do seu aplicativo para concluir a transação. Depois que o pagamento é concluído, o usuário é redirecionado de volta ao seu aplicativo usando um deep link. O SDK usa esse link direto para verificar o que aconteceu, verificando se o pagamento foi bem-sucedido, falhou ou foi cancelado, e pode mostrar uma tela de status para o usuário.
Para lidar com isso, você precisa atualizar seu AppDelegate para passar a URL de entrada de volta para o Yuno SDK. Isso permite que o SDK leia o resultado e, opcionalmente, exiba o status do pagamento. O trecho de código a seguir mostra como você pode adicioná-lo ao seu aplicativo:
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard url.scheme == "yunoexample" else { return false }
return Yuno.receiveDeeplink(url)
}Esse código escuta os links diretos que abrem seu aplicativo. Quando uma URL é recebida, ele verifica se o esquema corresponde ao que você usou na função callback_url durante a configuração da sessão de checkout. Se corresponder, a URL é passada para o Yuno SDK usando Yuno.receiveDeeplink(...). Em seguida, o SDK lê o resultado do pagamento e mostra a tela de status apropriada ao usuário.
Certifique-se de que o url.scheme nesse código corresponde ao callback_url que você forneceu ao criar o checkout_session.
Clique para pagarPara obter suporte ao Click to Pay, siga o guia de integração dedicado do Click to Pay SDK na seção Carteiras.
Retorno de chamada
O SDK retorna diferentes estados de transação após a conclusão do pagamento. A tabela a seguir descreve cada estado:
| Estado da transação | Descrição |
|---|---|
success | Indica que a transação ou o processo de payment foi concluído com êxito. |
fail | Esse estado indica que a transação ou o processo de pagamento falhou. Isso significa que houve um erro ou problema durante o processo de pagamento, impedindo que ele fosse concluído com êxito. |
processing | Indica que a transação ou o processo de pagamento está sendo processado no momento. Normalmente, é usado quando há um atraso no processamento do pagamento, como a espera de aprovação de um serviço de terceiros ou de uma instituição financeira. |
reject | Esse estado indica que a transação foi rejeitada. A rejeição pode ocorrer por vários motivos, como fundos insuficientes, atividade fraudulenta ou uma solicitação que viola regras ou políticas específicas. |
internalError | Significa que ocorreu um erro inesperado no sistema ou na infraestrutura que trata do processo de pagamento. Esse estado sugere que houve um problema no servidor ou no backend, e não um problema com a entrada ou a solicitação do usuário. |
userCancell | Esse estado indica que o usuário cancelou ou abortou voluntariamente a transação ou o processo de pagamento. Esse estado é normalmente usado quando há uma opção para o usuário cancelar ou abandonar o processo de pagamento. |
Validação do status do pagamento
Esta seção explica como o SDK lida com o status do pagamento quando os usuários cancelam ou abandonam os fluxos de pagamento e como o status do SDK se relaciona com o status do pagamento no back-end nesses cenários.
Sincronizar métodos de pagamento (Apple Pay)
Para métodos de pagamento síncronos, como o Apple Pay, quando um usuário cancela ou fecha a interface do usuário da carteira antes de receber a resposta do provedor de serviços de pagamento (PSP):
- Status do SDK: Devoluções
userCancell(CANCELLED) - Status do pagamento no backend: Restos mortais
PENDINGaté ao tempo limite do PSP ou ao cancelamento pelo comerciante - Importante: O SDK não retornará
rejectouprocessingnesse cenário
Isso garante que o pagamento no backend permaneça em estado pendente e possa ser tratado adequadamente pelo sistema do comerciante.
Formas de pagamento assíncronas (PIX e métodos baseados em QR)
Para métodos de pagamento assíncronos como o PIX, quando um usuário fecha a janela do código QR (clica em X) antes de concluir o pagamento:
- Status do SDK: Devoluções
PENDING, opcionalmente com um subestatuto, comoCLOSED_BY_USER - Status do pagamento no backend: Restos mortais
PENDINGe o código QR permanece válido até ao seu prazo de validade. - Reutilização da sessão de checkout: reabrir a mesma sessão de checkout pode exibir o mesmo código QR válido.
- Sem cancelamento automático: O pagamento PIX não é cancelado automaticamente quando o usuário fecha a janela do QR.
Esse comportamento permite que os usuários retornem ao fluxo de pagamento e concluam a transação usando o mesmo código QR antes que ele expire.
Pagamentos assíncronos expirados
Se um código QR PIX expirar naturalmente:
- Status do backendAtualizado para
EXPIRED - Status do SDK: endpoints de chamadas de retorno do SDK e endpoints de pesquisa
EXPIREDde forma consistente
Isso garante que os comerciantes recebam informações precisas sobre o status quando um método de pagamento expirar.
Implemente o delegado para receber os estados da transação:
enum Result {
case reject, success, fail, processing, internalError, userCancell
}
func yunoPaymentResult(_ result: Yuno.Result) { ... }
func yunoEnrollmentResult(_ result: Yuno.Result) { ... }Recursos complementares
O SDK do Yuno iOS oferece recursos adicionais para aprimorar a experiência do cliente. Use as personalizações do SDK para combinar com a aparência de sua marca ou configurar o carregador.
- Carregador: Controle o uso do carregador por meio das opções de configuração do SDK.
- Salvar o cartão para pagamentos futuros: Além disso, você pode exibir uma caixa de seleção para salvar ou registrar cartões usando
cardSaveEnable: true. Abaixo, você pode encontrar exemplos da caixa de seleção para ambas as renderizações do formulário de cartão.
- Você também pode escolher uma das opções de renderização para o formulário do cartão. Abaixo, você encontra capturas de tela que apresentam a diferença entre as opções de renderização
cardFormTypeONE_STEPeSTEP_BY_STEP.
- Personalizações do SDK: Altere a aparência do SDK para que corresponda à sua marca.
Integração do modo de renderização
O modo de renderização no Yuno SDK oferece maior flexibilidade de interface do usuário, permitindo que os desenvolvedores integrem fluxos de pagamento com controle total sobre a interface do usuário, mantendo a funcionalidade full SDK . Esse modo fornece visualizações SwiftUI que podem ser incorporadas perfeitamente à sua interface de usuário existente.
Função principal: startPaymentRenderFlow
startPaymentRenderFlowO startPaymentRender é um recurso do Yuno SDK que permite que os comerciantes integrem o processo de pagamento de forma mais detalhada e personalizável. Essa função concede controle total sobre quando e como os formulários de pagamento são exibidos, facilitando uma integração mais suave com a UI do aplicativo existente do comerciante.
Finalidade
Essa função foi projetada para oferecer maior controle sobre o fluxo de pagamento, permitindo que os comerciantes:
- Integrar formulários de pagamento de forma personalizada em sua própria interface de usuário.
- Controle com precisão quando os formulários de dados de pagamento são exibidos.
- Obtenha controle detalhado sobre o processo de confirmação de pagamento.
- Proporcionar uma experiência de usuário mais fluida e consistente no aplicativo do comerciante.
Sintaxe
A seção de sintaxe fornece a assinatura do método para o startPaymentRender função. Essa função é fundamental para integrar o processo de pagamento em seu aplicativo, oferecendo uma abordagem personalizável e detalhada para lidar com formulários e fluxos de pagamento.
@MainActor static func startPaymentRenderFlow(
paymentMethodSelected: PaymentMethodSelected,
with delegate: YunoPaymentDelegate
) async -> some YunoPaymentRenderFlowProtocolParâmetros
O startPaymentRender requer parâmetros específicos para operar com eficácia. Esses parâmetros são essenciais para definir o método de pagamento e lidar com as respostas do processo de pagamento.
| Parâmetro | Tipo | Descrição |
|---|---|---|
paymentMethodSelected | PaymentMethodSelected | O método de pagamento selecionado pelo usuário. Deve incluir o vaultedToken (se houver) e o paymentMethodType |
delegate | YunoPaymentDelegate | O delegado que tratará das respostas do processo de pagamento, incluindo a criação token e o resultado final |
Valor de retorno
Retorna uma instância que está em conformidade com YunoPaymentRenderFlowProtocolque fornece métodos para lidar com o fluxo de renderização de pagamentos.
Protocolo YunoPaymentRenderFlowProtocol
A instância retornada por startPaymentRender está em conformidade com esse protocolo, que inclui os seguintes métodos:
formView(paymentMethodSelected:with:)
func formView(
paymentMethodSelected: PaymentMethodSelected,
with delegate: YunoPaymentDelegate
) async -> AnyView?- Finalidade: Obtém a visualização do formulário para capturar dados de pagamento
- Comportamento:
- Se o método de pagamento exigir a exibição de um formulário, retorna um
AnyViewcom a forma correspondente - Se o método de pagamento não precisar mostrar nenhum formulário (por exemplo, métodos já configurados), retorna
nil
- Se o método de pagamento exigir a exibição de um formulário, retorna um
- Quando usar: Chame imediatamente após criar a instância do fluxo de pagamento
submitForm()
func submitForm()- Finalidade: Enviar dados de formulário para validação
- Comportamento: Executa todas as validações necessárias e, se for bem-sucedido, continua a gerar um novo token de uso único
- Quando usar: Quando o usuário executa a ação "pagar" no aplicativo do comerciante
continuePayment()
func continuePayment() async -> AnyView?- Finalidade: Continua o processo de pagamento após a geração do token de uso único
- Comportamento:
i. Se for necessário mostrar qualquer exibição adicional (por exemplo, autenticação 3DS), retorna um
AnyViewii. Se nenhuma visualização adicional for necessária, retornanil - Quando usar: Após receber o token de uso único por meio do delegado e criar o pagamento
Fluxo de implementação
Esta seção descreve a sequência de etapas necessárias para implementar o processo de renderização de pagamento usando o Yuno SDK.
Etapa 1: Configuração inicial
Para começar a usar startPaymentRenderVerifique se o SDK foi inicializado corretamente e se você possui um checkoutSession. Siga as etapas abaixo para configurar seu ambiente:
await Yunoinitialize(apiKey: "your_api_key")Etapa 2: Criar instância de fluxo de pagamento
Crie uma instância de fluxo de pagamento para gerenciar e renderizar o processo de pagamento usando o método selecionado.
let paymentFlow = await Yuno.startPaymentRenderFlow(
paymentMethodSelected: selectedPaymentMethod,
with: self
)Etapa 3: Obter e exibir o formulário
Recupere e apresente o formulário de pagamento para coletar informações de pagamento do usuário de forma 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()
}Etapa 4: Manipular o token de uso único
Implemente o método delegado para receber o 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()
}
}
}Exemplo 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 comuns
Esta seção descreve cenários típicos em que o Yuno SDK pode ser utilizado para lidar com vários métodos de pagamento, proporcionando flexibilidade e facilidade de integração.
1. Pagamento com cartão de crédito
Neste caso de uso, demonstramos como processar pagamentos usando novas informações de cartão de crédito, exigindo que o usuário preencha um formulário para capturar os detalhes necessários do cartão.
let cardPayment = CardPaymentMethodpaymentMethodType: "CARD")
let flow = Yuno.startPaymentRender(paymentMethodSelected: cardPayment, with: delegate)
let form = await flow.formView(paymentMethodSelected: cardPayment, with: delegate)2. Pagamento com método salvo
Esse cenário demonstra o uso de um método de pagamento salvo, permitindo que os usuários paguem sem reinserir os detalhes, utilizando um token protegido.
let savedCard = SavedCardPayment(
paymentMethodType: "CARD",
vaultedToken: "saved_token_123"
)
let flow = Yuno.startPaymentRender(paymentMethodSelected: savedCard, with: delegate)
let form = await flow.formView(paymentMethodSelected: savedCard, with: delegate)3. Pagamento com autenticação 3DS
O 3D Secure (3DS) adiciona uma etapa extra de verificação para aumentar a segurança. O SDK da Yuno integra esse processo em seu fluxo de pagamento sem problemas.
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)
}
}
}
}
}Considerações importantes
Esta seção destaca os principais pontos para integrar o SDK da Yuno de forma eficaz, garantindo um processo de pagamento seguro e sem interrupções.
Pré-requisitos
- Certifique-se de que o SDK esteja inicializado antes de usar
startPaymentRender - O delegado deve implementar todos os métodos necessários de
YunoPaymentDelegate - O
checkoutSessiondeve ser válido e ativo
Gerenciamento do estado
- Sempre verifique se
formView()retornosnilantes de exibir a exibição - Tratar adequadamente o caso em que
continuePayment()retornosnil - Implementar estados de carregamento durante operações assíncronas
Segurança
- Nunca armazene tokens de uso único - use-os imediatamente
- Sempre valide os resultados do pagamento em seu backend
- Implementar tempos limite apropriados para operações de rede
Desempenho
- Chamadas para
formView()econtinuePayment()são assíncronos - Considere mostrar indicadores de carga durante essas operações
- Reutilizar a instância do fluxo de pagamento quando possível
Solução de problemas
Esta seção oferece soluções rápidas para problemas comuns encontrados durante a integração do Yuno SDK, garantindo um processo de pagamento mais tranquilo.
Problemas comuns
-
formView()sempre retornanil- Verifique se o método de pagamento selecionado requer um formulário
- Verifique se o SDK foi inicializado corretamente
-
O delegado não recebe
yunoCreatePayment- Verifique se
submitForm()está sendo chamado corretamente - Confirmar que o formulário tem dados válidos
- Verifique se
-
continuePayment()não retorna a exibição quando esperado- Alguns métodos de pagamento não exigem visualizações adicionais
- Verifique a configuração do método de pagamento em seu painel do Yuno
Logs de depuração
Yuno.config.environment = .stagingMigração de outros métodos
Se você estiver migrando de startPayment() ou startPaymentLite():
Yuno.startPayment()
let flow = Yuno.startPaymentRender(paymentMethodSelected: method, with: delegate)
let form = await flow.formView(paymentMethodSelected: method, with: delegate)A principal vantagem de usar o novo método é o controle detalhado que ele oferece sobre a interface do usuário e o processo de pagamento.
Aplicativo de demonstraçãoAlém dos exemplos de código fornecidos, você pode acessar o repositório Yuno para obter uma implementação completa dos SDKs do Yuno para iOS.
Implementação YunoPaymentDelegate com Swift 6 Concurrency
YunoPaymentDelegate com Swift 6 ConcurrencyO Swift 6 apresenta requisitos de simultaneidade mais rígidos que afetam a forma como você implementa o YunoPaymentDelegate protocolo. Esta seção explica os desafios e oferece soluções para diferentes cenários de implementação.
Entendendo a simultaneidade no Swift 6A simultaneidade é a capacidade do seu aplicativo de gerenciar várias tarefas simultaneamente. Com o Swift 6, as regras de simultaneidade se tornaram mais rigorosas para aumentar a estabilidade do aplicativo e evitar falhas. Isso significa que seu código deve ser estruturado com mais cuidado para garantir a segurança dos threads e o gerenciamento adequado das tarefas.
O problema
Com o Swift 6, os protocolos que herdam do Sendable exigem que todas as suas implementações sejam thread-safe. Isso gera avisos ao implementar o delegado em classes marcadas como @MainActor.
Thread-safe significa que seu código pode ser chamado com segurança de vários threads sem causar falhas ou comportamento inesperado. @MainActor garante que o código seja executado no thread principal (thread da interface do usuário).
Nossa decisão de design
Não marcamos protocolos como @MainActor porque:
- Isso forçaria todas as implementações a serem
MainActor-compatível - Isso reduziria a flexibilidade para os comerciantes que não usam
MainActor - Cada implementação tem necessidades de simultaneidade diferentes
Responsabilidade do comerciante
É responsabilidade do comerciante lidar com a simultaneidade de acordo com sua implementação. Abaixo estão três abordagens diferentes que você pode usar, dependendo de suas necessidades específicas.
Opção 1: Propriedades imutáveis
Essa abordagem usa propriedades imutáveis que são automaticamente thread-safe, o que as torna ideais para configurações simples. Ela é mais adequada para aplicativos simples com valores de configuração fixos que não mudam durante o tempo de execução.
@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
}
}
}Opção 2: Propriedades mutáveis com MainActor.assumeIsolated
MainActor.assumeIsolatedEssa abordagem, melhor para aplicativos em que os valores de configuração podem ser alterados durante o tempo de execução (como as preferências do usuário), permite propriedades mutáveis e, ao mesmo tempo, mantém a segurança do thread usando 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 }
}
}Opção 3: Para nãoMainActor aulas
MainActor aulasEssa abordagem é adequada para classes de serviço que não requerem MainActor o que o torna melhor para serviços em segundo plano ou classes utilitárias que não interagem com a interface do usuário.
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) {
}
}⚠️ Considerações importantes
Ao implementar a simultaneidade em seu delegado, tenha em mente estes pontos-chave:
MainActor.assumeIsolated: Use apenas quando você garantir que ele seja chamado deMainActor. Esse é um mecanismo de segurança que diz ao Swift "confie em mim, eu sei que isso está sendo executado no thread principal".nonisolated: Significa que pode ser acessado de qualquer thread, portanto, deve ser thread-safe. Use-o quando suas propriedades ou métodos não dependerem do estado da interface do usuário.viewController: Permanece como@MainActorporque ele deve ser sempre acessado pelo thread principal. Os componentes da interface do usuário devem sempre ser executados no thread principal para evitar falhas.
Atualizado há 27 dias