Skip to content

Commit

Permalink
Merge branch 'develop' into COIOS-802_identify_native_redirect_flow
Browse files Browse the repository at this point in the history
  • Loading branch information
goergisn authored Nov 25, 2024
2 parents 10e1eab + adb4adf commit 6721b79
Show file tree
Hide file tree
Showing 26 changed files with 737 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .swiftformat
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
--disable blankLinesAtStartOfScope,blankLinesAtEndOfScope,unusedArguments,redundantSelf,wrapMultilineStatementBraces,extensionAccessControl,redundantClosure,redundantInternal,preferForLoop,redundantRawValues
--disable blankLinesAtStartOfScope,blankLinesAtEndOfScope,unusedArguments,redundantSelf,wrapMultilineStatementBraces,extensionAccessControl,redundantClosure,redundantInternal,preferForLoop,redundantRawValues,docCommentsBeforeModifiers
--swiftversion "5.7"
--commas inline
--ranges nospace
Expand Down
50 changes: 50 additions & 0 deletions Adyen.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Adyen/Analytics/AnalyticsProvider/AnalyticsProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ internal final class AnalyticsProvider: AnyAnalyticsProvider {
internal var eventAnalyticsProvider: AnyEventAnalyticsProvider?

private let uniqueAssetAPIClient: UniqueAssetAPIClient<InitialAnalyticsResponse>
private let context: AnalyticsContext
private let configuration: AnalyticsConfiguration

// MARK: - Initializers

internal init(
apiClient: APIClientProtocol,
context: AnalyticsContext,
configuration: AnalyticsConfiguration,
eventAnalyticsProvider: AnyEventAnalyticsProvider?
) {
self.context = context
self.configuration = configuration
self.eventAnalyticsProvider = eventAnalyticsProvider
self.uniqueAssetAPIClient = UniqueAssetAPIClient<InitialAnalyticsResponse>(apiClient: apiClient)
}
Expand All @@ -40,7 +40,7 @@ internal final class AnalyticsProvider: AnyAnalyticsProvider {
let analyticsData = AnalyticsData(
flavor: flavor,
additionalFields: additionalFields,
context: context
configuration: configuration
)

let initialAnalyticsRequest = InitialAnalyticsRequest(data: analyticsData)
Expand Down
17 changes: 17 additions & 0 deletions Adyen/Analytics/Models/AdyenAnalytics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,20 @@ public struct AdditionalAnalyticsFields {
self.sessionId = sessionId
}
}

/// Describes the levels that determine which analytics calls are made.
internal enum AnalyticsLevel: String, Encodable {

/// Indicates all analytics are enabled.
case all

/// Indicates only the initial call is enabled.
case initial
}

extension AnalyticsConfiguration {

internal var analyticsLevel: AnalyticsLevel {
isEnabled ? .all : .initial
}
}
10 changes: 7 additions & 3 deletions Adyen/Analytics/Models/AnalyticsData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,24 @@ internal struct AnalyticsData: Encodable {
internal var paymentMethods: [String] = []

internal let component: String

internal let level: AnalyticsLevel

// MARK: - Initializers

internal init(
flavor: AnalyticsFlavor,
additionalFields: AdditionalAnalyticsFields?,
context: AnalyticsContext
configuration: AnalyticsConfiguration
) {
self.flavor = flavor.value
self.amount = additionalFields?.amount
self.sessionId = additionalFields?.sessionId

self.version = context.version
self.platform = context.platform.rawValue
self.version = configuration.context.version
self.platform = configuration.context.platform.rawValue

self.level = configuration.analyticsLevel

switch flavor {
case let .dropIn(type, paymentMethods):
Expand Down
3 changes: 3 additions & 0 deletions Adyen/Analytics/Requests/InitialAnalyticsRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ internal struct InitialAnalyticsRequest: APIRequest {
private let containerWidth: Int?
private let paymentMethods: [String]
private let component: String
internal let level: String
internal let amount: Amount?
internal let sessionId: String?

Expand All @@ -67,6 +68,7 @@ internal struct InitialAnalyticsRequest: APIRequest {
self.containerWidth = data.containerWidth
self.paymentMethods = data.paymentMethods
self.component = data.component
self.level = data.level.rawValue
self.amount = data.amount
self.sessionId = data.sessionId
}
Expand All @@ -86,6 +88,7 @@ internal struct InitialAnalyticsRequest: APIRequest {
case containerWidth
case paymentMethods
case component
case level
case amount
case sessionId
}
Expand Down
8 changes: 8 additions & 0 deletions Adyen/Assets/Generated/LocalizationKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,14 @@ public struct LocalizationKey {
public static let paybybankTitle = LocalizationKey(key: "adyen.paybybank.title")
/// Search…
public static let searchPlaceholder = LocalizationKey(key: "adyen.search.placeholder")
/// Use Pay by Bank to pay instantly from any bank account.
public static let payByBankAISDDDisclaimerHeader = LocalizationKey(key: "adyen.payByBankAISDD.disclaimer.header")
/// By connecting your bank account you are authorizing debits to your account for any amount owed for use of our services and/or purchase of our products, until this authorization is revoked.
public static let payByBankAISDDDisclaimerBody = LocalizationKey(key: "adyen.payByBankAISDD.disclaimer.body")
/// Continue to Pay by Bank
public static let payByBankAISDDSubmit = LocalizationKey(key: "adyen.payByBankAISDD.submit")
/// + more
public static let payByBankAISDDMore = LocalizationKey(key: "adyen.payByBankAISDD.more")
/// How would you like to use UPI?
public static let upiModeSelection = LocalizationKey(key: "adyen.upi.modeSelection")
/// Enter a correct virtual payment address
Expand Down
2 changes: 1 addition & 1 deletion Adyen/Core/AdyenContext/AdyenContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public final class AdyenContext: PaymentAware {

return AnalyticsProvider(
apiClient: APIClient(apiContext: analyticsApiContext),
context: analyticsConfiguration.context,
configuration: analyticsConfiguration,
eventAnalyticsProvider: eventAnalyticsProvider
)
}
Expand Down
3 changes: 3 additions & 0 deletions Adyen/Core/Core Protocols/PaymentComponentBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ public protocol PaymentComponentBuilder: AdyenContextAware {

/// Builds a certain `PaymentComponent` based on a `StoredTwintPaymentMethod`.
func build(paymentMethod: StoredTwintPaymentMethod) -> PaymentComponent?

/// Builds a certain `PaymentComponent` based on a `PayByBankUSPaymentMethod`.
func build(paymentMethod: PayByBankUSPaymentMethod) -> PaymentComponent?

/// Builds a certain `PaymentComponent` based on any `PaymentMethod`, as a default case.
func build(paymentMethod: PaymentMethod) -> PaymentComponent?
Expand Down
6 changes: 5 additions & 1 deletion Adyen/Core/Payment Methods/Abstract/AnyPaymentMethod.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ internal enum AnyPaymentMethod: Codable {
case storedPayPal(StoredPayPalPaymentMethod)
case storedBCMC(StoredBCMCPaymentMethod)
case storedBlik(StoredBLIKPaymentMethod)
case storedPayByBankUS(StoredPayByBankUSPaymentMethod)
case storedAchDirectDebit(StoredACHDirectDebitPaymentMethod)
case storedCashAppPay(StoredCashAppPayPaymentMethod)
case storedTwint(StoredTwintPaymentMethod)
Expand Down Expand Up @@ -41,6 +42,7 @@ internal enum AnyPaymentMethod: Codable {
case upi(UPIPaymentMethod)
case cashAppPay(CashAppPayPaymentMethod)
case twint(TwintPaymentMethod)
case payByBankUS(PayByBankUSPaymentMethod)

case none

Expand Down Expand Up @@ -79,12 +81,14 @@ internal enum AnyPaymentMethod: Codable {
case let .upi(paymentMethod): return paymentMethod
case let .cashAppPay(paymentMethod): return paymentMethod
case let .twint(paymentMethod): return paymentMethod
case let .storedPayByBankUS(paymentMethod): return paymentMethod
case let .payByBankUS(paymentMethod): return paymentMethod
case .none: return nil
}
}

// MARK: - Decoding

internal init(from decoder: Decoder) throws {
self = AnyPaymentMethodDecoder.decode(from: decoder)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ internal enum AnyPaymentMethodDecoder {
.onlineBankingSK: OnlineBankingPaymentMethodDecoder(),
.upi: UPIPaymentMethodDecoder(),
.cashAppPay: CashAppPayPaymentMethodDecoder(),
.twint: TwintPaymentMethodDecoder()
.twint: TwintPaymentMethodDecoder(),
.payByBankAISDD: PayByBankUSPaymentMethodDecoder()
]

private static var defaultDecoder: PaymentMethodDecoder = InstantPaymentMethodDecoder()
Expand Down Expand Up @@ -341,6 +342,26 @@ private struct BLIKPaymentMethodDecoder: PaymentMethodDecoder {
}
}

private struct PayByBankUSPaymentMethodDecoder: PaymentMethodDecoder {
func decode(from decoder: Decoder, isStored: Bool) throws -> AnyPaymentMethod {
if isStored {
return try .storedPayByBankUS(.init(from: decoder))
} else {
return try .payByBankUS(.init(from: decoder))
}
}

func anyPaymentMethod(from paymentMethod: any PaymentMethod) -> AnyPaymentMethod? {
if let method = paymentMethod as? StoredPayByBankUSPaymentMethod {
return .storedPayByBankUS(method)
}
if let method = paymentMethod as? PayByBankUSPaymentMethod {
return .payByBankUS(method)
}
return nil
}
}

private struct DokuPaymentMethodDecoder: PaymentMethodDecoder {
func decode(from decoder: Decoder, isStored: Bool) throws -> AnyPaymentMethod {
try .doku(DokuPaymentMethod(from: decoder))
Expand Down
4 changes: 4 additions & 0 deletions Adyen/Core/Payment Methods/Abstract/PaymentMethodType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public enum PaymentMethodType: RawRepresentable, Hashable, Codable {
case upi
case cashAppPay
case twint
case payByBankAISDD
case other(String)

// Unsupported
Expand Down Expand Up @@ -129,6 +130,7 @@ public enum PaymentMethodType: RawRepresentable, Hashable, Codable {
case "cashapp": self = .cashAppPay
case "bizum": self = .bizum
case "twint": self = .twint
case "paybybank_AIS_DD": self = .payByBankAISDD
default: self = .other(rawValue)
}
}
Expand Down Expand Up @@ -191,6 +193,7 @@ public enum PaymentMethodType: RawRepresentable, Hashable, Codable {
case .cashAppPay: return "cashapp"
case .bizum: return "bizum"
case .twint: return "twint"
case .payByBankAISDD: return "paybybank_AIS_DD"
case let .other(value): return value
}
}
Expand Down Expand Up @@ -260,6 +263,7 @@ extension PaymentMethodType {
case .cashAppPay: return "cash app"
case .bizum: return "bizum"
case .twint: return "twint"
case .payByBankAISDD: return "Pay By Bank Direct Debit"
case let .other(name): return name.replacingOccurrences(of: "_", with: " ")
}
}
Expand Down
44 changes: 44 additions & 0 deletions Adyen/Core/Payment Methods/PayByBankUSPaymentMethod.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import Foundation

/// PayByBank US payment method.
public struct PayByBankUSPaymentMethod: PaymentMethod {
public let type: PaymentMethodType

public var name: String

public var merchantProvidedDisplayInformation: MerchantCustomDisplayInformation?

@_spi(AdyenInternal)
public static var logoNames: [String] {
["US-1", "US-2", "US-3", "US-4"]
}

public func defaultDisplayInformation(using parameters: LocalizationParameters?) -> DisplayInformation {
.init(
title: name,
subtitle: nil,
logoName: type.rawValue,
trailingInfo: .logos(
named: Self.logoNames,
trailingText: "+"
),
accessibilityLabel: name
)
}

@_spi(AdyenInternal)
public func buildComponent(using builder: PaymentComponentBuilder) -> PaymentComponent? {
builder.build(paymentMethod: self)
}

private enum CodingKeys: String, CodingKey {
case type
case name
}
}
55 changes: 55 additions & 0 deletions Adyen/Core/Payment Methods/StoredPayByBankUSPaymentMethod.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import Foundation

/// Stored PayByBank US payment method.
public struct StoredPayByBankUSPaymentMethod: StoredPaymentMethod {

public let type: PaymentMethodType

public let name: String

public let label: String?

public var merchantProvidedDisplayInformation: MerchantCustomDisplayInformation?

public let identifier: String

public let supportedShopperInteractions: [ShopperInteraction]

@_spi(AdyenInternal)
public func buildComponent(using builder: PaymentComponentBuilder) -> PaymentComponent? {
builder.build(paymentMethod: self)
}

@_spi(AdyenInternal)
public func defaultDisplayInformation(using parameters: LocalizationParameters?) -> DisplayInformation {
let title: String
let subtitle: String?

if let label {
title = label
subtitle = name
} else {
title = name
subtitle = nil
}

return DisplayInformation(title: title, subtitle: subtitle, logoName: type.rawValue)
}

// MARK: - Decoding

private enum CodingKeys: String, CodingKey {
case type
case name
case label
case identifier = "id"
case supportedShopperInteractions
}

}
3 changes: 2 additions & 1 deletion Adyen/Helpers/UIImageViewHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public extension AdyenScope where Base: UIImageView {
/// Applies given `ImageStyle` to the UIImageView
/// Sets `translatesAutoresizingMaskIntoConstraints` to `false`
/// - Parameter style: `ImageStyle` to be applied
internal func apply(_ style: ImageStyle) {
@_spi(AdyenInternal)
func apply(_ style: ImageStyle) {
round(using: style.cornerRounding)
base.layer.borderColor = style.borderColor?.cgColor
base.layer.borderWidth = style.borderWidth
Expand Down
3 changes: 2 additions & 1 deletion Adyen/Helpers/UILabelHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public extension AdyenScope where Base: UILabel {
/// Applies given `TextStyle` to the UILabel
/// Sets `adjustsFontForContentSizeCategory` to `true`
/// - Parameter style: `TextStyle` to be applied
internal func apply(_ style: TextStyle) {
@_spi(AdyenInternal)
func apply(_ style: TextStyle) {
base.font = style.font
base.textColor = style.color
base.textAlignment = style.textAlignment
Expand Down
Loading

0 comments on commit 6721b79

Please sign in to comment.