Provider de Transação - POS Android

O PosTransactionProvider é o provedor de transação utilizado ao efetuar pagamentos utilizando um POS Android.

Para passar uma transação, a primeira coisa a ser feita é instanciar um objeto do tipo TransactionObject

final TransactionObject transaction = new TransactionObject();
📘

Veja os atributos deste objeto na seção TransactionObject

E popular os seguintes atributos do TransactionObject:

Nome

Tipo

Descrição

amount obrigatório

String

Valor da transação em centavos.

requestId opcional

String

ID do pedido

initiatorTransactionKey opcional

String

É um identificador único da transação definido pela aplicação que inicia a transação. O SDK possui um padrão próprio para gerar este identificador e usará esse padrão se um identificador não for definido. Caso você queira passar o seu próprio identificador, certifique-se que ele será sempre único para todos os seus clientes.

emailClient opcional

EmailClient

Seu email de noReply para envio do comprovante eletrônico.

instalmentTransactionEnum (¹) obrigatório

Enum

Quantidade de parcelas.

typeOfTransactionEnum (¹) obrigatório

Enum

Tipo da transação (débito, crédito, voucher ou PIX).

shortName opcional

String

Nome de exibição no extrato do cliente (máximo de 14 caracteres). Deixar em branco caso queira que apareça o nome do estabelecimento cadastrado na Stone

capture obrigatório

Boolean

Define se a transação será realizada com captura automática ou não.

subMerchantCategoryCode opcional

String

MCC do sub-merchant que efetuou a transação. Atributo obrigatório para aplicações de subadquirentes

subMerchantAddress opcional

String

Logradouro do sub-merchant. Atributo obrigatório para aplicações de subadquirentes

subMerchantCity opcional

String

Cidade do sub-merchant. Atributo obrigatório para aplicações de subadquirentes

subMerchantPostalAddress opcional

String

CEP do sub-merchant. Atributo obrigatório epenas em casos de aplicações de subadquirentes

subMerchantRegisteredIdentifier opcional

String

Identificador do sub-merchant no Sistema do Subadquirente. Atributo obrigatório epenas em casos de aplicações de subadquirentes

subMerchantTaxIdentificationNumber opcional

String

CNPJ do sub-merchant (apenas números). Atributo obrigatório epenas em casos de aplicações de subadquirentes

📘

(¹) instalmentTransactionEnum e typeOfTransactionEnum

Os valores possíveis para estes atributos estão na seção Transaction Enums.

Exemplo: /

//Valor da transação em centavos
transaction.setAmount("10");//Valor da transação em centavos

transaction.setRequestId(null);
/* AVISO IMPORTANTE: Não é recomendado alterar o campo abaixo do ITK,
 * pois ele gera um valor único. Contudo, caso seja necessário
 * faça conforme a linha a seguir. */
transaction.setInitiatorTransactionKey("SEU_IDENTIFICADOR_UNICO_AQUI");

//Informa a quantidade de parcelas, veja a tabela de valores para o InstalmentTransactionEnum
transaction.setInstalmentTransaction(InstalmentTransactionEnum.ONE_INSTALMENT);

//Definir forma de pagamento
transaction.setTypeOfTransaction(TypeOfTransactionEnum.CREDIT);

// Define se transação será feita com captura ou não.
transaction.setCapture(true); 

//Os campos abaixo são obrigatório apenas em casos de aplicações de subadquirentes

//Cidade do sub-merchant
stoneTransaction.setSubMerchantCity("city") 
  
//CEP do sub-merchant (Apenas * números)  
stoneTransaction.setSubMerchantPostalAddress("00000000") 
  
// Identificador do sub-merchant  
stoneTransaction.setSubMerchantRegisteredIdentifier("00000000")
  
// Identificador do sub-merchant
stoneTransaction.setSubMerchantTaxIdentificationNumber("33368443000199")

Após instanciar e popular o objeto TransactionObject, você poderá passar o mesmo para o PosTransactionProvider, que será o responsável por enviar a transação para o autorizador e trabalhar com a inserção e atualização no TransactionDAO.

Exemplo:

//Processo para envio da transação
// Stone.getUserModel(0) é o usuário atual do aplicativo, que está na posição zero.
final PosTransactionProvider provider = new PosTransactionProvider("SUA_ACTIVITY_AQUI", transaction, "USUARIO_DO_APLICATIVO_AQUI");

provider.setConnectionCallback(new StoneActionCallback() {
  @Override
  public void onSuccess() {
    // Transação enviada com sucesso e salva no banco. Para acessar, use o TransactionDAO
  }
  @Override
  public void onStatusChanged(Action action) {
      // Nesse callback é retornado o próximo passo a ser executado no fluxo de pagamento
  }
  @Override
  public void onError() {
    // Erro na transação
  }
});

provider.execute();
//Processo para envio da transação
// Stone.getUserModel(0) é o usuário atual do aplicativo, que está na posição zero.
val provider = PosTransactionProvider("SUA_ACTIVITY_AQUI", transaction, "USUARIO_DO_APLICATIVO_AQUI")
  
provider.connectionCallback= object : StoneActionCallback {
  override fun onSuccess() {
    // Transação enviada com sucesso e salva no banco. Para acessar, use o TransactionDAO
  }

  override fun onStatusChanged(action: Action) {
    // Nesse callback é retornado o próximo passo a ser executado no fluxo de pagamento
  }

  override fun onError() {
    // Erro na transação
  }
}

provider.execute()
📘

Lembrando que o PosTransactionProvider segue a mesma estrutura do ActiveApplicationProvider e os demais.

Esse provider pede uma Activity, o TransactionObject que foi criado anteriormente e o usuário do aplicativo.

