3.2.1


Aviso

Essa versão contém diversas breaking changes, conforme descrito nas notas de versão abaixo.

Link para download do xcframework para adição manual do sdk

Release Notes

Principais alterações

  • Métodos expostos pelo SDK: setConfig, initialize, pay, processOnboarding, activateSession

  • Fluxo interno: Simplificado, sem necessidade de vincular conta ou iniciar sessão manualmente.

  • Correção de erros: Leitura de cartão (ex: Cartão expirado).

  • Comportamento: Mais conciso em leituras sem sucesso.

  • Callbacks: onSuccess, onError e onEvent.

  • Notificação de eventos: Tela do SDK/Apple visível, leitor pronto, cartão lido, etc. Podendo ser verificado aqui.

  • Suporte a bandeira ELO: Agora com suporte à ELO.

  • Animação da bandeira:

    • Animação Visa agora é gerenciada internamente pelo SDK.
    • Adicionada animação ELO.
    • Corrigido animação Visa em casos que não era exibida.
  • Onboarding: Foi disponibilizado um novo método chamado processOnboarding que processa o onboarding Apple, ensinando a usar o pagamento Tap to Pay, conforme detalhado aqui.

  • Nova tela do SDK:

    • Esta tela apresenta o estado da inicialização e pagamento baseado nos eventos do sdk
    • Durante o pagamento, a tela da Apple é exibida acima desta tela, mas, caso a inserção de senha seja necessária, a tela do SDK vai manter o estado internamente .closeBuiltInScreen com a mensagem padrão “Processando”. (nesse momento o cliente não será notificado deste evento, só ao fim da tela da Zoop)
    • A tela é exibida automaticamente durante o processo de pagamento.
    • É removida ao final do processo, nos callbacks onSuccess e onError.
    • Essa tela é totalmente configurável, conforme descrito aqui

    Exemplo de tela

  • Inicialização automática: A função initialize agora é opcional. Se não for chamada manualmente, a inicialização será feita automaticamente durante o pagamento.

  • Criação de sessão: Agora é possível criar a sessão (opcionalmente) após o método initialize, caso não seja chamado, criaremos a sessão durante o pagamento.

Novos feedbacks de leitura de cartão

Se iOS > 18.4

TapOnPhoneError( 
    code: .expiredCard, // 6096 
    source: .apple, 
    message: "The card is expired.", 
    description: description, 
    readerIdentifier: Definitions.instance.currentReaderId, 
    timestamp: Double.getTimestamp() 
)
TapOnPhoneError( 
    code: .invalidCard, // 6097 
    source: .apple, 
    message: "The card is invalid.", 
    description: description, 
    readerIdentifier: Definitions.instance.currentReaderId, 
    timestamp: Double.getTimestamp() 
)

Se iOS < 18.4

TapOnPhoneError( 
    code: .paymentCardDeclined, //6062 
    source: .apple, 
    message: "The payment card declined the transaction.", 
    description: description, 
    readerIdentifier: Definitions.instance.currentReaderId, 
    timestamp: Double.getTimestamp() 
)

Comparativo do fluxo de inicialização

SDK Antigo

TapOnPhone.Initialize( 
    environment: environment, 
    logLevel: logLevel, 
    strictMode: strictMode, 
    credentials: credentials, 
    paymentType: .credit 
) { [weak self] event in 
    guard let self else { return } 
 
    if event.type == .error { 
        print("SDK start error: ", event.logMessage) 
    } else { 
        print("Success Initialize SDK") 
        self.linkAppleAccount() 
    } 
}
Linkar conta Apple e criar sessão
private func linkAppleAccount() { 
    TapOnPhone.isAppleAccountLinked { [weak self] linked in 
        if !linked { 
            TapOnPhone.linkAppleAccount { [weak self] event in 
                if event.type == .success || event.code == .appleAccountAlreadyLinked { 
                    self?.startingSession() 
                } 
            } 
        } else { 
            self?.startingSession() 
        } 
    } 
} 
 
private func startingSession() { 
    if !TapOnPhone.isSessionStarted() { 
        TapOnPhone.startSession( 
            refreshToken: false, 
            paymentType: .credit, 
            skipAccountLinkCheck: true 
        ) { [weak self] event in 
            if event.type == .error { 
                print("Session start error") 
            } else { 
                print("Success started successfully") 
            } 
        } 
    } 
}

Novo SDK

