Headless SDK (pagamento iOS)


👍

SDK recomendado

Recomendamos 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.

O SDK Headless iOS da Yuno permite criar pagamentos e registrar métodos de pagamento simultaneamente. Observe que, ao usar o Headless SDK, você precisará solicitar e enviar via API todos os campos obrigatórios que o provedor de pagamento exige para gerar o pagamento em sua API.

O Headless SDK da Yuno permite que você crie pagamentos em dois cenários diferentes:

  • Crie um Token de uso único usando informações de cartão de crédito ou métodos de pagamento alternativos e, em seguida, crie um pagamento.
  • Criar um Token de uso único usando um vaulted_token de um método de pagamento registrado anteriormente para coletar informações relevantes para provedores de fraude e, em seguida, criar um pagamento.

As etapas a seguir descrevem a criação de um pagamento usando o Headless SDK da Yuno.

Etapa 1: Inclua a biblioteca em seu projeto

A primeira etapa é instalar o Yuno SDK em seu projeto iOS.

📘

Verifique as versões do SDK do iOS

Para ver todas as versões disponíveis, visite a página de lançamento no repositório do SDK do Yuno iOS.

Você pode instalar o Yuno SDK de duas maneiras:

  • Cocoápodes: Se você não tiver um Podfile, siga as instruções CocoaPods para criar um. Depois de criar o Podfile, você integrará o Yuno SDK ao Cocoapods adicionando a linha abaixo ao seu Podfile:
    pod 'YunoSDK', '~> {last_version}'
  • Gerenciador de pacotes Swift: Configure o pacote Swift e adicione o Yuno SDK como uma dependência, conforme apresentado no bloco de código a seguir:
    dependencies: [
        .package(url: "https://github.com/yuno-payments/yuno-sdk-ios.git", .upToNextMajor(from: "{last_version}"))
    ]

Etapa 2: Initialize Headless SDK com a chave pública

Para initialize o Headless SDK, você precisa importar o Yuno e fornecer uma chave PUBLIC_API_KEY. Se você não tiver suas credenciais de API, acesse a página Developers (Credentials) para verificar como recuperá-las no painel.

🚧

Inicialização do UISceneDelegate

Se o seu aplicativo estiver usando um UISceneDelegatecertifique-se de colocar seu código de inicialização do Yuno em seu arquivo SceneDelegate. Saiba mais

O bloco de código abaixo apresenta um exemplo de importação e inicialização do Yuno.

importar YunoSDK

Yunoinitialize(
    apiKey:PUBLIC_API_KEY"
)

Etapa 3: Inicie o processo de checkout

Em seguida, você iniciará o processo de checkout usando o apiClientPayment fornecendo os parâmetros de configuração necessários. Você precisa chamar essa função quando o cliente selecionar o método de pagamento. Como resultado, o SDK começará a coletar informações relevantes para o 3DS e as ferramentas de prevenção de fraudes que você configurou em seu roteamento.

Parâmetros

A tabela a seguir lista todos os parâmetros necessários e suas descrições.

ParâmetroDescrição
countryCodeEsse 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 seus respectivos countryCode está disponível no site Cobertura do país página.
checkout_sessionRefere-se à sessão de checkout do pagamento atual criada usando o endpoint Criar sessão de checkout. Example: '438413b7-4921-41e4-b8f3-28a5a0141638'

O bloco de código a seguir apresenta um exemplo de configuração de parâmetros.

var apiClientPayment: YunoPaymentHeadless?

apiClientPayment = Yuno.apiClientPayment(
   countryCode: "CO",
   checkoutSession: "438413b7-4921-41e4-b8f3-28a5a0141638"
)

Etapa 4: Gerar token

Depois de coletar todas as informações do usuário, você pode iniciar o pagamento. Primeiro, você precisa criar um token de uso único (OTT) usando a função apiClientPayment.generateToken. Como se trata de uma função assíncrona, você pode usar do/catch para garantir que você tratará corretamente os erros acionados. Abaixo, você encontrará dois exemplos de cenários diferentes para criar um token de uso único:

  1. Exemplo 1: Crie um token de uso único utilizando um cartão como método de pagamento e incluindo todas as informações necessárias sobre o cartão.
  2. Exemplo 2: Crie um token de uso único usando o vaulted_token informações.
👍

Vantagens de usar um Token abobadado

