iOS
Nesta seção você irá aprender mais sobre os detalhes de cada funcionalidade do SDK iOS
para mPOS. Veja como fazer o download e como configurar as bibliotecas básicas que seguem o protocolo ABECS. Entenda também o fluxo de criação de uma transação. Vamos lá!
Download do SDK
Para integrar seu PinPad com uma aplicação que utiliza da biblioteca mPOS iOS Pagar.me você precisa primeiro fazer o download em: Bibliotecas
Ao finalizar o download, você deve descompactar a pasta mpos-ios, e localizar os diretórios lib e include, já que ambos serão necessários para os próximos passos.
Configurando o ambiente
Em seu Xcode, siga os seguintes passos:
- Adicione as libraries
libabecs.a
,libmpos.a
,libmposios.a
elibtms.a
— que estão incluídas na distribuição do SDK (pastalib
) — nas configurações do projeto Xcode em Build Phases > Link Binary With Libraries; - Adicione o diretório
include
da distribuição do SDK a Build Settings > Search Paths > Header Search Paths; - Adicione o diretório
lib
da distribuição do SDK a Build Settings > Search Paths > Library Search Paths; - Mude a opção Build Settings > Build Options > Enable Bitcode de
Yes
paraNo
; - Caso seu projeto use Objective-C ou Swift (e não Objective-C++), adicione
-lstdc++
a Build Settings > Linking > Other Linker Flags.
Caso você use Swift
- Adicione um header file ao seu projeto para fazer o bridging, e insira:
#import <mpos-ios.h>
- No campo Build Settings > Swift Compiler - Code Generation > Objective-C Bridging Header, insira este header;
- Ao adicionar o Header, a classe
PMMposController
estará disponível para você.
Criando uma transação
O exemplo abaixo segue todo o fluxo para capturar as informações do cartão e gerar um card_hash para que posteriormente você consiga criar uma transação. Em seguida já explicamos os principais pontos do código, segue:
//
// ViewController.m
// mposToDocs
//
// Created by Aardvark on 1/25/17.
// Copyright © 2017 Aardvark. All rights reserved.
//
#import "ViewController.h"
#import <ExternalAccessory/ExternalAccessory.h>
#import "mpos-ios.h"
@interface ViewController ()
@end
@implementation ViewController
- (void) makeATransaction{
// Obtém um objeto EAAccessory, que representa um aparelho Bluetooth pareado.
EAAccessory *accessory = [[[EAAccessoryManager sharedAccessoryManager]
connectedAccessories]
firstObject];
PMMposController *controller = [[PMMposController alloc] initWithAccessory:accessory encryptionKey:@"SUA ENCRYPTION_KEY"];
[controller openConnection];
[controller openSessionWithCallback:^(NSError *error) {
if (error != nil) {
/* Lidar com Erro */
NSLog(@"What's wrong kido: %@", error);
return;
}
/* Agora vamos configurar duas aplicações, ou seja, especificar
duas combinações de Bandeira + Tipo de cartão que desejamos limitar o aceite,
sendo Visa e Master crédito. Mas para aceitar todas, passe nil no parâmetro.
*/
NSArray *applications = @[
[PMEmvApplication applicationWithCardBrand:@"visa"
paymentMethod:MPM_CREDIT],
[PMEmvApplication applicationWithCardBrand:@"master"
paymentMethod:MPM_CREDIT]
];
/* selecionar Crédito como método de pagamento de tarja */
[controller payAmount:15000 withApplications:applications
magstripePaymentMethod:MPM_CREDIT
withCallback:^(NSString *cardHash,
NSDictionary *dict,
NSError *error) {
NSLog(@"Sweet you've just got a cardHash, look: %@", cardHash);
/*Excelente, neste momento já pode criar uma transação usando o cardHash gerado. */
/* recomendamos que faça a chamada para API
de um servidor externo, e não diretamente do device */
NSLog(@"Crie a transação neste ponto");
/* E após criar essa transação, a API Pagar.Me vai retornar alguns parâmetros que
você precisa para encerrar o processo junto ao PinPad*/
[controller finishTransactionWithSuccessfulConnection:YES
responseCode:200
emvData:@"emvDataResponse"
withCallback:^(NSError *error){
if(error != nil){
NSLog(@"Something went wrong while finishing the transaction, look: %@", error);
}
/*Com tudo certo, você deve agora encerrar a session e a connection com o Pinpad*/
[controller closeSessionWithMessage:@"You are terminated!" callback:^(NSError *error) {
/* Hora de encerrar a connection também */
[controller closeConnection];
}];
}];
}];
}];
}
@end
import ExternalAccessory
// Obtém um objeto EAAccessory, que representa um aparelho Bluetooth pareado.
let accessory = EAAccessoryManager.sharedAccessoryManager().connectedAccessories.first
let controller = PMMposController(accessory: accessory, encryptionKey: "SUA_ENCRYPTION_KEY")
controller.openConnection()
controller.openSessionWithCallback({ (error: NSError!) -> Void in
if error != nil {
/* Lidar com Erro */
return
}
/* aceitar somente Visa Crédito */
var applications = [ PMEmvApplication(cardBrand: "visa", paymentMethod: MPM_CREDIT) ];
/* selecionar Crédito como método de pagamento de tarja */
controller.payAmount(100, withApplications: applications, withCallback: { (cardHash: String!, error: NSError!) -> Void in
if error != nil {
/* Lidar com Erro */
return
}
NSLog("card_hash gerado = %@", cardHash);
/* Gerar transação com a API Pagar.me... */
controller.finishTransactionWithSuccess(..., withCallback: { error: NSError! -> Void in
if error != nil {
/* Lidar com Erro */
return
}
controller.closeSessionWithMessage(message: "Message", callback: { error: NSError! -> Void in
controller.closeConnection()
})
})
})
});
Atualizando tabelas EMV
Para as diferentes aplicações de Cartão de crédito (diferentes bandeiras e diferença entre crédito e débito) existe um conjunto de especificações de como o PinPad deve se comportar, assim como certificados que permitem ao PinPad lidar com elas. Este conjunto é denominado tabelas EMV
e pode ser obtido junto ao 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 as bibliotecas, como no exemplo abaixo, fazem a instalação no PinPad:
#import <ExternalAccessory/ExternalAccessory.h>
#import "mpos-ios.h"
// Obtém um objeto EAAccessory, que representa um aparelho Bluetooth pareado.
EAAccessory *accessory = [[[EAAccessoryManager sharedAccessoryManager] connectedAccessories] firstObject];
PMMposController *controller = [[PMMposController alloc] initWithAccessory:accessory encryptionKey:@"{ENCRYPTION_KEY}"];
BOOL force = NO; // Define o comportamento da atualização de tabelas
[controller openConnection];
[controller openSessionWithCallback:^(NSError *error){
if (error != nil) { /* Lidar com Erro */ return; }
[controller downloadEMVTablesToDeviceWithCallback:^(BOOL loaded, NSError *error){
if (error != nil) { /* Lidar com Erro */ return; }
NSLog(@"Tabelas Carregadas: %d", loaded);
[controller closeSessionWithMessage:@"Message" callback:^(NSError *error){
[controller closeConnection];
}];
} forceUpdate:force];
}];
import ExternalAccessory
// Obtém um objeto EAAccessory, que representa um aparelho Bluetooth pareado.
let accessory = EAAccessoryManager.sharedAccessoryManager().connectedAccessories.first
let controller = PMMposController(accessory: accessory, encryptionKey: "ENCRYPTION_KEY")
let force = false // Define o comportamento da atualização de tabelas
controller.openConnection()
controller.openSessionWithCallback({ (error: NSError!) -> Void in
if error != nil {
/* Lidar com Erro */
return
}
controller.downloadEMVTablesToDeviceWithCallback({ (loaded: Bool, error: NSError!) -> Void in
if error != nil {
/* Lidar com Erro */
return;
}
NSLog("Tabelas Carregadas: %d", loaded);
controller.closeSessionWithMessage(message: "Message", callback: { error: NSError! -> Void in
controller.closeConnection()
})
}, forceUpdate: force)
});
O valor booleano force
dos exemplos especifica o comportamento de atualização de tabelas no PinPad. Caso ele seja 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 uma transação de cartão de crédito/débito por intermédio do PinPad e obter o card hash — que deve ser enviado à API Pagar.me para que a transação seja completada — o seguinte código pode ser utilizado:
#import <ExternalAccessory/ExternalAccessory.h>
#import "mpos-ios.h"
// Obtém um objeto EAAccessory, que representa um aparelho Bluetooth pareado.
EAAccessory *accessory = [[[EAAccessoryManager sharedAccessoryManager] connectedAccessories] firstObject];
PMMposController *controller = [[PMMposController alloc] initWithAccessory:accessory encryptionKey:@"{ENCRYPTION_KEY}"];
[controller openConnection];
[controller openSessionWithCallback:^(NSError *error){
if (error != nil) { /* Lidar com Erro */ return; }
/* aceitar somente Visa Crédito */
NSArray *applications = @[ [PMEmvApplication applicationWithCardBrand:@"visa" paymentMethod:MPM_CREDIT] ];
/* selecionar Crédito como método de pagamento de tarja */
[controller payAmount:100 withApplications:applications magstripePaymentMethod:MPM_CREDIT withCallback:^(NSString *cardHash, NSError *error){
if (error != nil) { /* Lidar com Erro */ return; }
NSLog(@"card_hash gerado = %@", cardHash);
/* Gerar transação com a API Pagar.me... */
[controller finishTransactionWithSuccess:... withCallback:^(NSError *error){
if (error != nil) { /* Lidar com Erro */ return; }
[controller closeSessionWithMessage:@"Message" callback:^(NSError *error){
[controller closeConnection];
}];
}];
}];
}];
import ExternalAccessory
// Obtém um objeto EAAccessory, que representa um aparelho Bluetooth pareado.
let accessory = EAAccessoryManager.sharedAccessoryManager().connectedAccessories.first
let controller = PMMposController(accessory: accessory, encryptionKey: "{ENCRYPTION_KEY}")
controller.openConnection()
controller.openSessionWithCallback({ (error: NSError!) -> Void in
if error != nil {
/* Lidar com Erro */
return
}
/* aceitar somente Visa Crédito */
var applications = [ PMEmvApplication(cardBrand: "visa", paymentMethod: MPM_CREDIT) ];
/* selecionar Crédito como método de pagamento de tarja */
controller.payAmount(100, withApplications: applications, withCallback: { (cardHash: String!, error: NSError!) -> Void in
if error != nil {
/* Lidar com Erro */
return
}
NSLog("card_hash gerado = %@", cardHash);
/* Gerar transação com a API Pagar.me... */
controller.finishTransactionWithSuccess(..., withCallback: { error: NSError! -> Void in
if error != nil {
/* Lidar com Erro */
return
}
controller.closeSessionWithMessage(message: "Message", callback: { error: NSError! -> Void in
controller.closeConnection()
})
})
})
});
O SDK usa a função payAmount
para capturar os dados, que aceita os seguites 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, que podem ser juntadas com o operador bitwise-OR (|):
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, o que requer sempre que a aplicação o defina. |
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:
#import "mpos-ios.h"
BOOL connected = YES; /* Define se foi possível se conectar à API Pagar.me para processar a transação */
[controller finishTransactionWithSuccess:connected withResponseCode:[responseCode integerValue] emvData:emvData withCallback:^(NSError *error){}];
let connected = true; /* Define se foi possível se conectar à API Pagar.me para processar a transação */
controller.finishTransactionWithSuccess(connected, withResponseCode: Int(responseCode), emvData: emvData, withCallback: { error: NSError! }) -> Void in });
Os parâmetros responseCode
e emvData
devem ser retirados do objeto transaction retornado pela API Pagar.me:
{
"card_pin_mode": "online",
"acquirer_response_code": "0000",
"card_emv_response": "124046c481.ca8c"
}
Com a seguinte correspondência:
Parâmetro | Significado |
---|---|
responseCode | Integer dentro da propriedade acquirer_response_code do objeto transaction |
emvData | card_emv_response : String responsável por finalizar a comunicação entre PinPad e cartão — 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 sernull
.
Parâmetro local_time
Ao criar uma transação de mundo físico, deve ser enviado o parâmetro
local_time
, que refere-se a data e hora do dispositivo que está efetuando a transação, em formato ISO String (2017-10-31T14:53:00.000Z
).
Updated about 7 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: