From 8eec06ebe818ea83766aea7fa07f4dbb999aa1ca Mon Sep 17 00:00:00 2001 From: Diego Trevisan Lara Date: Thu, 29 Aug 2019 14:04:23 -0300 Subject: [PATCH 1/3] Initial ObjC support. --- .../APIClient/Endpoint/URLs.swift | 23 +++++++++++++------ DirectCheckout/SDK/DirectCheckout.swift | 8 +++++-- .../SDK/Entities/Response/Card.swift | 4 ++-- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/DirectCheckout/Dependencies/APIClient/Endpoint/URLs.swift b/DirectCheckout/Dependencies/APIClient/Endpoint/URLs.swift index 9a16973..197d668 100644 --- a/DirectCheckout/Dependencies/APIClient/Endpoint/URLs.swift +++ b/DirectCheckout/Dependencies/APIClient/Endpoint/URLs.swift @@ -9,24 +9,33 @@ // MARK: - Enums struct APIEndpointUrl { - let base: APIEnvionment + let environment: APIEnvionment let path: EndpointPath - init(base: APIEnvionment = .current, path: EndpointPath) { - self.base = base + init(environment: APIEnvionment = .current, path: EndpointPath) { + self.environment = environment self.path = path } var url: String { - return "\(base.rawValue)\(path.value)" + return "\(environment.baseUrl)\(path.value)" } } // MARK: - Environment -public enum APIEnvionment: String { - case production = "https://www.boletobancario.com/boletofacil/integration/api" - case sandbox = "https://sandbox.boletobancario.com/boletofacil/integration/api" +@objc public enum APIEnvionment: Int { + case production + case sandbox + + var baseUrl: String { + switch self { + case .production: + return "https://www.boletobancario.com/boletofacil/integration/api" + case .sandbox: + return "https://sandbox.boletobancario.com/boletofacil/integration/api" + } + } static var current: APIEnvionment = .production } diff --git a/DirectCheckout/SDK/DirectCheckout.swift b/DirectCheckout/SDK/DirectCheckout.swift index 2e09845..2539336 100644 --- a/DirectCheckout/SDK/DirectCheckout.swift +++ b/DirectCheckout/SDK/DirectCheckout.swift @@ -6,17 +6,21 @@ // Copyright © 2019 Juno Pagamentos. All rights reserved. // -public class DirectCheckout { +@objc public class DirectCheckout: NSObject { private static var publicToken: String? - public static func initialize(publicToken: String, environment: APIEnvionment = .production) { + @objc public static func initialize(publicToken: String, environment: APIEnvionment = .production) { self.publicToken = publicToken APIEnvionment.current = environment } // MARK: - Get hash + @objc public static func getCardHash(card: Card, success: (_ hash: String) -> Void, error: (_ error: Error) -> Void) { + + } + public static func getCardHash(_ card: Card, completion: @escaping (Result) -> Void) { guard let publicToken = publicToken else { diff --git a/DirectCheckout/SDK/Entities/Response/Card.swift b/DirectCheckout/SDK/Entities/Response/Card.swift index c35f66a..eac384b 100644 --- a/DirectCheckout/SDK/Entities/Response/Card.swift +++ b/DirectCheckout/SDK/Entities/Response/Card.swift @@ -6,7 +6,7 @@ // Copyright © 2019 Juno Pagamentos. All rights reserved. // -public struct Card: Codable { +@objc public class Card: NSObject, Codable { let cardNumber: String let holderName: String @@ -14,7 +14,7 @@ public struct Card: Codable { let expirationMonth: String let expirationYear: String - public init(cardNumber: String, holderName: String, securityCode: String, expirationMonth: String, expirationYear: String) { + @objc public init(cardNumber: String, holderName: String, securityCode: String, expirationMonth: String, expirationYear: String) { self.cardNumber = cardNumber.onlyNumbers self.holderName = holderName self.securityCode = securityCode.onlyNumbers From 6545c5696afbc9ac9ec6c5868459592a65d5eb7a Mon Sep 17 00:00:00 2001 From: Diego Trevisan Lara Date: Thu, 29 Aug 2019 23:04:52 -0300 Subject: [PATCH 2/3] ObjC support. --- DirectCheckout.podspec | 2 +- DirectCheckout/SDK/DirectCheckout.swift | 42 ++++-- .../SDK/Entities/Response/Card.swift | 28 +++- .../SDK/Entities/Response/CardType.swift | 2 +- DirectCheckout/SDK/Utils/CardUtils.swift | 2 +- DirectCheckoutTests/DirectCheckoutTests.swift | 8 +- README-OBJC.md | 122 ++++++++++++++++++ README.md | 29 +++-- 8 files changed, 200 insertions(+), 35 deletions(-) create mode 100644 README-OBJC.md diff --git a/DirectCheckout.podspec b/DirectCheckout.podspec index ce954d5..0dd2ae3 100644 --- a/DirectCheckout.podspec +++ b/DirectCheckout.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |spec| spec.name = "DirectCheckout" - spec.version = "0.0.2" + spec.version = "0.0.3" spec.summary = "SDK para criptografia e validação de dados do cartão de crédito para integração com a API de pagamentos da Juno/BoletoBancário." spec.homepage = "http://www.juno.com.br" spec.author = { "Diego Trevisan Lara" => "diego@juno.com.br" } diff --git a/DirectCheckout/SDK/DirectCheckout.swift b/DirectCheckout/SDK/DirectCheckout.swift index 2539336..33eb1c9 100644 --- a/DirectCheckout/SDK/DirectCheckout.swift +++ b/DirectCheckout/SDK/DirectCheckout.swift @@ -6,20 +6,18 @@ // Copyright © 2019 Juno Pagamentos. All rights reserved. // -@objc public class DirectCheckout: NSObject { +public class DirectCheckout: NSObject { private static var publicToken: String? + // MARK: - Initialization + @objc public static func initialize(publicToken: String, environment: APIEnvionment = .production) { self.publicToken = publicToken APIEnvionment.current = environment } - // MARK: - Get hash - - @objc public static func getCardHash(card: Card, success: (_ hash: String) -> Void, error: (_ error: Error) -> Void) { - - } + // MARK: - Get card hash public static func getCardHash(_ card: Card, completion: @escaping (Result) -> Void) { @@ -64,16 +62,42 @@ return CardUtils.getCardType(cardNumber) } - public static func isValidCardNumber(_ cardNumber: String) -> Bool { + @objc public static func isValidCardNumber(_ cardNumber: String) -> Bool { return CardUtils.validateNumber(cardNumber) } - public static func isValidSecurityCode(_ cardNumber: String, _ securityCode: String) -> Bool { - return CardUtils.validateCVC(cardNumber, securityCode) + @objc(isValidSecurityCode:cardNumber:) + public static func isValidSecurityCode(_ securityCode: String, _ cardNumber: String) -> Bool { + return CardUtils.validateCVC(securityCode, cardNumber) } + @objc(isValidExpireDateMonth:year:) public static func isValidExpireDate(month: String, year: String) -> Bool { return CardUtils.validateExpireDate(month, year) } } + +// MARK: - Objective-C Support + +extension DirectCheckout { + + @available(swift, obsoleted: 0.1) + @objc public static func initialize(publicToken: String) { + initialize(publicToken: publicToken, environment: .production) + } + + @available(swift, obsoleted: 0.1) + @objc(getCardHash:success:failure:) + public static func getCardHash(card: Card, success: @escaping (_ hash: String) -> Void, failure: @escaping (_ error: Error) -> Void) { + getCardHash(card) { result in + switch result { + case .success(let hash): + success(hash) + case .failure(let error): + failure(error) + } + } + } + +} diff --git a/DirectCheckout/SDK/Entities/Response/Card.swift b/DirectCheckout/SDK/Entities/Response/Card.swift index eac384b..a7a9c20 100644 --- a/DirectCheckout/SDK/Entities/Response/Card.swift +++ b/DirectCheckout/SDK/Entities/Response/Card.swift @@ -6,7 +6,7 @@ // Copyright © 2019 Juno Pagamentos. All rights reserved. // -@objc public class Card: NSObject, Codable { +public class Card: NSObject, Codable { let cardNumber: String let holderName: String @@ -34,21 +34,21 @@ // MARK: - Aux functions -extension Card { +public extension Card { func getType() -> CardType? { return CardUtils.getCardType(cardNumber) } - func validateNumber() -> Bool { + @objc func validateNumber() -> Bool { return CardUtils.validateNumber(cardNumber) } - func validateCVC() -> Bool { - return CardUtils.validateCVC(cardNumber, securityCode) + @objc func validateCVC() -> Bool { + return CardUtils.validateCVC(securityCode, cardNumber) } - func validateExpireDate() -> Bool { + @objc func validateExpireDate() -> Bool { return CardUtils.validateExpireDate(expirationMonth, expirationYear) } @@ -98,3 +98,19 @@ public enum CardError: LocalizedError { } } } + +// MARK: - Objective-C Support + +public extension Card { + + @available(swift, obsoleted: 0.1) + @objc func validate(success: (Card) -> Void, failure: (Error) -> Void) { + do { + _ = try validate() + success(self) + } catch { + failure(error) + } + } + +} diff --git a/DirectCheckout/SDK/Entities/Response/CardType.swift b/DirectCheckout/SDK/Entities/Response/CardType.swift index 1945560..6b1804e 100644 --- a/DirectCheckout/SDK/Entities/Response/CardType.swift +++ b/DirectCheckout/SDK/Entities/Response/CardType.swift @@ -24,7 +24,7 @@ struct CardTypeAssets { } } -enum CardType: String, CaseIterable { +public enum CardType: String, CaseIterable { case visa case masterCard case amex diff --git a/DirectCheckout/SDK/Utils/CardUtils.swift b/DirectCheckout/SDK/Utils/CardUtils.swift index 54c0fc0..87ce071 100644 --- a/DirectCheckout/SDK/Utils/CardUtils.swift +++ b/DirectCheckout/SDK/Utils/CardUtils.swift @@ -18,7 +18,7 @@ class CardUtils { return cardType?.cardLength == clearCardNumber.count && luhnCheck(clearCardNumber) } - static func validateCVC(_ cardNumber: String, _ securityCode: String) -> Bool { + static func validateCVC(_ securityCode: String, _ cardNumber: String) -> Bool { let cardType = getCardType(cardNumber)?.assets() return cardType?.cvcLength == securityCode.count } diff --git a/DirectCheckoutTests/DirectCheckoutTests.swift b/DirectCheckoutTests/DirectCheckoutTests.swift index 5fd6de8..e42e788 100644 --- a/DirectCheckoutTests/DirectCheckoutTests.swift +++ b/DirectCheckoutTests/DirectCheckoutTests.swift @@ -67,11 +67,11 @@ class DirectCheckoutTests: XCTestCase { } func test_valid_security_code() { - XCTAssertTrue(DirectCheckout.isValidSecurityCode("4111111111111111", "123")) //visa - XCTAssertTrue(DirectCheckout.isValidSecurityCode("5105105105105100", "987")) //master + XCTAssertTrue(DirectCheckout.isValidSecurityCode("123", "4111111111111111")) //visa + XCTAssertTrue(DirectCheckout.isValidSecurityCode("987", "5105105105105100")) //master - XCTAssertFalse(DirectCheckout.isValidSecurityCode("4111111111111111", "1234")) //visa - XCTAssertFalse(DirectCheckout.isValidSecurityCode("5105105105105100", "98")) //master + XCTAssertFalse(DirectCheckout.isValidSecurityCode("1234", "4111111111111111")) //visa + XCTAssertFalse(DirectCheckout.isValidSecurityCode("98", "5105105105105100")) //master } func test_card_valid_security_code() { diff --git a/README-OBJC.md b/README-OBJC.md new file mode 100644 index 0000000..ba7b602 --- /dev/null +++ b/README-OBJC.md @@ -0,0 +1,122 @@ +# DirectCheckout iOS + +![CocoaPods Compatible](https://img.shields.io/cocoapods/v/DirectCheckout.svg) +![Platforms](https://img.shields.io/badge/platforms-iOS-333333.svg) +![Languages](https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-333333.svg) + +>_Caso necessite, [confira a documentação para Swift](https://github.com/tamojuno/direct-checkout-ios/blob/master/README.md)._ + +SDK para criptografia e validação de dados de cartão de crédito para integração com a API de pagamentos da Juno/BoletoBancário. + +Visando garantir a segurança das transações realizadas em nossa plataforma, a API da Juno adota uma política de criptografia dos dados de cartão de crédito de ponta-a-ponta. + +Para mais informações acesse nossa página de integração: + +[Integração via API](https://www.boletobancario.com/boletofacil/integration/integration.html) + +## Instalação + +### Cocoapods + +Adicione o SDK nas dependências do seu aplicativo inserindo a seguinte linha no arquivo `Podfile`: + +``` +pod 'DirectCheckout' +``` + +Em seguida, instale as dependências pelo comando: + +```bash +pod install +``` + +Na inicialização do aplicativo, preferencialmente na classe `AppDelegate`, faça a inicialização do SDK passando como parâmetro o seu token público, que pode ser obtido em nossa [página de integração](https://www.boletobancario.com/boletofacil/integration/integration.html): + +```objc +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + [DirectCheckout initializeWithPublicToken:@"AC2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5"]; + + return YES; +} +``` + +Opcionalmente também é possível escolher o ambiente de testes (Sandbox): + +```objc +[DirectCheckout initializeWithPublicToken:@"AC2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5" environment:APIEnvionmentSandbox]; +``` + +## Utilização + +Detalhamos a seguir um exemplo de utilização de nossa biblioteca de como obter o hash do cartão de crédito: + +```objc +Card *card = [[Card alloc] initWithCardNumber:@"5448280000000007" + holderName:@"Antônio" + securityCode:@"123" + expirationMonth:@"01" + expirationYear:@"2020"]; + +[DirectCheckout getCardHash:card success:^(NSString *hash) { + + /* Sucesso - A variável hash conterá o hash do cartão de crédito */ + +} failure:^(NSError *error) { + + /* Erro - A variável error conterá o erro ocorrido ao obter o hash */ + +}]; +``` + +## Funções Auxiliares + +A biblioteca disponibilizada também possui uma série de métodos auxiliares para a validação de dados do cartão de crédito, conforme demonstrado a seguir: + +```objc +/* isValidCardNumber: Valida número do cartão de crédito (retorna true se for válido) */ +[DirectCheckout isValidCardNumber:@"9999999999999999"]; + +/* isValidSecurityCode: Valida código de segurança do cartão de crédito (retorna true se for válido) */ +[DirectCheckout isValidSecurityCode:@"111" cardNumber:@"9999999999999999"]; + +/* isValidExpireDate: Valida data de expiração do cartão de crédito (retorna true se for válido) */ +[DirectCheckout isValidExpireDateMonth:@"05" year:@"2021"]; +``` + +Algumas funções também podem ser acessadas diretamente da classe Card: + +```objc +Card *card = [[Card alloc] initWithCardNumber:@"5448280000000007" + holderName:@"Antônio" + securityCode:@"123" + expirationMonth:@"01" + expirationYear:@"2020"]; + +/* validateNumber: Valida número do cartão de crédito (retorna true se for válido) */ +[card validateNumber]; + +/* validateCVC: Valida código de segurança do cartão de crédito (retorna true se for válido) */ +[card validateCVC]; + +/* validateExpireDate: Valida data de expiração do cartão de crédito (retorna true se for válido) */ +[card validateExpireDate]; + +/* validate: Realiza todas as validações do cartão de crédito (executando bloco success se for válido ou bloco failure com um erro especificando a falha) */ +[card validateWithSuccess:^(Card *card) { + + /* Sucesso */ + +} failure:^(NSError *error) { + + /* Erro */ + +}]; + +``` + +## Contato + +Para mais informações entre em contato com a Juno: + +* https://juno.com.br/contato.html diff --git a/README.md b/README.md index 422b849..27d62f5 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,18 @@ - # DirectCheckout iOS +![CocoaPods Compatible](https://img.shields.io/cocoapods/v/DirectCheckout.svg) +![Platforms](https://img.shields.io/badge/platforms-iOS-333333.svg) +![Languages](https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-333333.svg) + +>_Caso necessite, [confira a documentação para Objective-C](https://github.com/tamojuno/direct-checkout-ios/blob/master/README-OBJC.md)._ + SDK para criptografia e validação de dados de cartão de crédito para integração com a API de pagamentos da Juno/BoletoBancário. Visando garantir a segurança das transações realizadas em nossa plataforma, a API da Juno adota uma política de criptografia dos dados de cartão de crédito de ponta-a-ponta. Para mais informações acesse nossa página de integração: -[Integração via API](https://www.boletobancario.com/boletofacil/integration/integration.html) +[Integração via API](https://www.boletobancario.com/boletofacil/integration/integration.html) ## Instalação @@ -30,8 +35,8 @@ Na inicialização do aplicativo, preferencialmente na classe `AppDelegate`, fa ```swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { - DirectCheckout.initialize(publicToken: "AF2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5") - + DirectCheckout.initialize(publicToken: "AC2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5") + return true } ``` @@ -39,7 +44,7 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau Opcionalmente também é possível escolher o ambiente de testes (Sandbox): ```swift -DirectCheckout.initialize(publicToken: "AF2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5", environment: .sandbox) +DirectCheckout.initialize(publicToken: "AC2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5", environment: .sandbox) ``` ## Utilização @@ -52,12 +57,12 @@ let card = Card(cardNumber: "5448280000000007", securityCode: "123", expirationMonth: "01", expirationYear: "2020") - + DirectCheckout.getCardHash(card) { result in do { let hash = try result.get() /* Sucesso - A variável hash conterá o hash do cartão de crédito */ - + } catch let error { /* Erro - A variável error conterá o erro ocorrido ao obter o hash */ } @@ -69,11 +74,11 @@ DirectCheckout.getCardHash(card) { result in A biblioteca disponibilizada também possui uma série de métodos auxiliares para a validação de dados do cartão de crédito, conforme demonstrado a seguir: ```swift -/* isValidSecurityCode: Valida número do cartão de crédito (retorna true se for válido) */ +/* isValidCardNumber: Valida número do cartão de crédito (retorna true se for válido) */ DirectCheckout.isValidCardNumber("9999999999999999") /* isValidSecurityCode: Valida código de segurança do cartão de crédito (retorna true se for válido) */ -DirectCheckout.isValidSecurityCode("9999999999999999", "111") +DirectCheckout.isValidSecurityCode("111", "9999999999999999") /* isValidExpireDate: Valida data de expiração do cartão de crédito (retorna true se for válido) */ DirectCheckout.isValidExpireDate(month: "05", year: "2021") @@ -90,7 +95,7 @@ let card = Card(cardNumber: "5448280000000007", securityCode: "123", expirationMonth: "01", expirationYear: "2020") - + /* getType: Obtém o tipo de cartão de crédito (bandeira) */ card.getType() @@ -108,10 +113,8 @@ card.validate() ``` -## Contato +## Contato Para mais informações entre em contato com a Juno: * https://juno.com.br/contato.html - - From 74d1e5e056959b8e5aa2a12897629d8e21d31d47 Mon Sep 17 00:00:00 2001 From: Diego Trevisan Lara <34442011+diegotl@users.noreply.github.com> Date: Thu, 29 Aug 2019 23:08:47 -0300 Subject: [PATCH 3/3] Fixed code highlight --- README-OBJC.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README-OBJC.md b/README-OBJC.md index ba7b602..e32d37d 100644 --- a/README-OBJC.md +++ b/README-OBJC.md @@ -32,7 +32,7 @@ pod install Na inicialização do aplicativo, preferencialmente na classe `AppDelegate`, faça a inicialização do SDK passando como parâmetro o seu token público, que pode ser obtido em nossa [página de integração](https://www.boletobancario.com/boletofacil/integration/integration.html): -```objc +```objective-c - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [DirectCheckout initializeWithPublicToken:@"AC2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5"]; @@ -43,7 +43,7 @@ Na inicialização do aplicativo, preferencialmente na classe `AppDelegate`, fa Opcionalmente também é possível escolher o ambiente de testes (Sandbox): -```objc +```objective-c [DirectCheckout initializeWithPublicToken:@"AC2261A2ECC7FD90D205502092571F5C1C0831935E35073AA95AEBEB68D7E5C5" environment:APIEnvionmentSandbox]; ``` @@ -51,7 +51,7 @@ Opcionalmente também é possível escolher o ambiente de testes (Sandbox): Detalhamos a seguir um exemplo de utilização de nossa biblioteca de como obter o hash do cartão de crédito: -```objc +```objective-c Card *card = [[Card alloc] initWithCardNumber:@"5448280000000007" holderName:@"Antônio" securityCode:@"123" @@ -73,7 +73,7 @@ Card *card = [[Card alloc] initWithCardNumber:@"5448280000000007" A biblioteca disponibilizada também possui uma série de métodos auxiliares para a validação de dados do cartão de crédito, conforme demonstrado a seguir: -```objc +```objective-c /* isValidCardNumber: Valida número do cartão de crédito (retorna true se for válido) */ [DirectCheckout isValidCardNumber:@"9999999999999999"]; @@ -86,7 +86,7 @@ A biblioteca disponibilizada também possui uma série de métodos auxiliares pa Algumas funções também podem ser acessadas diretamente da classe Card: -```objc +```objective-c Card *card = [[Card alloc] initWithCardNumber:@"5448280000000007" holderName:@"Antônio" securityCode:@"123"