4 - Erros de adquirente

Saiba como tratar o erro 6015 (transactionError) no callback onError do SDK Tap to Pay iOS, exibir a mensagem correta ao cliente e interpretar os dados da adquirente.


Regra obrigatória para o erro 6015

🚨

Obrigatório: quando o callback retornar .payment(PaymentErrorResponse) e paymentError.error.code for transactionError (6015), exiba para o cliente o valor de paymentError.error.description.

Não substitua esse conteúdo por message, code ou textos genéricos quando description estiver preenchido. Como description pode ser nil, valide esse campo e aplique uma mensagem de fallback antes de exibir o erro.


Tipos de erro no onError

O callback onError retorna response.sdkError, que pode ser um dos três casos abaixo:

CasoQuando esperarTipo retornado
.payment(PaymentErrorResponse)Pagamento negado ou falha após leitura do cartãoErro de pagamento com dados da transação, como transactionId, cardBrand e acquirerCode
.tapOnPhone(TapOnPhoneError)Erro de configuração, sessão, inicialização ou falha interna do SDKErro do SDK com code, message, source e outros metadados
.unknown(Any)Cenário não tipado ou inesperadoValor bruto para fallback e diagnóstico

Em fluxos de pagamento negado, sdkError costuma ser .payment(PaymentErrorResponse). Nesse cenário:

  • paymentError.error.code identifica o erro tipado do SDK.
  • paymentError.error.description traz o detalhe funcional da recusa.
  • paymentError.acquirerCode pode classificar a resposta da adquirente.

Tratamento recomendado com sdkError

onError: { response in
    switch response.sdkError {
    case .payment(let paymentError):
        let err = paymentError.error
        if err.code == .transactionError {
            let customerMessage = err.description ?? "Não foi possível concluir o pagamento. Tente novamente."
            // Obrigatório: exiba err.description para o cliente quando esse campo estiver preenchido.
            print("Mensagem para o cliente:", customerMessage)
        }

        print("Pagamento negado — id:", paymentError.transactionId ?? "desconhecido")
        print("sdkCode:", err.code.rawValue)
        print("sdkName:", err.code.description)
        print("message:", err.message)
        print("description:", err.description ?? "sem descrição")
        print("source:", err.source)
        print("readerIdentifier:", err.readerIdentifier ?? "sem readerIdentifier")
        print("timestamp:", err.timestamp)

        if let acquirer = paymentError.acquirerCode {
            print("acquirerCode:", acquirer)
        }

    case .tapOnPhone(let sdkError):
        print("Erro do SDK — code:", sdkError.code.rawValue)
        print("name:", sdkError.code.description)
        print("message:", sdkError.message)
        print("source:", sdkError.source)

    case .unknown(let underlying):
        print("Erro não tipado:", underlying)
    }
}

Como interpretar o 6015 no onError

Quando paymentError.error.code for transactionError, você está diante do erro 6015 da tabela de erros.

onError: { response in
    switch response.sdkError {
    case .payment(let paymentError):
        // objeto PaymentErrorResponse
        // paymentError.acquirerCode   → equivalente ao código 4023
        // paymentError.error.description → equivalente a "TSENHA INVALIDA"
        // paymentError.error.code        → equivalente ao 6015

        print(paymentError.error.code)
        print(paymentError.error.message)
        print(paymentError.error.description ?? "sem descrição")
        print(paymentError.acquirerCode ?? "sem acquirerCode")

    case .tapOnPhone(let sdkError):
        print(sdkError.code)
        print(sdkError.message)
        print(sdkError.description ?? "sem descrição")

    case .unknown(let underlying):
        print(underlying)
    }
}

Ordem de diagnóstico do 6015

Ao diagnosticar o 6015, siga esta ordem:

  1. Leia paymentError.error.description para identificar o detalhe principal da recusa.
  2. Exiba obrigatoriamente paymentError.error.description para o cliente quando o erro vier em .payment(PaymentErrorResponse).
  3. Se paymentError.error.description vier nil, exiba uma mensagem de fallback apropriada para o cliente.
  4. Consulte paymentError.acquirerCode para classificar a resposta da adquirente.
  5. Registre paymentError.transactionId, paymentError.error.readerIdentifier e paymentError.error.timestamp para apoiar o diagnóstico.

Exemplo real de 6015 com acquirerCode

O bloco abaixo reproduz um retorno real do SDK quando o erro 6015 é acompanhado de um acquirerCode:

paymentError.error: TapOnPhoneError(code: TapOnPhoneSDK.TapOnPhoneErrorCode.transactionError, source: TapOnPhoneSDK.TapOnPhoneErrorSource.sdk, message: "The payment transaction failed.", description: Optional("TMCC Invalido"), readerIdentifier: Optional("f9f3d66af843f2ad7c2aaebb5e40120de32906b8c4f302ee074e556b5b1fbb68"), timestamp: 1777324799.3312612)
paymentError.error.code: transactionError
paymentError.error.description: TMCC Invalido
paymentError.error.message: The payment transaction failed.
paymentError.error.readerIdentifier: f9f3d66af843f2ad7c2aaebb5e40120de32906b8c4f302ee074e556b5b1fbb68
paymentError.error.timestamp: 1777324799.3312612
paymentError.acquirerCode: 4058
paymentError.binNumber: 516292
paymentError.transactionId: 04f93c9c88f546eab767d9d33c188fb5
paymentError.cardBrand: MASTERCARD
paymentError.paymentDevice: UNKNOWN
paymentError.localizedDescription: A operação não pôde ser concluída. (TapOnPhoneSDK.PaymentErrorResponse erro 1.)

Interpretação do exemplo

CampoValorSignificado
paymentError.error.codetransactionErrorIdentifica o erro tipado do SDK como 6015
paymentError.error.descriptionTMCC InvalidoDetalhe principal da recusa — exiba ao cliente
paymentError.acquirerCode4058Classifica a recusa na adquirente
paymentError.transactionId04f93c9c...Correlaciona a tentativa nos logs e sistemas de backend
paymentError.cardBrandMASTERCARDBandeira do cartão utilizado
paymentError.binNumber516292BIN do cartão para apoio ao diagnóstico

Prioridade dos campos para tratamento

Ao tratar o cenário 6015, priorize os campos nesta ordem:

  1. paymentError.error.description — detalhe funcional da recusa
  2. paymentError.acquirerCode — classificador da adquirente
  3. paymentError.transactionId — correlação nos logs
  4. paymentError.error.readerIdentifier — identificação do leitor
  5. paymentError.error.timestamp — momento da falha

Precisa de ajuda?

Se o erro persistir após seguir as orientações acima, entre em contato com o suporte Zoop:

📞 Telefone (segunda a sexta, 9h às 19h)

  • Capitais: 4003-3261
  • Demais regiões: 0800 878 8161

✉️ E-mail

[email protected]