diff --git a/CHANGELOG.md b/CHANGELOG.md index d3d2d6249d..16de52ede5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Braintree iOS SDK Release Notes +## unreleased +* BraintreeApplePay + * Add `BTApplePayCardNonce.isDeviceToken` for MPAN identification + ## 6.28.0 (2025-02-05) * BraintreeVenmo * Allow universal links to be set without a return URL scheme (fixes #1505) diff --git a/Sources/BraintreeApplePay/BTApplePayCardNonce.swift b/Sources/BraintreeApplePay/BTApplePayCardNonce.swift index 6861a97504..f20d030c25 100644 --- a/Sources/BraintreeApplePay/BTApplePayCardNonce.swift +++ b/Sources/BraintreeApplePay/BTApplePayCardNonce.swift @@ -10,12 +10,18 @@ import BraintreeCore /// The BIN data for the card number associated with this nonce. public let binData: BTBinData + /// This Boolean indicates whether this tokenized card is a device-specific account number (DPAN) or merchant/cloud token (MPAN). Available on iOS 16+. + /// If `isDeviceToken` is `false`, then token type is MPAN + public var isDeviceToken: Bool + init?(json: BTJSON) { guard let nonce = json["nonce"].asString() else { return nil } let cardType = json["details"]["cardType"].asString() ?? "ApplePayCard" let isDefault = json["default"].isTrue + self.isDeviceToken = json["details"]["isDeviceToken"].asBool() ?? true + binData = BTBinData(json: json["binData"]) super.init(nonce: nonce, type: cardType, isDefault: isDefault) } diff --git a/UnitTests/BraintreeApplePayTests/BTApplePayCardNonce_Tests.swift b/UnitTests/BraintreeApplePayTests/BTApplePayCardNonce_Tests.swift index 36e89ea383..92fe1e9543 100644 --- a/UnitTests/BraintreeApplePayTests/BTApplePayCardNonce_Tests.swift +++ b/UnitTests/BraintreeApplePayTests/BTApplePayCardNonce_Tests.swift @@ -24,6 +24,44 @@ class BTApplePayCardNonce_Tests: XCTestCase { XCTAssertEqual(applePayNonce?.type, "fake-card-type") } + func testInitWithJSON_whenApplePayTokenIsMPAN() { + let applePayCard = BTJSON( + value: [ + "consumed": false, + "binData": [ + "commercial": "yes" + ], + "details": [ + "cardType": "fake-card-type", + "isDeviceToken": false + ], + "nonce": "a-nonce" + ] as [String: Any] + ) + + let applePayNonce = BTApplePayCardNonce(json: applePayCard) + XCTAssertEqual(applePayNonce?.isDeviceToken, false) + } + + func testInitWithJSON_whenApplePayTokenIsDPAN() { + let applePayCard = BTJSON( + value: [ + "consumed": false, + "binData": [ + "commercial": "yes" + ], + "details": [ + "cardType": "fake-card-type", + "isDeviceToken": true + ], + "nonce": "a-nonce" + ] as [String: Any] + ) + + let applePayNonce = BTApplePayCardNonce(json: applePayCard) + XCTAssertEqual(applePayNonce?.isDeviceToken, true) + } + func testInitWithJSON_setsDefaultProperties() { let applePayCard = BTJSON( value: [