func initializeSDK() { 

    TapOnPhone.setConfig(
      configParameters: ConfigParameters(
        credentials: credentials,
        environment: environment,
        logLevel: logLevel,
        sdkConfig: sdkConfig
      )
    )
    TapOnPhone.initialize(
        onSuccess: { [weak self] in
            guard let self else { return }

            print("Success Initialize SDK!")
        },
        onError: { [weak self] error in
            guard let self else { return }
            let initError = error.error as! TapOnPhoneError
            
            print("SDK start error - code: ", initError.code.rawValue)
            print("name: ", initError.code.description)
            print("message: ", initError.message)
        },
        onEvent: { ApplicationEvent in
            print("ApplicationEvent: \(ApplicationEvent)")
        }
    )
}

Comparativo pagamento

SDK Antigo

TapOnPhone.readPaymentCard( 
    amount: Decimal(amount) / Decimal(100), 
    type: paymentType, 
    installments: installments, 
    clientMetadata: clientMetadata 
) { [weak self] event in 
    if event.code == .transactionSuccess { 
        print("Sucesso na transação") 
    } else { 
        print("Falha na transação") 
    } 
} 

Novo SDK

TapOnPhone.pay(
    payRequest: PaymentRequest(
        amount: 1000, // R$ 10,00
        paymentType: TapOnPhonePaymentType.credit,
        installments: 2,
        metadata: """
            {
                "clientId": "1234",
                "name": "John Doe"        
            }
        """
    ),
    onSuccess: { [weak self] result in
        guard let self else { return }

        print("Payment approved! id: \(result.transactionId)")
    },
    onError: { [weak self] transactionError in
        guard let self else { return }
        
        if transactionError.type == .payment {
          let error = transactionError.error as! PaymentErrorResponse
          print("Payment denied - id: ", error.transactionId ?? "unknown")
          print("code: ", error.error.code.rawValue)
          print("name: ", error.error.code.description)
          print("message: ", error.error.message)
        } else {
          error.error as! TapOnPhoneError
          print("SDK start error - code: ", error.code.rawValue)
          print("name: ", error.code.description)
          print("message: ", error.message)
        }
    },
    onEvent: { ApplicationEvent in
        print("ApplicationEvent: \(ApplicationEvent)")
    }
)
Estruturas do pagamento
// Pagamento de sucesso
public struct PaymentApprovedResponse { 
    let transactionId: String 
    let cardBrand: String 
    let readerIdentifier: String? 
    let readResultId: String 
}

// PaymentErrorResponse
public struct PaymentErrorResponse: Error { 
    let error: TapOnPhoneError 
    let transactionId: String? 
    let cardBrand: String? 
    let readResultId: String? 
}

Eventos

Os eventos são emitidos durante todas as requisições do SDK, garantindo total informação sobre os fluxos, conforme descrito a seguir:

Maiores detalhes aqui

public enum ApplicationEvent: Hashable {
    // Tela
    case launchBuiltInScreen // Tela nativa do SDK apareceu
    case closeBuiltInScreen // Tela nativa do SDK desapareceu
    
    // Ativação
    case terminalActivationStarted // Começou o processo de ativação (contempla o fluxo completo, ativação zoop e ativação apple)
    case terminalActivationFinished // Finalizou o processo de ativação (contempla o fluxo completo, ativação zoop e ativação apple)
    
    case zoopActivationStarted // Começou o fluxo de ativação na Zoop
    case zoopActivationSucceeded // Ativação na Zoop realizada com sucesso
    case zoopActivationFailed // Ativação na Zoop falhou
    
    case kernelActivationStarted // Criando o leitor do cartão na Apple
    case kernelActivationSucceeded // Leitor Apple criado com sucesso
    case kernelActivationFailed // Falha na criação do leitor Apple

    case sessionActivationStarted // Criação da sessão do pagamento iniciada
    case sessionActivationSucceeded // Sessão criada com sucesso
    case sessionActivationFailed // Falha na criação da sessão
    case sessionActivationRetry // Retentativa de criação de sessão
    
    // Processo do pagamento
    case paymentProcessStarted // Processo do pagamento iniciado
    case paymentProcessFinished // Processo do pagamento finalizado
    case paymentProcessSucceeded // Sucesso no pagamento
    case paymentProcessFailed // Falha no pagamento
    case paymentConfirmationStarted // Criando confirmação do pagamento
    case paymentConfirmationSucceeded // Pagamento confirmado
    case paymentConfirmationFailed // Falha na confirmação do pagamento
    
    // Eventos do pagamento
    
    case cardReadingStarted // Iniciando a leitura do cartão
    case cardReadingRetry // Retentativa da leitura do cartão
    case cardReadingFinished // Leitura do cartão finalizada
    case pinInputStarted // Inicio da captura de pin
    case pinInputFinished // Captura de pin finalizada
    case authorizingPleaseWait // Enviando autorização
    case holdCardSteady // Manter o cartão aproximado
    case transactionAborted // Operação cancelada

}