A utilização de um token abobadado com o SDK garante que todas as informações sobre fraudes de seus provedores configurados sejam coletadas e anexadas ao token de uso único. Além disso, você pode incluir detalhes de parcelamento e um código de segurança, se exigido pelo provedor.

deixe tokenCollectedData: TokenCollectedData = TokenCollectedData(
   checkoutSession: "438413b7-4921-41e4-b8f3-28a5a0141638",
    paymentMethod: CollectedData(
        type: "CARD",
       vaultedToken: nil,
        card: CardData(
            save: true,
            detail: CardData.Detail(
                number: "4111111111111111",
                expirationMonth: 12,
                expirationYear: 25,
                securityCode: "123",
                holderName: "Andrea",
                type: .credit
            ),
            installment: CardData.Installment(
                id: "64ceacef-0886-4c81-9779-b2b3029c4e8b",
                value: 1
            )
        ),
        customer: Customer()
    )
)

let result = try await apiClientPayment.generateToken(
    data: tokenCollectedData
)
deixe tokenCollectedData: TokenCollectedData = TokenCollectedData(
   checkoutSession: "438413b7-4921-41e4-b8f3-28a5a0141638",
    paymentMethod: CollectedData(
        type: "CARD",
       vaultedToken: "c8bb2bd8-8abf-4265-b478-0ec4e3c10cd5",
        card: CardData(
            installment: CardData.Installment(
                id: "64ceacef-0886-4c81-9779-b2b3029c4e8b",
                value: 1
            )
        ),
        customer: Customer()
    )
)

let result = try await apiClientPayment.generateToken(
    data: tokenCollectedData
)

