Android
Nesta seção você irá aprender mais sobre os detalhes de cada funcionalidade do SDK Android para mPOS. Veja como fazer o download e configurar as bibliotecas básicas que seguem o protocolo ABECS. Além disso, veja o fluxo de criação de uma transação. Vamos lá!
Download do SDK
O SDK Android pode ser encontrado em duas distribuições, dependendo do sistema de build sendo usado:
Configurando o ambiente
Permissões Android
Adicione as seguintes linhas ao AndroidManifest.xml do seu projeto, no interior da tag <manifest>
:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
Essas linhas garantirão as permissões necessárias para que o aplicativo e o SDK possam realizar operações com Bluetooth e com conexões à Internet.
Instruções para build com Ant:
-
Após fazer o download em Ant, você deve encontrar os seguintes arquivos:
- mpos-android-native.jar
- mpos-android.jar
-
Adicione os JARs incluídos na distribuição ao seu projeto.
Instruções para build com Gradle:
-
Dentro do diretório de sua application Android (geralmente '/app'), você deve encontrar os seguintes arquivos:
- AndroidManifest.xml - build.gradle
E após fazer o download em Gradle, os seguintes arquivos estarão disponíveis:
- mpos-android-native.jar - mpos-android.aar
-
Adicione as seguintes linhas ao build.gradle:
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile (name:'mpos-android', ext:'aar') {
transitive = true
}
}
Essas linhas incluirão os componentes nativos e os componentes Java do SDK para Android no seu projeto.
- Adicione os arquivos:
- mpos-android-native.jar
- mpos-android.aar
ao diretório libs
abaixo do diretório de sua application Android
.
Fluxo pré-transação
O código abaixo demonstra um fluxo completo que pode ser usado por sua aplicação,
para capturar os dados de cartão, gerar o card_hash
e usá-lo para criar uma transação com
a API Pagar.Me a partir de um servidor externo. Vamos lá:
package com.example.pagarme.mpospocs;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import me.pagar.mposandroid.MposPaymentResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import me.pagar.mposandroid.Mpos;
import me.pagar.mposandroid.MposListener;
import me.pagar.mposandroid.EmvApplication;
import me.pagar.mposandroid.PaymentMethod;
public class MainActivity extends AppCompatActivity {
private ListView listView;
private ArrayList<String> mDeviceList = new ArrayList<String>();
private ArrayList<BluetoothDevice> abecsList = new ArrayList<BluetoothDevice>();
private BluetoothAdapter mBluetoothAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long arg3) {
view.setSelected(true);
BluetoothDevice device = abecsList.get(position);
Log.d("Abecs", "SELECTED DEVICE " + device.getName());
try {
final Mpos mpos = new Mpos(abecsList.get(position), "SUA ENCRYPTION KEY", getApplicationContext());
mpos.addListener(new MposListener() {
public void bluetoothConnected() {
Log.d("Abecs", "Bluetooth connected.");
mpos.initialize();
}
public void bluetoothDisconnected() {
Log.d("Abecs", "Bluetooth disconnected.");
}
public void bluetoothErrored(int error) {
Log.d("Abecs", "Received bluetooth error");
}
public void receiveInitialization() {
Log.d("Abecs", "receive initialization!");
try {
mpos.downloadEMVTablesToDevice(true);
} catch (Exception e) {
Log.d("Abecs", "Got error in initialization and table update " + e.getMessage());
}
}
public void receiveNotification(String notification) {
Log.d("Abecs", "Got Notification " + notification);
}
public void receiveTableUpdated(boolean loaded) {
Log.d("Abecs", "received table updated loaded = " + loaded);
EmvApplication visaCredit = new EmvApplication(PaymentMethod.CreditCard, "visa");
ArrayList<EmvApplication> l = new ArrayList<EmvApplication>();
l.add(visaCredit);
EmvApplication masterCredit = new EmvApplication(PaymentMethod.CreditCard, "master");
l.add(masterCredit);
mpos.payAmount(5000, l, PaymentMethod.CreditCard);
}
public void receiveFinishTransaction() {
Log.d("Abecs", "Finished transaction");
mpos.close("TRANSACAO APROVADA");
}
public void receiveClose() {
Log.d("Abecs", "Receive close");
mpos.closeConnection();
}
public void receiveCardHash(String cardHash, MposPaymentResult result) {
Log.d("Abecs", "Card Hash is " + cardHash);
Log.d("Abecs", "Card Brand is " + result.cardBrand);
Log.d("Abecs", "FD = " + result.cardFirstDigits + " LD = " + result.cardLastDigits);
Log.d("Abecs", "ONL = " + result.isOnline);
/* Nesse momento você deve enviar o card_hash para
seu servidor, criar a transação, e devolver um
response para o app com os seguintes campos:
* acquirer_response_code
* card_emv_response
* card_pin_mode
Que serão usados no mpos.finishTransaction()
*/
mpos.finishTransaction(true, Integer.parseInt((String) t.get("acquirer_response_code")), (String) t.get("card_emv_response"));
}
public void receiveError(int error) {
Log.d("ABECS", "Received error " + error);
}
public void receiveOperationCancelled() {
Log.d("ABECS", "Cancel");
}
});
Log.d("Abecs", "Telling to initialize");
mpos.openConnection(false);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
Atualizando as tabelas EMV
Para as diferentes aplicações de cartão de crédito (diferentes bandeiras, crédito/débito) existem um conjunto de especificações de como o PinPad deve se comportar, assim como certificados que permitem lidar com elas. Este conjunto é denominado tabelas EMV
e pode ser obtido junto à Pagar.me via SDK.
Para baixar as tabelas EMV, as seguintes operações são realizadas:
- Download das tabelas EMV pela API Pagar.me;
- Transferência das tabelas baixadas para o PinPad.
A API Pagar.me fornece as tabelas EMV e então as bibliotecas, como no exemplo abaixo, fazem a instalação no PinPad:
public void receiveInitialization() {
Log.d("Abecs", "receive initialization!");
try {
mpos.downloadEMVTablesToDevice(true);
} catch (Exception e) {
Log.d("Abecs", "Got error in initialization and table update " + e.getMessage());
}
}
O valor booleano force
dos exemplos especifica o comportamento de atualização de tabelas no PinPad. Caso esteja setado como true, faz o download e instala as tabelas baixadas no PinPad. Caso esteja como false, somente instala as tabelas no PinPad se a versão no PinPad for diferente da versão das tabelas na API Pagar.me, evitando instalações de forma redundante.
O parâmetro loaded
nos eventos lançados por ocasião do término de atualização de tabelas indica, se true
, que foram instaladas tabelas no PinPad; se false
, que essa instalação não foi necessária.
Processando os dados de cartão
Para processar e obter um card_hash
— que deverá ser enviado à API Pagar.me para que a transação seja criada — o seguinte código pode ser utilizado:
public void receiveTableUpdated(boolean loaded) {
Log.d("Abecs", "received table updated loaded = " + loaded);
EmvApplication visaCredit = new EmvApplication(PaymentMethod.CreditCard, "visa");
ArrayList<EmvApplication> l = new ArrayList<EmvApplication>();
l.add(visaCredit);
EmvApplication masterCredit = new EmvApplication(PaymentMethod.CreditCard, "master");
l.add(masterCredit);
mpos.payAmount(5000, l, PaymentMethod.CreditCard);
}
Este SDK usa uma função de processamento chamada payAmount
com três parâmetros: amount
, applications
e magstripePaymentMethod
.
O primeiro é um inteiro representando a quantia a ser cobrada em centavos (no caso dos exemplos, 100 = R$1,00). As opções possíveis são as seguintes:
Parâmetro | Significado |
---|---|
amount | Quantia a ser cobrada em centavos (ex. 100 = R$1,00) |
applications | Um conjunto de EMVApplication que sua aplicação deseja selecionar. Uma EMVApplication consiste da combinação bandeira e método de pagamento (ex. Visa Crédito, Master Débito, Amex Crédito). Em caso de valor nulo, a escolha de possíveis aplicações é feita pelo pinpad. |
magstripePaymentMethod | A tarja magnética não permite seleção de método de pagamento no pinpad, e requer sempre que a aplicação o defina. Possíveis valores: PaymentMethod.CreditCard ou PaymentMethod.DebitCard |
Vale ressaltar
Caso o conjunto de aplicações especificado não seja suportado pelo cartão inserido (ex. applications contém Visa Crédito e o cartão é Master Crédito), o pinpad retorna o erro 70.
Finalizando uma transação
Após a obtenção de um card_hash por meio do processamento no SDK, e seu envio à API Pagar.me para criação de uma transação, é necessário finalizar o procedimento como um todo. Para tal, o seguinte código deve ser usado:
boolean connected = true; /* Define se foi possível se conectar à API Pagar.me para processar a transação */
mpos.finishTransaction(connected, Integer.parseInt((String) t.get("acquirer_response_code")), (String) t.get("card_emv_response"));
Logo, considere a seguinte assinatura para o método finishTransaction
:
finishTransaction(boolean connected, int responseCode, String emvData)
Começando com o parâmetro connected
, ele define se a conexão com a API Pagar.me foi bem-sucedida, e os demais podem ser encontrados no response
da API Pagar.Me para seu servidor:
{
"card_pin_mode": "online",
"acquirer_response_code": "0000",
"card_emv_response": "124046c481.ca8c"
}
Sendo:
Parâmetro | Correspondência no objeto transaction |
---|---|
responseCode | acquirer_response_code , diz respeito ao código de retorno do adquirente Pagar.Me para sua aplicação. |
emvData | card_emv_response : String responsável por finalizar a comunicação entre pinpad e cartão, e usada somente quando a autenticação foi pin online, veja a seguir. |
card_pin_mode
Você deve usar este parâmetro para validar se é necessário executar o finishTransaction
. Sempre que o retorno estiver como online
, é necessário finalizar a transação, caso contrário apenas execute o fechamento da conexão com o PinPad.
Vale ressaltar
Caso não tenha sido possível fazer uma conexão com a API Pagar.me, para inicializar uma transação (e o parâmetro connected seja false), responseCode deve ser 0 e emvData deve ser
null
.
Updated over 6 years ago
Excelente! Você aprendeu como integrar sua aplicação com nosso SDK para mPOS, mas caso encontre algum erro ao longo do caminho, a seguinte tabela pode te ajudar na resolução, segue: