Fluxo de uso da biblioteca

O Zoop Android SDK facilita a adição de pagamentos de cartão de crédito/débito/voucher ao seu aplicativo para dispositivos móveis. Esta biblioteca nativa para Android permite que você colete informações de cartão sem ter que lidar com dados sensíveis que passam por seus servidores.

Para inicializar o SDK é preciso apenas chamar o método:

ZoopAPI.initialize(<ApplicationContext>)

Implementando métodos para seleção de maquininha



Interface DeviceSelectionListener

Implemente a interface DeviceSelectionListener para receber notificações quando a maquininha for encontrada.

A interface possui 4 métodos. Todos serão explicados com mais detalhes nas seguintes linhas:

  • Esse método trás um vetor de todas as maquininhas já encontradas no formato JSON.
void showDeviceListForUserSelection(Vector<JSONObject> var1)
  • Esse método trás um JSONObject representando uma nova maquininha encontrada.
void updateDeviceListForUserSelection(JSONObject var1, Vector<JSONObject> var2, int var3)
{
  /* Nome da maquininha (String) */
  "name": "MP 5-42259466",
  /* 'btspp://' + Número serial da maquininha (String) */
  "uri": "btspp://C8:DF:84:1C:5B:46",
  /* Sempre 'Bluetooth' (String) */
  "communication": "Bluetooth",
  /* Sempre 'true' (Boolean) */
  "persistent": true,
  /* Última data de detecção da maquininha (String) */
  "dateTimeDetected": "6 de abr de 2020 11:27:50",
  /* Fabricante da maquininha (String) */
  "manufacturer": "PAX",
   /**
   * Tipo do terminal (Integer) 
   * 0 - Compatível; 
   * 1 - Parcialmente Compatível; 
   * 2 - Incompatível; 
   * 3 - Desconhecido 
   */
  "typeTerminal": 3 
}

❗️

Atenção

Para mais informações a respeito do campo "typeTerminal" ver a seção API de compatibilidade mPOS

  • Esse método é um callback que verifica se o Bluetooth está habilitado em seu dispositivo móvel.
void bluetoothIsNotEnabledNotification()
  • Esse método trás o JSONObject da maquininha selecionada.
void deviceSelectedResult(JSONObject var1, Vector<JSONObject> var2, int var3)

Para ajudar a implementar os métodos dessa interface em sua "Activity" é preciso utilizar os métodos expostos pela classe "TerminalListManager".

Classe TerminalListManager

Para iniciar a procura por uma maquininha deve-se chamar o método "void startTerminalsDiscovery()". Uma boa prática é colocar esse método na "onCreate()" da sua Activity. Caso seja encontrada alguma maquininha, ela virá no callback "showDeviceListForUserSelection" ou "updateDeviceListForUserSelection". Para selecionar a maquininha que irá transacionar é só utilizar o método "void requestZoopDeviceSelection(JSONObject var)" passando o JSON da maquininha selecionada. Caso queira terminar o processo de procura de maquininhas deve-se chamar o método "void finishTerminalDiscovery()".

A seguir, um exemplo de código:

public class ConfigPinPadActivity extends Activity implements DeviceSelectionListener {