O bloco de código a seguir apresenta o apiClientPayment.generateToken para os dois exemplos acima. A resposta é um dicionário do tipo [String: Any].

 [token": "9ee44ac7-9134-4598-ae28-a26fec03099d",
     "type": "CARD",
     "customer": ["billing_address": nil,
                  "first_name": nil,
                  "gender": "",
                  "phone": nil,
                  "browser_info": ["color_depth": nil,
                                   "language": "en",
                                   "accept_header": "*/*",
                                   "browser_time_difference": nil,
                                   "accept_content": nil,
                                   "accept_browser": nil,
                                   "java_enabled": nil,
                                   "user_agent": "YunoSDK_Example/1 CFNetwork/1406.0.4 Darwin/22.6.0",
                                   "screen_height": "844.0",
                                   "screen_width" (largura da tela): "390.0",
                                   "javascript_enabled": nil],
                  "document": nil,
                  "last_name": nil,
                  "device_fingerprint": nil,
                 email": nil],
     "country" (país): "BR",
     "vaulted_token": nil,
     "installment": ["rate": "",
                     "id": "cca80084-961b-4212-9c34-54f03f4f10ae",
                     "value": 24,
                     "amount": nil],
     "card_data": nil]
[token": "9ee44ac7-9134-4598-ae28-a26fec03099d",
     "type": "CARD",
     "customer": ["billing_address": nil,
                  "first_name": nil,
                  "gender": "",
                  "phone": nil,
                  "browser_info": ["color_depth": nil,
                                   "language": "en",
                                   "accept_header": "*/*",
                                   "browser_time_difference": nil,
                                   "accept_content": nil,
                                   "accept_browser": nil,
                                   "java_enabled": nil,
                                   "user_agent": "YunoSDK_Example/1 CFNetwork/1406.0.4 Darwin/22.6.0",
                                   "screen_height": "844.0",
                                   "screen_width" (largura da tela): "390.0",
                                   "javascript_enabled": nil],
                  "document": nil,
                  "last_name": nil,
                  "device_fingerprint": nil,
                 email": nil],
     "country" (país): "BR",
     "vaulted_token": "a1c7c5d1-b260-4dc6-909a-8368704233cf",
     "installment": ["rate": "",
                     "id": "cca80084-961b-4212-9c34-54f03f4f10ae",
                     "value": 24,
                     "amount": nil],
     "card_data": nil]

Etapa 5: 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.

endpoint inclui o sdk_action_required que indica se são necessárias ações adicionais para concluir o pagamento:

Para métodos de pagamento síncronos, o pagamento é concluído instantaneamente. Nesse caso, sdk_action_required será falso na resposta da API e o processo de pagamento será encerrado. Se o pagamento exigir mais interação do SDK para concluir o fluxo, sdk_action_required será verdadeiro; nesse caso, prossiga com a Etapa 6 para obter instruções.

Etapa 6: Processar pagamentos assíncronos (opcional)

Um pagamento com 3DS pode exigir um desafio adicional para verificar a identidade do cliente, conforme descrito na página Verificação de cartão 3DS. Se for necessário um desafio de verificação 3DS, a resposta endpoint Criar pagamento conterá:

  • Status igual a PENDING e sub status igual a WAITING_ADDITIONAL_STEP
  • sdk_action_required = true
  • A redirect_url definido em payment.payment_method.payment_method_detail.card

Para realizar o desafio e concluir o pagamento, você tem duas opções de integração:

Obter o URL do desafio 3DS

Para obter o URL do desafio 3DS, você precisa ligar para o getThreeDSecureChallenge fornecendo a função checkoutSession. O checkoutSession só é necessário se você não estiver usando o que foi usado para criar o pagamento. Abaixo, você encontrará um exemplo de uso da opção getThreeDSecureChallenge função. Como getThreeDSecureChallenge é uma função assíncrona, você pode usar do/catch para garantir que você tratará corretamente os erros acionados.

func getThreeDSecureChallengecheckoutSession: String?) async throws -> ThreeDSecureChallengeResponse

O getThreeDSecureChallenge retornará a função ThreeDSecureChallengeResponseapresentado no próximo bloco de código:

public struct ThreeDSecureChallengeResponse {
    public let url: String
}

O url conterá um URL válido que você precisa para redirecionar seu cliente para concluir o desafio.

Você é responsável por redirecionar seus clientes para a URL fornecida pelo getThreeDSecureChallenge() para concluir o desafio. Quando o cliente concluir com êxito o desafio 3DS, ele será automaticamente redirecionado para a página callback_urlque você forneceu ao criar o checkout_session com o Criar sessão de checkout endpoint.

Para confirmar que o desafio foi concluído, você pode abrir uma visualização da Web para carregar a URL fornecida e ouvir a mensagem messageFromWeb evento. Abaixo está um exemplo de código que demonstra como ouvir esse evento.

class HeadlessWebView: UIViewController, WKScriptMessageHandler, WKNavigationDelegate {

    private var webView: WKWebView!
    private var url: String = ""
    private let configuration = WKWebViewConfiguration()

    init(url: String) {
        self.url = url
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        webViewConfig()
    }

    func webViewConfig() {
   
        configuration.preferences.javaScriptEnabled = true
        configuration.userContentController.add(self, name: "messageFromWeb")
        webView = WKWebView(frame: view.bounds, configuration: configuration)
        webView.navigationDelegate = self

        guard let url = URL(string: url) else {
            return
        }
        let request = URLRequest(url: url)
        webView.load(request)

    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "messageFromWeb", let messageBody = message.body as? String {
            self.dismiss(animated: true)

        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        self.configuration.userContentController.removeScriptMessageHandler(forName: "messageFromWeb")
    }

}

A resposta informará o status do desafio, que pode ser COMPLETED ou ERROR. O próximo bloco de código apresenta exemplos para cada opção possível.

{
   "origin":"CHALLENGE",
   "status":"COMPLETED",
   "data":"callback_url"
}
{
   "origin":"CHALLENGE",
   "status":"ERROR",
   "data":"Invalid 3DS provider"
}

Para concluir o fluxo de pagamento do Headless SDK , você precisa usar o Yuno Webhooks, que o notificará imediatamente sobre o resultado do desafio 3DS e o status final do pagamento. O uso de webhooks garante que você receba atualizações em tempo real sobre o andamento da transação de pagamento. Além dos webhooks, você pode recuperar as informações de pagamento usando o endpoint Retrieve Payment by ID.

Para concluir a implementação do pagamento e entender as etapas restantes, acesse Headless SDK (Payment).

Etapa 7: Manipular o status do pagamento (opcional)

🚧

Deep Links e Mercado Pago Checkout Pro

Essa 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, showStatusView: true)
}

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(...). O SDK então lê o resultado do pagamento e, se showStatusView é definido como truemostra a tela de status apropriada para o usuário.

Certifique-se de que o url.scheme nesse código corresponde ao callback_url que você forneceu ao criar o checkout_session.

📘

Aplicativo de demonstração

Alé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.