Skip to content

Commit

Permalink
[V4] Adding support for iDeal 2.0 (#1690)
Browse files Browse the repository at this point in the history
## Summary
- Changed iDeal to be an InstantPaymentMethod (ignoring the issuers)

## Release Notes
<new>
The new iDEAL payment flow where the shopper is redirected to the iDEAL
payment page to select their bank and authorize the payment.
</new>
  • Loading branch information
goergisn authored May 24, 2024
1 parent 31d4edf commit 1556fc9
Show file tree
Hide file tree
Showing 14 changed files with 45 additions and 55 deletions.
2 changes: 0 additions & 2 deletions .jazzy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ custom_categories:
- name: Issuer List Component
children:
- IssuerListComponent
- IdealComponent
- MOLPayComponent
- DotpayComponent
- EPSComponent
Expand All @@ -229,7 +228,6 @@ custom_categories:
- EPSDetails
- DotpayDetails
- MOLPayDetails
- IdealDetails
- IssuerListDetails

- name: EContext Component
Expand Down
13 changes: 8 additions & 5 deletions Adyen/Core/Payment Methods/AnyPaymentMethodDecoder.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2021 Adyen N.V.
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand Down Expand Up @@ -93,7 +93,6 @@ internal enum AnyPaymentMethodDecoder {
// Supported payment methods
.card: CardPaymentMethodDecoder(),
.scheme: CardPaymentMethodDecoder(),
.ideal: IssuerListPaymentMethodDecoder(),
.entercash: IssuerListPaymentMethodDecoder(),
.eps: IssuerListPaymentMethodDecoder(),
.dotpay: IssuerListPaymentMethodDecoder(),
Expand Down Expand Up @@ -130,11 +129,15 @@ internal enum AnyPaymentMethodDecoder {
internal static func decode(from decoder: Decoder) -> AnyPaymentMethod {
do {
let container = try decoder.container(keyedBy: AnyPaymentMethod.CodingKeys.self)
let type = try container.decode(String.self, forKey: .type)
let type = try PaymentMethodType(rawValue: container.decode(String.self, forKey: .type))
let isStored = decoder.codingPath.contains { $0.stringValue == PaymentMethods.CodingKeys.stored.stringValue }
let brand = try? container.decode(String.self, forKey: .brand)
let isIssuersList = container.contains(.issuers)

if type == .ideal {
return try RedirectPaymentMethodDecoder().decode(from: decoder, isStored: isStored)
}

if isIssuersList {
return try IssuerListPaymentMethodDecoder().decode(from: decoder, isStored: isStored)
}
Expand All @@ -147,11 +150,11 @@ internal enum AnyPaymentMethodDecoder {
// That includes brand, type, isStored, and requiresDetails,
// This matching struct will be used as the key to the decoders
// dictionary.
if isStored, brand == "bcmc", type == "scheme" {
if isStored, brand == "bcmc", type == .scheme {
return try decoders[.bcmc, default: defaultDecoder].decode(from: decoder, isStored: true)
}

let paymentDecoder = PaymentMethodType(rawValue: type).map { decoders[$0, default: defaultDecoder] } ?? defaultDecoder
let paymentDecoder = type.map { decoders[$0, default: defaultDecoder] } ?? defaultDecoder

return try paymentDecoder.decode(from: decoder, isStored: isStored)
} catch {
Expand Down
4 changes: 2 additions & 2 deletions Adyen/Core/Payment Methods/IssuerListPaymentMethod.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//
// Copyright (c) 2021 Adyen N.V.
// 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

/// An issuer list payment method, such as iDEAL or Open Banking.
/// An issuer list payment method, such as Open Banking.
public struct IssuerListPaymentMethod: PaymentMethod {

/// :nodoc:
Expand Down
7 changes: 2 additions & 5 deletions AdyenComponents/Issuer List/IssuerListComponent.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2022 Adyen N.V.
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand All @@ -8,7 +8,7 @@ import Adyen
import Foundation
import UIKit

/// A generic component for "issuer-based" payment methods, such as iDEAL and MOLPay.
/// A generic component for "issuer-based" payment methods, such as MOLPay.
/// This component will provide a list in which the user can select their issuer.
public final class IssuerListComponent: PaymentComponent, PresentableComponent, LoadingComponent {

Expand Down Expand Up @@ -84,9 +84,6 @@ public final class IssuerListComponent: PaymentComponent, PresentableComponent,
}()
}

/// Provides an issuer selection list for iDEAL payments.
public typealias IdealComponent = IssuerListComponent

/// Provides an issuer selection list for MOLPay payments.
public typealias MOLPayComponent = IssuerListComponent

Expand Down
5 changes: 1 addition & 4 deletions AdyenComponents/Issuer List/IssuerListDetails.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2021 Adyen N.V.
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand Down Expand Up @@ -28,9 +28,6 @@ public struct IssuerListDetails: PaymentMethodDetails {

}

/// Contains the details supplied by the IDEAL component.
public typealias IdealDetails = IssuerListDetails

/// Contains the details supplied by the MOLPay component.
public typealias MOLPayDetails = IssuerListDetails

Expand Down
4 changes: 2 additions & 2 deletions Demo/Common/Assets/payment_methods_response.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@
"type" : "select"
}
],
"name" : "iDEAL",
"name" : "Open Banking",
"supportsRecurring" : true,
"type" : "ideal"
"type" : "openbanking_UK"
},
{
"brands" : [
Expand Down
9 changes: 1 addition & 8 deletions Demo/Common/IntegrationExampleComponents.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2022 Adyen N.V.
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand All @@ -22,13 +22,6 @@ extension IntegrationExample {
present(component)
}

internal func presentIdealComponent() {
guard let paymentMethod = paymentMethods?.paymentMethod(ofType: IssuerListPaymentMethod.self) else { return }
let component = IdealComponent(paymentMethod: paymentMethod,
apiContext: apiContext)
present(component)
}

internal func presentSEPADirectDebitComponent() {
guard let paymentMethod = paymentMethods?.paymentMethod(ofType: SEPADirectDebitPaymentMethod.self) else { return }
let component = SEPADirectDebitComponent(paymentMethod: paymentMethod,
Expand Down
7 changes: 1 addition & 6 deletions Demo/SwiftUI/PaymentsViewModel.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2021 Adyen N.V.
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand Down Expand Up @@ -28,10 +28,6 @@ internal final class PaymentsViewModel: ObservableObject, Identifiable, Presente
integrationExample.presentCardComponent()
}

internal func presentIdealComponent() {
integrationExample.presentIdealComponent()
}

internal func presentSEPADirectDebitComponent() {
integrationExample.presentSEPADirectDebitComponent()
}
Expand All @@ -47,7 +43,6 @@ internal final class PaymentsViewModel: ObservableObject, Identifiable, Presente
],
[
ComponentsItem(title: "Card", selectionHandler: presentCardComponent),
ComponentsItem(title: "iDEAL", selectionHandler: presentIdealComponent),
ComponentsItem(title: "SEPA Direct Debit", selectionHandler: presentSEPADirectDebitComponent),
ComponentsItem(title: "MB WAY", selectionHandler: presentMBWayComponent)
]
Expand Down
7 changes: 1 addition & 6 deletions Demo/UIKit/ComponentsViewController.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2021 Adyen N.V.
// Copyright (c) 2024 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand Down Expand Up @@ -33,7 +33,6 @@ internal final class ComponentsViewController: UIViewController, Presenter {
],
[
ComponentsItem(title: "Card", selectionHandler: presentCardComponent),
ComponentsItem(title: "iDEAL", selectionHandler: presentIdealComponent),
ComponentsItem(title: "SEPA Direct Debit", selectionHandler: presentSEPADirectDebitComponent),
ComponentsItem(title: "BACS Direct Debit", selectionHandler: presentBACSDirectDebitComponent),
ComponentsItem(title: "MB WAY", selectionHandler: presentMBWayComponent),
Expand Down Expand Up @@ -61,10 +60,6 @@ internal final class ComponentsViewController: UIViewController, Presenter {
integrationExample.presentCardComponent()
}

internal func presentIdealComponent() {
integrationExample.presentIdealComponent()
}

internal func presentSEPADirectDebitComponent() {
integrationExample.presentSEPADirectDebitComponent()
}
Expand Down
4 changes: 2 additions & 2 deletions Demo/UIKit/PaymentMethods.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@
"type" : "select"
}
],
"name" : "iDEAL",
"name" : "Open Banking",
"supportsRecurring" : true,
"type" : "ideal"
"type" : "openbanking_UK"
},
{
"brands" : [
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ In order to have more flexibility over the checkout flow, you can use our Compon
- [3D Secure 2 Component][reference.threeDS2Component]
- [Apple Pay Component][reference.applePayComponent]
- [BCMC Component][reference.bcmcComponent]
- [iDEAL Component][reference.issuerListComponent]
- [SEPA Direct Debit Component][reference.sepaDirectDebitComponent]
- [MOLPay Component][reference.issuerListComponent]
- [Dotpay Component][reference.issuerListComponent]
Expand Down
20 changes: 14 additions & 6 deletions Tests/AdyenTests/Adyen Tests/Core/PaymentMethodTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class PaymentMethodTests: XCTestCase {
econtextATM,
econtextStores,
econtextOnline,
oxxo
oxxo,
ideal
]
]

Expand Down Expand Up @@ -116,11 +117,14 @@ class PaymentMethodTests: XCTestCase {

// Regular payment methods

XCTAssertEqual(paymentMethods.regular.count, 21)
XCTAssertEqual(paymentMethods.regular.count, 22)
XCTAssertTrue(paymentMethods.regular[0] is CardPaymentMethod)
XCTAssertEqual((paymentMethods.regular[0] as! CardPaymentMethod).fundingSource!, .credit)

XCTAssertTrue(paymentMethods.regular[1] is IssuerListPaymentMethod)
XCTAssertEqual(paymentMethods.regular[1].type, "openbanking_UK")
XCTAssertEqual(paymentMethods.regular[1].name, "Open Banking")

XCTAssertTrue(paymentMethods.regular[2] is SEPADirectDebitPaymentMethod)
XCTAssertTrue(paymentMethods.regular[3] is RedirectPaymentMethod)

Expand Down Expand Up @@ -210,6 +214,10 @@ class PaymentMethodTests: XCTestCase {
XCTAssertTrue(paymentMethods.regular[20] is OXXOPaymentMethod)
XCTAssertEqual(paymentMethods.regular[20].name, "OXXO")
XCTAssertEqual(paymentMethods.regular[20].type, "oxxo")

XCTAssertTrue(paymentMethods.regular[21] is RedirectPaymentMethod)
XCTAssertEqual(paymentMethods.regular[21].name, "iDeal")
XCTAssertEqual(paymentMethods.regular[21].type, "ideal")

}

Expand Down Expand Up @@ -355,8 +363,8 @@ class PaymentMethodTests: XCTestCase {

func testDecodingIssuerListPaymentMethod() throws {
let paymentMethod = try Coder.decode(issuerListDictionary) as IssuerListPaymentMethod
XCTAssertEqual(paymentMethod.type, "ideal")
XCTAssertEqual(paymentMethod.name, "iDEAL")
XCTAssertEqual(paymentMethod.type, "openbanking_UK")
XCTAssertEqual(paymentMethod.name, "Open Banking")

XCTAssertEqual(paymentMethod.issuers.count, 3)
XCTAssertEqual(paymentMethod.issuers[0].identifier, "1121")
Expand All @@ -369,8 +377,8 @@ class PaymentMethodTests: XCTestCase {

func testDecodingIssuerListPaymentMethodWithoutDetailsObject() throws {
let paymentMethod = try Coder.decode(issuerListDictionaryWithoutDetailsObject) as IssuerListPaymentMethod
XCTAssertEqual(paymentMethod.type, "ideal_100")
XCTAssertEqual(paymentMethod.name, "iDEAL_100")
XCTAssertEqual(paymentMethod.type, "openbanking_UK_100")
XCTAssertEqual(paymentMethod.name, "Open_Banking_100")

XCTAssertEqual(paymentMethod.issuers.count, 3)
XCTAssertEqual(paymentMethod.issuers[0].identifier, "1121")
Expand Down
13 changes: 9 additions & 4 deletions Tests/AdyenTests/Adyen Tests/Core/TestPaymentMethodsJson.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ let storedBcmcDictionary = [
] as [String: Any]

let issuerListDictionary = [
"type": "ideal",
"name": "iDEAL",
"type": "openbanking_UK",
"name": "Open Banking",
"details": [
[
"items": [
Expand Down Expand Up @@ -144,8 +144,8 @@ let sevenElevenDictionary = [
] as [String: Any]

let issuerListDictionaryWithoutDetailsObject = [
"type": "ideal_100",
"name": "iDEAL_100",
"type": "openbanking_UK_100",
"name": "Open_Banking_100",
"issuers": [
[
"id": "1121",
Expand Down Expand Up @@ -226,6 +226,11 @@ let oxxo = [
"type": "oxxo"
] as [String: Any]

let ideal = [
"name": "iDeal",
"type": "ideal"
] as [String: Any]

let multibanco = [
"name": "Multibanco",
"type": "multibanco"
Expand Down
4 changes: 2 additions & 2 deletions Tests/AdyenTests/Adyen Tests/DropIn/DropInTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class DropInTests: XCTestCase {
"type" : "select"
}
],
"name" : "iDEAL",
"name" : "Open Banking",
"supportsRecurring" : true,
"type" : "ideal"
"type" : "openbanking_UK"
},
{
"brands" : [ "mc", "visa" ],
Expand Down

0 comments on commit 1556fc9

Please sign in to comment.