diff --git a/Stripe/StripeiOSTests/STPPaymentMethodBillingDetailsTests+Link.swift b/Stripe/StripeiOSTests/STPPaymentMethodBillingDetailsTests+Link.swift index c7274014204..10b6bd7536b 100644 --- a/Stripe/StripeiOSTests/STPPaymentMethodBillingDetailsTests+Link.swift +++ b/Stripe/StripeiOSTests/STPPaymentMethodBillingDetailsTests+Link.swift @@ -5,6 +5,8 @@ // Created by Eduardo Urias on 2/27/23. // +@_spi(STP) import StripeCore +@_spi(STP) import StripePayments @testable import StripePaymentSheet import XCTest @@ -38,4 +40,23 @@ final class STPPaymentMethodBillingDetailsTests: XCTestCase { XCTAssertNil(params["state"]) XCTAssertNil(params["country"]) } + + func testCreateLinkBillingAddress() { + let billingAddress = BillingAddress( + name: "Name", + line1: "Line 1", + line2: "Line 2", + city: "City", + state: "State", + countryCode: "Country" + ) + let billingDetails = STPPaymentMethodBillingDetails.init(billingAddress: billingAddress, email: "email@email.com")! + XCTAssertEqual(billingDetails.name, "Name") + XCTAssertEqual(billingDetails.address?.line1, "Line 1") + XCTAssertEqual(billingDetails.address?.line2, "Line 2") + XCTAssertEqual(billingDetails.address?.city, "City") + XCTAssertEqual(billingDetails.address?.state, "State") + XCTAssertEqual(billingDetails.address?.country, "Country") + XCTAssertEqual(billingDetails.email, "email@email.com") + } } diff --git a/StripeCore/StripeCore/Source/Connections Bindings/BillingAddress.swift b/StripeCore/StripeCore/Source/Connections Bindings/BillingAddress.swift index 71a51d4a252..da8a12b216d 100644 --- a/StripeCore/StripeCore/Source/Connections Bindings/BillingAddress.swift +++ b/StripeCore/StripeCore/Source/Connections Bindings/BillingAddress.swift @@ -7,14 +7,14 @@ import Foundation -@_spi(STP) public struct BillingAddress: Encodable { - let name: String? - let line1: String? - let line2: String? - let city: String? - let state: String? - let postalCode: String? - let countryCode: String? +@_spi(STP) public struct BillingAddress: Codable { + @_spi(STP) public let name: String? + @_spi(STP) public let line1: String? + @_spi(STP) public let line2: String? + @_spi(STP) public let city: String? + @_spi(STP) public let state: String? + @_spi(STP) public let postalCode: String? + @_spi(STP) public let countryCode: String? @_spi(STP) public init( name: String? = nil, diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Helpers/PaymentSheetLinkAccount.swift b/StripePaymentSheet/StripePaymentSheet/Source/Helpers/PaymentSheetLinkAccount.swift index d454991867e..396a7a715c5 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Helpers/PaymentSheetLinkAccount.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Helpers/PaymentSheetLinkAccount.swift @@ -483,11 +483,12 @@ extension PaymentSheetLinkAccount { /// - Returns: Payment method params for paying with Link. func makePaymentMethodParams(from paymentDetails: ConsumerPaymentDetails, cvc: String?) -> STPPaymentMethodParams? { guard let currentSession = currentSession else { - assertionFailure("Cannot make payment method params without an active session.") + stpAssertionFailure("Cannot make payment method params without an active session.") return nil } let params = STPPaymentMethodParams(type: .link) + params.billingDetails = STPPaymentMethodBillingDetails(billingAddress: paymentDetails.billingAddress, email: paymentDetails.billingEmailAddress) params.link?.paymentDetailsID = paymentDetails.stripeID params.link?.credentials = ["consumer_session_client_secret": currentSession.clientSecret] diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/API Bindings/Link/PaymentDetails.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/API Bindings/Link/PaymentDetails.swift index 5ef8cd682d4..2688d487de9 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/API Bindings/Link/PaymentDetails.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/API Bindings/Link/PaymentDetails.swift @@ -21,26 +21,34 @@ typealias ConsumerSessionWithPaymentDetails = (session: ConsumerSession, payment final class ConsumerPaymentDetails: Decodable { let stripeID: String let details: Details + let billingAddress: BillingAddress? + let billingEmailAddress: String? var isDefault: Bool - // TODO(link) : Billing address - init(stripeID: String, details: Details, + billingAddress: BillingAddress?, + billingEmailAddress: String?, isDefault: Bool) { self.stripeID = stripeID self.details = details + self.billingAddress = billingAddress + self.billingEmailAddress = billingEmailAddress self.isDefault = isDefault } private enum CodingKeys: String, CodingKey { case stripeID = "id" + case billingAddress = "billing_address" + case billingEmailAddress = "billing_email_address" case isDefault } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.stripeID = try container.decode(String.self, forKey: .stripeID) + self.billingAddress = try? container.decode(BillingAddress.self, forKey: .billingAddress) + self.billingEmailAddress = try? container.decode(String.self, forKey: .billingEmailAddress) // The payment details are included in the dictionary, so we pass the whole dict to Details self.details = try decoder.singleValueContainer().decode(Details.self) self.isDefault = try container.decode(Bool.self, forKey: .isDefault) diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Components/PaymentMethodPicker/LinkPaymentMethodPicker-CellContentView.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Components/PaymentMethodPicker/LinkPaymentMethodPicker-CellContentView.swift index 5fe2fe5bcc5..47fed359fe4 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Components/PaymentMethodPicker/LinkPaymentMethodPicker-CellContentView.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Components/PaymentMethodPicker/LinkPaymentMethodPicker-CellContentView.swift @@ -6,6 +6,7 @@ // Copyright © 2021 Stripe, Inc. All rights reserved. // +@_spi(STP) import StripePayments @_spi(STP) import StripePaymentsUI @_spi(STP) import StripeUICore import UIKit @@ -22,10 +23,8 @@ extension LinkPaymentMethodPicker { var paymentMethod: ConsumerPaymentDetails? { didSet { switch paymentMethod?.details { - case .card: -// TODO(link): Needs refactor -// case .card(let card): -// cardBrandView.cardBrand = card.stpBrand + case .card(let card): + cardBrandView.setCardBrand(STPCard.brand(from: card.brand)) bankIconView.isHidden = true cardBrandView.isHidden = false primaryLabel.text = paymentMethod?.paymentSheetLabel diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-NewPaymentViewController.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-NewPaymentViewController.swift index 99059fde799..2921f241d40 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-NewPaymentViewController.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-NewPaymentViewController.swift @@ -92,16 +92,13 @@ extension PayWithLinkViewController { var configuration = context.configuration configuration.linkPaymentMethodsOnly = true configuration.appearance = LinkUI.appearance - // TODO(link): Update elementsSession, formCache, analyticsHelper, and paymentMethodTypes - assertionFailure("Not yet implemented") return AddPaymentMethodViewController( intent: context.intent, - // TODO(link): Update elementsSession - elementsSession: .makeBackupElementsSession(allResponseFields: [:], paymentMethodTypes: []), + elementsSession: context.elementsSession, configuration: configuration, paymentMethodTypes: [.stripe(.card)], - formCache: .init(), - analyticsHelper: .init(integrationShape: .complete, configuration: configuration), + formCache: .init(), // We don't want to share a form cache with the containing PaymentSheet + analyticsHelper: context.analyticsHelper, delegate: self ) }() diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-SignUpViewController.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-SignUpViewController.swift index 054cb4b0cd4..fba6663cc79 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-SignUpViewController.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController-SignUpViewController.swift @@ -222,9 +222,8 @@ extension PayWithLinkViewController { case .success(let account): self?.coordinator?.accountUpdated(account) STPAnalyticsClient.sharedClient.logLinkSignupComplete() - case .failure: break -// TODO(link): Fix signup failure logging -// STPAnalyticsClient.sharedClient.logLinkSignupFailure() + case .failure(let error): + STPAnalyticsClient.sharedClient.logLinkSignupFailure(error: error) } self?.signUpButton.isLoading = false diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController.swift index 4d149b5cfd0..3c5832e4466 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Controllers/PayWithLinkViewController.swift @@ -68,6 +68,7 @@ final class PayWithLinkViewController: UINavigationController { let shouldFinishOnClose: Bool let callToAction: ConfirmButton.CallToActionType var lastAddedPaymentDetails: ConsumerPaymentDetails? + var analyticsHelper: PaymentSheetAnalyticsHelper /// Creates a new Context object. /// - Parameters: @@ -77,13 +78,15 @@ final class PayWithLinkViewController: UINavigationController { /// - shouldOfferApplePay: Whether or not to show Apple Pay as a payment option. /// - shouldFinishOnClose: Whether or not Link should finish with `.canceled` result instead of returning to Payment Sheet when the close button is tapped. /// - callToAction: A custom CTA to display on the confirm button. If `nil`, will display `intent`'s default CTA. + /// - analyticsHelper: An instance of `AnalyticsHelper` to use for logging. init( intent: Intent, elementsSession: STPElementsSession, configuration: PaymentSheet.Configuration, shouldOfferApplePay: Bool, shouldFinishOnClose: Bool, - callToAction: ConfirmButton.CallToActionType? + callToAction: ConfirmButton.CallToActionType?, + analyticsHelper: PaymentSheetAnalyticsHelper ) { self.intent = intent self.elementsSession = elementsSession @@ -91,6 +94,7 @@ final class PayWithLinkViewController: UINavigationController { self.shouldOfferApplePay = shouldOfferApplePay self.shouldFinishOnClose = shouldFinishOnClose self.callToAction = callToAction ?? intent.callToAction + self.analyticsHelper = analyticsHelper } } @@ -118,7 +122,8 @@ final class PayWithLinkViewController: UINavigationController { configuration: PaymentSheet.Configuration, shouldOfferApplePay: Bool = false, shouldFinishOnClose: Bool = false, - callToAction: ConfirmButton.CallToActionType? = nil + callToAction: ConfirmButton.CallToActionType? = nil, + analyticsHelper: PaymentSheetAnalyticsHelper ) { self.init( context: Context( @@ -127,7 +132,8 @@ final class PayWithLinkViewController: UINavigationController { configuration: configuration, shouldOfferApplePay: shouldOfferApplePay, shouldFinishOnClose: shouldFinishOnClose, - callToAction: callToAction + callToAction: callToAction, + analyticsHelper: analyticsHelper ) ) } diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Elements/LinkCardEditElement.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Elements/LinkCardEditElement.swift index ca756197344..0150c3c7182 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Elements/LinkCardEditElement.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Elements/LinkCardEditElement.swift @@ -12,7 +12,6 @@ @_spi(STP) import StripeUICore import UIKit -// TODO(link): Remove after migrating to modern bindings fileprivate extension ConsumerPaymentDetails { var cardDetails: Details.Card? { switch details { @@ -167,8 +166,10 @@ final class LinkCardEditElement: Element { private lazy var billingAddressSection: AddressSectionElement? = { guard configuration.billingDetailsCollectionConfiguration.address != .never else { return nil } + let defaultBillingAddress = AddressSectionElement.AddressDetails(billingAddress: paymentMethod.billingAddress ?? .init(), phone: nil) return AddressSectionElement( title: String.Localized.billing_address_lowercase, + defaults: defaultBillingAddress, collectionMode: configuration.billingDetailsCollectionConfiguration.address == .full ? .all() : .countryAndPostal(), diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Extensions/ConfirmButton+Link.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Extensions/ConfirmButton+Link.swift index ab6795a9c91..f4e099479ec 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Extensions/ConfirmButton+Link.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/Extensions/ConfirmButton+Link.swift @@ -21,14 +21,6 @@ extension ConfirmButton { didTap: didTap ) - // Override the background color of the `.succeeded` state. Make it match - // the background color of the `.enabled` state. - // TODO(link): Needs refactor -// button.succeededBackgroundColor = ( -// LinkUI.appearance.primaryButton.backgroundColor ?? -// LinkUI.appearance.colors.primary -// ) - button.directionalLayoutMargins = compact ? LinkUI.compactButtonMargins : LinkUI.buttonMargins diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/LinkUI.swift b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/LinkUI.swift index 671a5704f4f..84065acae5b 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/LinkUI.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/Internal/Link/LinkUI.swift @@ -168,6 +168,7 @@ extension LinkUI { // Primary button appearance.primaryButton.textColor = .linkPrimaryButtonForeground appearance.primaryButton.backgroundColor = .linkBrand + appearance.primaryButton.successBackgroundColor = .linkBrand appearance.primaryButton.borderWidth = 0 appearance.primaryButton.cornerRadius = LinkUI.cornerRadius appearance.primaryButton.font = LinkUI.font(forTextStyle: .bodyEmphasized) diff --git a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Link/PaymentSheet-LinkConfirmOption.swift b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Link/PaymentSheet-LinkConfirmOption.swift index 62ad5969a94..45176ef9180 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Link/PaymentSheet-LinkConfirmOption.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Link/PaymentSheet-LinkConfirmOption.swift @@ -87,10 +87,8 @@ extension PaymentSheet.LinkConfirmOption { return intentConfirmParams.paymentMethodParams.billingDetails case .withPaymentMethod(let paymentMethod): return paymentMethod.billingDetails - case .withPaymentDetails: -// TODO(link): Implement .billingDetails -// return paymentDetails.billingDetails - return nil + case .withPaymentDetails(_, let paymentDetails): + return STPPaymentMethodBillingDetails(billingAddress: paymentDetails.billingAddress, email: paymentDetails.billingEmailAddress) case .withPaymentMethodParams(_, let paymentMethodParams): return paymentMethodParams.billingDetails } diff --git a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+API.swift b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+API.swift index e8c92a38432..91b9a541f08 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+API.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+API.swift @@ -437,10 +437,10 @@ extension PaymentSheet { case .withPaymentMethod(let paymentMethod): confirmWithPaymentMethod(paymentMethod, nil, false) case .withPaymentDetails(let linkAccount, let paymentDetails): -// TODO(link): Confirm the last two options should be "nil" and "false" - confirmWithPaymentDetails(linkAccount, paymentDetails, nil, false) + // shouldSave is false, as we don't show a save checkbox in the Link VC + confirmWithPaymentDetails(linkAccount, paymentDetails, paymentDetails.cvc, false) case .withPaymentMethodParams(let linkAccount, let paymentMethodParams): -// TODO(link): Confirm the last two options should be "nil" and "false" + // shouldSave is false, as we don't show a save checkbox in the Link VC createPaymentDetailsAndConfirm(linkAccount, paymentMethodParams, false) } case let .external(paymentMethod, billingDetails): diff --git a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+Link.swift b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+Link.swift index 6f8160f7bca..4893ff4a80f 100644 --- a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+Link.swift +++ b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheet+Link.swift @@ -71,7 +71,8 @@ extension PaymentSheet { elementsSession: elementsSession, configuration: configuration, shouldOfferApplePay: shouldOfferApplePay, - shouldFinishOnClose: shouldFinishOnClose + shouldFinishOnClose: shouldFinishOnClose, + analyticsHelper: self.analyticsHelper ) payWithLinkVC.payWithLinkDelegate = self diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/LinkCardEditElementSnapshotTests.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/LinkCardEditElementSnapshotTests.swift index ded3d7b0db0..894e1bc373b 100644 --- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/LinkCardEditElementSnapshotTests.swift +++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/LinkCardEditElementSnapshotTests.swift @@ -64,6 +64,8 @@ extension LinkCardEditElementSnapshotTests { checks: nil ) ), + billingAddress: nil, + billingEmailAddress: nil, isDefault: isDefault ) diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/PayWithLinkViewController-WalletViewModelTests.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/PayWithLinkViewController-WalletViewModelTests.swift index f701a1aff5c..5bc01d97f04 100644 --- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/PayWithLinkViewController-WalletViewModelTests.swift +++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/Link/PayWithLinkViewController-WalletViewModelTests.swift @@ -139,7 +139,8 @@ extension PayWithLinkViewController_WalletViewModelTests { configuration: .init(), shouldOfferApplePay: false, shouldFinishOnClose: false, - callToAction: nil + callToAction: nil, + analyticsHelper: ._testValue() ), paymentMethods: LinkStubs.paymentMethods() ) diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/LinkStubs.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/LinkStubs.swift index 4dcec786c77..718bf030b0f 100644 --- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/LinkStubs.swift +++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/LinkStubs.swift @@ -38,6 +38,8 @@ extension LinkStubs { last4: "1234", checks: nil) ), + billingAddress: nil, + billingEmailAddress: nil, isDefault: true ), ConsumerPaymentDetails( @@ -49,11 +51,15 @@ extension LinkStubs { last4: "4321", checks: .init(cvcCheck: .fail)) ), + billingAddress: nil, + billingEmailAddress: nil, isDefault: false ), ConsumerPaymentDetails( stripeID: "3", details: .bankAccount(bankAccount: .init(iconCode: nil, name: "test", last4: "1234")), + billingAddress: nil, + billingEmailAddress: nil, isDefault: false ), ConsumerPaymentDetails( @@ -65,6 +71,8 @@ extension LinkStubs { last4: "1111", checks: nil) ), + billingAddress: nil, + billingEmailAddress: nil, isDefault: false ), ] diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetLinkAccountTests.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetLinkAccountTests.swift index 9dbcba74315..df3dba98f9d 100644 --- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetLinkAccountTests.swift +++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetLinkAccountTests.swift @@ -55,6 +55,8 @@ extension PaymentSheetLinkAccountTests { return ConsumerPaymentDetails( stripeID: "1", details: .card(card: .init(expiryYear: 30, expiryMonth: 10, brand: "visa", last4: "1234", checks: nil)), + billingAddress: nil, + billingEmailAddress: nil, isDefault: false ) } diff --git a/StripePayments/StripePayments/Source/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift b/StripePayments/StripePayments/Source/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift index 2b6c8896824..b622687564b 100644 --- a/StripePayments/StripePayments/Source/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift +++ b/StripePayments/StripePayments/Source/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift @@ -130,4 +130,22 @@ extension STPPaymentMethodBillingDetails { address.country = countryCode self.address = address } + + /// Convenience initializer for creating an `STPPaymentMethodBillingDetails` instance with a Link BillingDetails + @_spi(STP) public convenience init?( + billingAddress: BillingAddress?, + email: String? + ) { + self.init() + let address = STPPaymentMethodAddress() + address.line1 = billingAddress?.line1 + address.line2 = billingAddress?.line2 + address.city = billingAddress?.city + address.state = billingAddress?.state + address.postalCode = billingAddress?.postalCode + address.country = billingAddress?.countryCode + self.address = address + self.name = billingAddress?.name + self.email = email + } } diff --git a/StripePaymentsUI/StripePaymentsUI/Source/Internal/UI/Views/CardBrandView.swift b/StripePaymentsUI/StripePaymentsUI/Source/Internal/UI/Views/CardBrandView.swift index d94c880aaba..d0669b79110 100644 --- a/StripePaymentsUI/StripePaymentsUI/Source/Internal/UI/Views/CardBrandView.swift +++ b/StripePaymentsUI/StripePaymentsUI/Source/Internal/UI/Views/CardBrandView.swift @@ -182,6 +182,10 @@ import UIKit fatalError("init(coder:) has not been implemented") } + @_spi(STP) public func setCardBrand(_ brand: STPCardBrand) { + setCardBrand(.brand(brand), animated: false) + } + /// Updates the card brand, optionally animating the transition. /// - Parameters: /// - newBrandState: New card brand state. diff --git a/StripeUICore/StripeUICore/Source/Elements/Factories/Address/AddressSectionElement.swift b/StripeUICore/StripeUICore/Source/Elements/Factories/Address/AddressSectionElement.swift index 0cc08e89302..b8dfebcc647 100644 --- a/StripeUICore/StripeUICore/Source/Elements/Factories/Address/AddressSectionElement.swift +++ b/StripeUICore/StripeUICore/Source/Elements/Factories/Address/AddressSectionElement.swift @@ -441,3 +441,20 @@ extension AddressSectionElement: ElementDelegate { } } } + +@_spi(STP) public extension AddressSectionElement.AddressDetails { + init(billingAddress: BillingAddress, phone: String?) { + self.init( + name: billingAddress.name, + phone: phone, + address: Address( + city: billingAddress.city, + country: billingAddress.countryCode, + line1: billingAddress.line1, + line2: billingAddress.line2, + postalCode: billingAddress.postalCode, + state: billingAddress.state + ) + ) + } +} diff --git a/StripeUICore/StripeUICoreTests/Unit/Elements/AddressSectionElementTest.swift b/StripeUICore/StripeUICoreTests/Unit/Elements/AddressSectionElementTest.swift index 22ec2e392fc..bd0c6992abe 100644 --- a/StripeUICore/StripeUICoreTests/Unit/Elements/AddressSectionElementTest.swift +++ b/StripeUICore/StripeUICoreTests/Unit/Elements/AddressSectionElementTest.swift @@ -6,6 +6,7 @@ // Copyright © 2021 Stripe, Inc. All rights reserved. // +@_spi(STP) @testable import StripeCore @_spi(STP) @testable import StripeUICore import XCTest @@ -230,4 +231,25 @@ class AddressSectionElementTest: XCTestCase { sut.country.select(index: 0) XCTAssertNotEqual(sut.country.selectedIndex, sut.phone?.countryDropdownElement.selectedIndex) } + + func testConvertLinkBillingAddressToAddressDetails() { + let linkBillingDetails = BillingAddress( + name: "Test Testerson", + line1: "123 Main St", + line2: "Apt 4", + city: "San Francisco", + state: "CA", + postalCode: "94102", + countryCode: "US" + ) + let addressDetails = AddressSectionElement.AddressDetails(billingAddress: linkBillingDetails, phone: "+1231231234") + XCTAssertEqual(addressDetails.name, linkBillingDetails.name) + XCTAssertEqual(addressDetails.phone, "+1231231234") + XCTAssertEqual(addressDetails.address.city, linkBillingDetails.city) + XCTAssertEqual(addressDetails.address.country, linkBillingDetails.countryCode) + XCTAssertEqual(addressDetails.address.line1, linkBillingDetails.line1) + XCTAssertEqual(addressDetails.address.line2, linkBillingDetails.line2) + XCTAssertEqual(addressDetails.address.postalCode, linkBillingDetails.postalCode) + XCTAssertEqual(addressDetails.address.state, linkBillingDetails.state) + } } diff --git a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testExpanded@3x.png b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testExpanded@3x.png index 9703d37c31b..b17d3a0119b 100644 Binary files a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testExpanded@3x.png and b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testExpanded@3x.png differ diff --git a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_First_Option@3x.png b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_First_Option@3x.png index 31861aa3354..2c5f51547a2 100644 Binary files a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_First_Option@3x.png and b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_First_Option@3x.png differ diff --git a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_Second_Option@3x.png b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_Second_Option@3x.png index 50b5afa1ed5..52f00f7ef02 100644 Binary files a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_Second_Option@3x.png and b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testNormal_Second_Option@3x.png differ diff --git a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testUnsupportedBankAccount@3x.png b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testUnsupportedBankAccount@3x.png index 4498759c7c9..a1ac830e281 100644 Binary files a/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testUnsupportedBankAccount@3x.png and b/Tests/ReferenceImages_64/StripePaymentSheetTests.LinkPaymentMethodPickerSnapshotTests/testUnsupportedBankAccount@3x.png differ