Skip to content

Commit

Permalink
fix: SDK not sending card CVN when creating authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
javiersuweijie committed Sep 17, 2021
1 parent 7295ee6 commit 6f83794
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Xendit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Xendit"
s.version = "3.4.1"
s.version = "3.4.2"
s.summary = "Xendit is an API for accepting payments online"
s.homepage = "https://www.xendit.co"
s.license = "MIT"
Expand Down
36 changes: 25 additions & 11 deletions Xendit/XDTCards.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,21 @@ public class XDTCards: CanTokenize, CanAuthenticate {
completion(tokenWith3DSRecommendation, nil);
})
} else {
handleCreditCardTokenization(fromViewController: fromViewController, authenticatedToken: authenticatedToken, amount: tokenizationRequest.amount, currency: currency, onBehalfOf: onBehalfOf, error: error, completion: completion)
handleCreditCardTokenization(fromViewController: fromViewController, authenticatedToken: authenticatedToken, amount: tokenizationRequest.amount, currency: currency, onBehalfOf: onBehalfOf, cardCvn: tokenizationRequest.cardData.cardCvn, error: error, completion: completion)
}
}
}
public static func createAuthentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, onBehalfOf: String?, customer: XenditCustomer?, completion: @escaping (XenditAuthentication?, XenditError?) -> Void) {

createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: nil, onBehalfOf: onBehalfOf, customer: customer, completion: completion);
}

public static func createAuthentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, currency: String?, onBehalfOf: String?, customer: XenditCustomer?, completion: @escaping (XenditAuthentication?, XenditError?) -> Void) {

createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: nil, onBehalfOf: onBehalfOf, customer: customer, cardCvn: nil, completion: completion);
}