  TerminalListManager terminalListManager;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_config_pinpad);
    terminalListManager = new TerminalListManager(this,getApplicationContext());
    terminalListManager.startTerminalsDiscovery();
    initPermissionsListener();
  }
  
  private void initPermissionsListener() {
    MultiplePermissionsListener dialogMultiplePermissionsListener =
      DialogOnAnyDeniedMultiplePermissionsListener.Builder
      .withContext(this)
      .withTitle("Permissão de localização")
      .withMessage("Precisamos da permissão para acessar os dados da conexão com a maquininha")
      .withButtonText(android.R.string.ok)
      .build();

    Dexter.withActivity(this)
      .withPermissions(android.Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
      .withListener(dialogMultiplePermissionsListener)
      .check();
  }

  @Override
  public void showDeviceListForUserSelection(final Vector<JSONObject>
  vectorZoopTerminals) {
    try {
      if (vectorZoopTerminals.size() > 0 {
        //dummy logic to always select the first device on the list 
     terminalListManager.requestZoopDeviceSelection(vectorZoopTerminals.get(0));
      }
    }
    catch (Exception e) {
      ZLog.exception(300064, e);
    }
  }

  @Override
  public void updateDeviceListForUserSelection(JSONObject joNewlyFoundZoopDevice,
  Vector<JSONObject> vectorZoopTerminals, int iNewlyFoundDeviceIndex) {
    try {
      //dummy logic to select the newly found device 
      terminalListManager.requestZoopDeviceSelection(joNewlyFoundZoopDevice);
    } catch (Exception e) {
      ZLog.exception(677541, e);
    }
  }

  @Override
  public void bluetoothIsNotEnabledNotification() {
    terminalListManager.enableDeviceBluetoothAdapter();
  }

  @Override
  public void deviceSelectedResult(JSONObject joZoopSelectedDevice, Vector<JSONObject>
  vectorAllAvailableZoopTerminals, int iSelectedDeviceIndex) {
    String namePinpad = joZoopSelectedDevice.getString("name")
  }

  @Override
  public void onDestroy() {
    terminalListManager.finishTerminalDiscovery();
    super.onDestroy();
  }          
          
}

Uma vez que já exista a lógica para selecionar uma maquininha implementada, poderá seguir para o próximo passo.

Implementando métodos para realizar uma transação



Interface TerminalPaymentListener

Implemente a interface "TerminalPaymentListener" para receber notificações de status, solicitações e resultados finais de carga/transação.

A interface possui 7 métodos. Todos serão explicados com mais detalhes nas seguintes linhas.

  • Esse método notifica sua aplicação de que uma carga/transação falhou. Dentre outras informações, podemos encontrar uma mensagem de erro amigável dentro do JSONObject.
void paymentFailed(JSONObject var1)
  • Esse método notifica sua aplicação de que uma carga/transação foi aprovada.
void paymentSuccessful(JSONObject var1)
  • Esse método notifica sua aplicação de que a carga solicitada foi abortada com sucesso após a solicitação do usuário.
void paymentAborted()
  • Esse método notifica sua aplicação que uma carga/transação é duplicada. Essa função deve ser solicitada previamente ao suporte. Para configurar o intervalo mínimo para a trava de duplicação.
void paymentDuplicated(JSONObject var1)
  • Esse método notifica sua aplicação de que é necessário capturar a assinatura do titular do cartão como prova para que a carga/transação seja aprovada. Atenção: Esta chamada não irá esperar por uma assinatura. O seu aplicativo deverá capturar a assinatura do usuário e posteriormente adicionar à transação.
void cardholderSignatureRequested()-Opcional
  • Esse método notifica sua aplicação se em determinando momento é permitido abortar uma carga/transação em andamento. Um exemplo prático seria usar esse método para habilitar e desabilitar um botão de abortar.
void currentChargeCanBeAbortedByUser(boolean var1)
  • Esse método é um callback que informa se a assinatura foi adicionada com sucesso no comprovante. Em caso de sucesso, seu parâmetro é igual a '0'.
void signatureResult(int var1) - Opciona

❗️

Quick disclaimer​

Cancelar uma transação de cartão de crédito depois de aprovada pode ter impacto na forma de como as processadoras de cartão classificam o risco de um vendedor. Então, uma vez que o pedido seja concluído - enviado para processamento - o cancelamento só pode ser feito depois fazendo uma operação real de cancelamento e não um desfazimento. E a interface do usuário aceita cancelar antes de qualquer coisa ter sido enviada para o gateway de pagamento processar, de forma que o método currentChargeCanBeAbortedByUser o faça.

Interface ApplicationDisplayListener

Implemente a interface ApplicationDisplayListener para solicitar que o aplicativo apresente mensagens ao usuário.

A interface possui 2 métodos. Todos serão explicados com mais detalhes nas seguintes linhas.

  • Esse método notifica sua aplicação com uma mensagem e o tipo da mensagem para que sua aplicação possa fazer o processamento que julgar necessário antes de repassar ao usuário.
void showMessage(String  var1, TerminalMessageType  var2)
  • Esse método notifica sua aplicação com uma mensagem, o tipo da mensagem e uma breve explicação para que sua aplicação possa fazer o processamento que julgar necessário antes de repassar ao usuário.
void showMessage(String var1, TerminalMessageType var2, String var3)

Para ajudar a implementar os métodos dessas 2 interfaces em sua "Activity" pode ser necessário utilizar os métodos expostos pela classe ZoopTerminalPayment.

Classe ZoopTerminalPayment

Para realizar uma carga/transação, na "onCreate()" da sua "Activity" deve-se criar uma nova instância do ZoopTerminalPayment e "setar" os seus "listerners".

A seguir, um exemplo de código:

try {
  ZoopTerminalPayment zoopTerminalPayment = new ZoopTerminalPayment();
  zoopTerminalPayment.setTerminalPaymentListener(ChargeActivity.this);
  zoopTerminalPayment.setApplicationDisplayListener(ChargeActivity.this);
  zoopTerminalPayment.setExtraCardInformationListener(ChargeActivity.this);
} catch (Exception e) {
  Log.e("Error instantiating ZoopTerminalPayment", e);
}

📘

A interface ExtraCardInformationListener é descrita na seção Respostas para a aplicação.

Uma vez instanciado o ZoopTerminalPayment podemos chamar o método que efetivamente realiza a carga/transação:

  • charge ("BigDecimal valueToCharge", "int paymentOption", "int iNumberOfInstallments", "String marketplaceId", "String sellerId", "String publishableKey").

  • valueToCharge - o valor a ser cobrado no formato BigDecimal

  • paymentOption - int representando a opção de pagamento. Pode assumir os valores: 0 - crédito; 1 - débito; 2 - crédito parcelado; 3 - voucher

  • iNumberOfInstallments - int representando o número de parcelas para dividir o valor cobrado

  • marketplaceId - String contendo o identificador registrado para o marketplace atual

  • sellerId - String contendo o identificador do vendedor registrado

  • publishableKey - chave de identificação em String

A seguir, um exemplo de código:

zoopTerminalPayment.charge(new BigDecimal(1.00),
                            0,
                            1,
                            "ffffa5eeee47cccc8b22229d7777a3bb",
                            "8989894eee3434530909e9234565bffd",
                            "zk_test_jhUYGlLGlOPPoF23FFoaRODf");

❗️

Sobre as Credenciais

Sua integração requer chaves de API diferentes para cada ambiente: Teste e Produção. Especialmente em produção, você deve manter suas chaves seguras, não importa o quê! não compartilhe suas chaves de API com qualquer pessoa. Para fazer transações de pagamento, você também precisará do marketplaceId correspondente e o sellerId com quem seu marketplace está fazendo transações em nome dele. Você pode obter essas credenciais de API com nossa equipe de suporte em: [email protected].

Adicionando Metadado

Para adicionar informações complementares ao nosso objeto transaction basta realizar a chamada do comando charge da seguinte forma:

charge(BigDecimal valueToCharge, int paymentOption, int iNumberOfInstallments, String marketplaceId, String sellerId, String publishableKey, JSONObject joMetadado)

Adicionando Identificador de Referência

Alguns negócios geram chaves únicas para identificar unidades básicas de operação, como ordens de serviço, ordem de reparo, entrega. Através do campo "referenceId", a ser enviado em cada transação, pode-se vincular estes identificadores às suas respectivas transações realizadas através da plataforma Zoop. Veja mais na seção Identificador de Referência para transações.

Após o método charge ser chamado, o SDK irá se comunicar com a maquininha para obter as informações necessárias do cartão para que a transação seja realizada com sucesso. Nesse processo, um possível fluxo seria passar repetidas vezes pelo método showMessage da interface ApplicationDisplayListener até que um JSONObject contendo informações do status da transação seja trazido no método paymentSuccessful ou no método paymentFailed, ambos da interface TerminalPaymentListener.

Interceptando as logs de erros

A partir da versão 2.1.8 do SDK Android será possível que sua aplicação intercepte a log de erros durante o processo de charge/void e use esta log da forma que for mais adequada para o seu contexto.

Para ter acesso aos logs implemente a interface LogInterceptorListener nas activities que executam o seu processo de charge (venda) e/ou void (estorno). Esta implementação exige a adição de um método void dump(string log) o qual vai receber em tempo real o callback contendo as ocorrências de log ocorridas. Você pode usar estas logs para debugar e/ou analisar ocorrências durante a execução.