Diferentemente do Provider de Pinpad, o POS exige um conjunto mais robusto de tratamento de eventos e portanto a "DefaultUI" é suportada.
É preciso criar as telas respodendo aos Actions, que podem ocorrer durante a transação.

Após a execução do provider, a sua aplicação receberá uma chamada no método onSuccess() ou onError().

Para ter acesso ao status da transação, você deve utilizar o método:

  provider.getTransactionStatus();
📘

Status da Transação

Todos os status possíveis se encontram na seção Status da Transação.

Em caso de REJECTED e DECLINED, você pode capturar a mensagem do autorizador, utilizando o método:

provider.getMessageFromAuthorize();

Mensagens como, por exemplo: “Saldo insuficiente”, “Cartão inválido”, “Violação de segurança”, etc.

🚧

Códigos de Retorno Sandbox

Existem diferentes retornos no ambiente de sandbox de acordo com o numero de centavos da transação. Por favor, para ter um transação aprovada teste usando um valor maior ou igual à um real, como por exemplo: R$ 2,00

Retorno Sandbox

📘

Códigos de Retorno Autorizador

Todos os códigos possíveis retornados pelo autorizador Stone em produção se encontram na seção Códigos de Retorno do Autorizador Stone.

Transações de QRCode

👍

APP Teste de pagamento PIX

Para realizar testes com Transações de QRCode, por favor instale o APP TESTE PIX em um smartphone Android, gere o QRCode no seu aplicativo de Pagamento em um POS Android e faça o scan usando o app no seu celular.

O Stone SDK também suporta transações com QRCode em seus Providers de Transação. Este tipo de transação possui fluxo próprio mas de fácil integração dentro da mesma arquitetura utilizada para transações de cartão.

Para, por exemplo, realizar uma transação PIX, basta setar o tipo da transação

transaction.setTypeOfTransaction(TypeOfTransactionEnum.PIX);

Ou, caso queira suportar transações de QRCode Elo (Auxílio Emergencial), configure o tipo e o entry mode

transaction.setTypeOfTransaction(TypeOfTransactionEnum.DEBIT);
transaction.setEntryMode(EntryMode.QRCODE);

E responder à Action para exibição do QRCode gerado, exibindo-o na tela.
A propriedade "QRCode" no TransactionObject é um Bitmap para ser atribuído em uma View

@Override
  public void onStatusChanged(Action action) {    
    if (action == Action.TRANSACTION_WAITING_QRCODE_SCAN) {
      // Mostre o QRCode na tela usando transaction.getQRCode()
    }
  }

Também é necessário que o StoneCode que esteja gerando o QRCode tenha uma Conta Stone cadastrada, caso contrário não será possível gerar o QRCode.

Caso não haja uma Conta Stone associada, a mensagem de erro será "Conta Stone não encontrada", no campo transactionProvider.getMessageFromAuthorize();

🚧

Tempo de Expiração do QRCode

O QRCode deverá ficar visivel por 90 segundos, definido dinamicamente pelo nossa API de QRCode.
Após esse tempo, será disparada o callback indicando que ocorreu um erro na transação de QRCode Expirado, e ele não poderá mais ser pago.

Antes de fazer uma transação de QRCode também é necessário configurar as chaves de acesso à API de QRCode, QRCODE_AUTHORIZATION e QRCODE_PROVIDERID, conforme coberto no tópico Inicializando o SDK

Caso as credenciais estejam incorretas, a mensagem de erro será "Erro no Sistema", no campo transactionProvider.getMessageFromAuthorize();

❗️

Sobre Status de Transações PIX

Transações PIX que recebam erro (como, por exemplo, um erro de falta de conexão após a criação do QRCode) não podem ser assumidas como negadas, como acontece com transações capturadas com cartão.

Estas transações, por suas próprias características, não podem ser desfeitas pois o POS atua passivamente identificando o pagamento, quem de fato realiza o pagamento é o device do pagador.

Portando, em cenário de erro, é sempre recomendado que o lojista faça a validação em sua Conta Stone, e é recomendado que isto seja refletido na mensagem para o usuário.

Abort Payment

O método de abortPayment() é utilizado como um recurso de cancelamento de transações que estão em andamento, podendo ser considerada uma reversão. Esse cenário pode acontecer por iniciativa do próprio usuário (cancelando a operação antes de passar o cartão usando a opção de cancelar, por exemplo) ou por algum motivo interno na comunicação entre as partes durante o processo de pagamento (após o usuário confirmar o pagamento com seu cartão ou outra modalidade escolhida).

Quando o abortPayment() é chamado, são realizadas as seguintes etapas:

  1. O TransactionObject.transactionStatus é alterado para TransactionStatusEnum.CANCELLED;
    • Em paralelo, o processo de pagamento tentará ser cancelado;
  2. O TransactionObject.transactionStatus é alterado para TransactionStatusEnum.PENDING_REVERSAL;
    • Em paralelo, a transação tentará ser revertida;
  3. Será checado se a transação foi gravada no banco de dados;
    • Caso positivo, seus dados serão atualizados;
  4. Uma função de callback será chamada caso alguma tenha sido informada;
PosTransactionProvider provider = PosTransactionProvider(context, transactionObject, userModel);

// Faça o processo de pagamento

// Em caso de retornar erro ou usuário cancelou o processo
provider.abortPayment();

❗️

Problemas comuns

  • Chamar o abortPayment() múltiplas vezes para a mesma transação acarretará em múltiplas threads sendo criadas para tentar cancelar a transação, causando um problema de concorrência, onde será lançada uma IllegalStateException();
  • Caso o Provider de Cancelamento já tenha sido chamado para cancelar uma transação, chamar o abortPayment() irá neutralizar essa solicitação de cancelamento;