public static func createAuthentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, currency: String?, onBehalfOf: String?, customer: XenditCustomer?, cardCvn: String?, completion: @escaping (XenditAuthentication?, XenditError?) -> Void) {
if publishableKey == nil {
completion(nil, XenditError(errorCode: "VALIDATION_ERROR", message: "Empty publishable key"))
return
Expand All @@ -96,12 +102,12 @@ public class XDTCards: CanTokenize, CanAuthenticate {
(jwt, error) in
if error != nil || jwt?.jwt == nil {
// Continue with normal flow
create3DS1Authentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, completion: completion)
create3DS1Authentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, cardCvn: cardCvn, completion: completion)
} else {
// 3DS2 flow
let environment = jwt?.environment;
let jwt = jwt?.jwt
handleEmv3DSFlow(fromViewController: fromViewController, tokenId: tokenId, environment: environment!, amount: amount, currency: currency, jwt: jwt!, onBehalfOf: onBehalfOf) {
handleEmv3DSFlow(fromViewController: fromViewController, tokenId: tokenId, environment: environment!, amount: amount, currency: currency, jwt: jwt!, onBehalfOf: onBehalfOf, cardCvn: cardCvn) {
(token, error) in
if token == nil || error != nil {
completion(nil, error)
Expand All @@ -116,7 +122,7 @@ public class XDTCards: CanTokenize, CanAuthenticate {
}
}

private static func create3DS1Authentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, currency: String?, onBehalfOf: String?, completion: @escaping (XenditAuthentication?, XenditError?) -> Void) {
private static func create3DS1Authentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, currency: String?, onBehalfOf: String?, cardCvn: String?, completion: @escaping (XenditAuthentication?, XenditError?) -> Void) {
if publishableKey == nil {
completion(nil, XenditError(errorCode: "VALIDATION_ERROR", message: "Empty publishable key"))
return
Expand All @@ -130,6 +136,10 @@ public class XDTCards: CanTokenize, CanAuthenticate {
requestBody["currency"] = currency
}

if cardCvn != nil {
requestBody["card_cvn"] = cardCvn
}

var extraHeaders: [String: String] = [:]
if onBehalfOf != nil || onBehalfOf != "" {
extraHeaders["for-user-id"] = onBehalfOf
Expand All @@ -143,7 +153,7 @@ public class XDTCards: CanTokenize, CanAuthenticate {
XDTApiClient.create3DSRecommendationRequest(publishableKey: publishableKey!, tokenId: tokenId, completion: completion)
}

private static func createAuthenticationWithSessionId(fromViewController: UIViewController, tokenId: String, sessionId: String, amount: NSNumber, currency: String?, onBehalfOf: String?, completion:@escaping (_ : XenditCCToken?, _ : XenditError?) -> Void) {
private static func createAuthenticationWithSessionId(fromViewController: UIViewController, tokenId: String, sessionId: String, amount: NSNumber, currency: String?, onBehalfOf: String?, cardCvn: String?, completion:@escaping (_ : XenditCCToken?, _ : XenditError?) -> Void) {

var requestBody: [String: Any] = [
"amount" : amount,
Expand All @@ -154,6 +164,10 @@ public class XDTCards: CanTokenize, CanAuthenticate {
requestBody["currency"] = currency
}

if cardCvn != nil {
requestBody["card_cvn"] = cardCvn
}

var header: [String: String] = [:]
if onBehalfOf != nil {
header["for-user-id"] = onBehalfOf!
Expand All @@ -173,7 +187,7 @@ public class XDTCards: CanTokenize, CanAuthenticate {
authentication?.authenticationTransactionId == nil ||
authentication?.requestPayload == nil {
// Revert to 3DS1 flow
return create3DS1Authentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf) { (authentication, error) in
return create3DS1Authentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, cardCvn: cardCvn) { (authentication, error) in
if error != nil {
return completion(nil, error)
}
Expand Down Expand Up @@ -246,7 +260,7 @@ public class XDTCards: CanTokenize, CanAuthenticate {
return nil
}

private static func handleCreditCardTokenization(fromViewController: UIViewController, authenticatedToken: XenditAuthenticatedToken?, amount: NSNumber, currency: String?, onBehalfOf: String?, error: XenditError?, completion:@escaping (_ : XenditCCToken?, _ : XenditError?) -> Void) {
private static func handleCreditCardTokenization(fromViewController: UIViewController, authenticatedToken: XenditAuthenticatedToken?, amount: NSNumber, currency: String?, onBehalfOf: String?, cardCvn: String?, error: XenditError?, completion:@escaping (_ : XenditCCToken?, _ : XenditError?) -> Void) {
if let error = error {
// handle error message
if error.errorCode == "INVALID_USER_ID" {
Expand All @@ -265,7 +279,7 @@ public class XDTCards: CanTokenize, CanAuthenticate {
if status != nil {
if status == "IN_REVIEW" {
if CreditCard.is3ds2Version(version: authenticatedToken?.threedsVersion) && jwt != nil {
handleEmv3DSFlow(fromViewController: fromViewController, tokenId: tokenId, environment: authenticatedToken!.environment!, amount: amount, currency: currency, jwt: jwt!, onBehalfOf: onBehalfOf, completion: completion)
handleEmv3DSFlow(fromViewController: fromViewController, tokenId: tokenId, environment: authenticatedToken!.environment!, amount: amount, currency: currency, jwt: jwt!, onBehalfOf: onBehalfOf, cardCvn: cardCvn, completion: completion)
} else if let authenticationURL = authenticatedToken?.authenticationURL {
cardAuthenticationProvider.authenticate(
fromViewController: fromViewController,
Expand All @@ -283,16 +297,16 @@ public class XDTCards: CanTokenize, CanAuthenticate {
}
}

private static func handleEmv3DSFlow(fromViewController: UIViewController, tokenId: String, environment: String, amount: NSNumber, currency: String?, jwt: String, onBehalfOf: String?, completion:@escaping (_ : XenditCCToken?, _ : XenditError?) -> Void) {
private static func handleEmv3DSFlow(fromViewController: UIViewController, tokenId: String, environment: String, amount: NSNumber, currency: String?, jwt: String, onBehalfOf: String?, cardCvn: String?, completion:@escaping (_ : XenditCCToken?, _ : XenditError?) -> Void) {
let cardinalEnvironment = environment == "DEVELOPMENT" ? CardinalSessionEnvironment.staging : CardinalSessionEnvironment.production;
configureCardinal(environment: cardinalEnvironment);
cardinalSession?.setup(jwtString: jwt, completed: {
(sessionId: String) in
createAuthenticationWithSessionId(fromViewController: fromViewController, tokenId: tokenId, sessionId: sessionId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, completion: completion)
createAuthenticationWithSessionId(fromViewController: fromViewController, tokenId: tokenId, sessionId: sessionId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, cardCvn: cardCvn, completion: completion)
}) {
(response : CardinalResponse) in
// Revert to 3DS1 flow
create3DS1Authentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf) { (authentication, error) in
create3DS1Authentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, cardCvn: cardCvn) { (authentication, error) in
if error != nil {
return completion(nil, error)
}
Expand Down
10 changes: 5 additions & 5 deletions Xendit/Xendit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import CardinalMobile
let amount = authenticationRequest.amount
let customer = authenticationRequest.customer
let currency = authenticationRequest.currency
XDTCards.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, customer: customer, completion: completion)
XDTCards.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: currency, onBehalfOf: onBehalfOf, customer: customer, cardCvn: authenticationRequest.cardCvn, completion: completion)
}

@available(*, deprecated, message: "Use createToken(UIViewController, XenditTokenizationRequest, String, Callback) instead")
Expand All @@ -60,19 +60,19 @@ import CardinalMobile
@available(*, deprecated, message: "Use createAuthentication(UIViewController, XenditAuthenticationRequest, Callback) instead")
public static func createAuthentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, onBehalfOf: String, completion:@escaping (_ : XenditAuthentication?, _ : XenditError?) -> Void) {
XDTCards.setup(publishableKey: publishableKey!)
XDTCards.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, onBehalfOf: onBehalfOf, customer: nil, completion: completion)
XDTCards.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: nil, onBehalfOf: onBehalfOf, customer: nil, cardCvn: nil, completion: completion)
}

@available(*, deprecated, message: "Use createAuthentication(UIViewController, XenditAuthenticationRequest, Callback) instead")
public static func createAuthentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, completion:@escaping (_ : XenditAuthentication?, _ : XenditError?) -> Void) {
XDTCards.setup(publishableKey: publishableKey!)
self.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, onBehalfOf: "", completion: completion)
XDTCards.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: nil, onBehalfOf: nil, customer: nil, cardCvn: nil, completion: completion)
}

@available(*, deprecated, message: "Use createAuthentication(UIViewController, XenditAuthenticationRequest, Callback) instead")
public static func createAuthentication(fromViewController: UIViewController, tokenId: String, amount: NSNumber, cardCVN: String, completion:@escaping (_ : XenditAuthentication?, _ : XenditError?) -> Void) {
self.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, completion: completion)
}
XDTCards.setup(publishableKey: publishableKey!)
XDTCards.createAuthentication(fromViewController: fromViewController, tokenId: tokenId, amount: amount, currency: nil, onBehalfOf: nil, customer: nil, cardCvn: cardCVN, completion: completion) }

// Card data validation method
public static func isCardNumberValid(cardNumber: String) -> Bool {
Expand Down

0 comments on commit 6f83794

Please sign in to comment.