Skip to content

* [EACQAPW-5625] Added Card Options to pass DATA field in /AttachCard #509

Merged
merged 2 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions ASDKSample/ASDKSample/BuyProductsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class BuyProductsViewController: UIViewController {
private var rebillCards: [PaymentCard] { activeCards.filter { $0.parentPaymentId != nil } }
private var activeCards = [PaymentCard]()

private lazy var cardsController = uiSDK.cardsController(customerKey: customerKey)
private lazy var cardsController = uiSDK.cardsController(customerKey: customerKey, addCardOptions: .cardOptions)

@IBOutlet var tableView: UITableView!
@IBOutlet var buttonAddToCart: UIBarButtonItem!
Expand Down Expand Up @@ -615,13 +615,13 @@ private extension PaymentOptions {
}

var initAddData = initData.additionalData ?? .empty()
initAddData.merging(["/InitKey": "/InitValue"])
initAddData.merging(AdditionalData.paymentInit)

return PaymentOptions(
orderOptions: orderOptions,
customerOptions: customerOptions,
paymentInitData: initAddData,
paymentFinishData: AdditionalData(data: ["/FinishKey": "/FinishValue"])
paymentFinishData: .paymentFinish
)
}
}
Expand Down Expand Up @@ -651,3 +651,8 @@ extension PaymentResult {
}
}
}

extension AdditionalData {
static let paymentInit = AdditionalData(data: ["/InitKey": "/InitValue"])
static let paymentFinish = AdditionalData(data: ["/FinishKey": "/FinishValue"])
}
14 changes: 13 additions & 1 deletion ASDKSample/ASDKSample/RootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class RootViewController: UITableViewController {
sdk.presentCardList(
on: self,
customerKey: AppSetting.shared.activeSdkCredentials.customerKey,
addCardOptions: .cardOptions,
cardScannerDelegate: self
)
}
Expand All @@ -172,7 +173,12 @@ class RootViewController: UITableViewController {

let customerKey = AppSetting.shared.activeSdkCredentials.customerKey

sdk.presentAddCard(on: self, customerKey: customerKey, cardScannerDelegate: nil) { [weak self] result in
sdk.presentAddCard(
on: self,
customerKey: customerKey,
addCardOptions: .cardOptions,
cardScannerDelegate: nil
) { [weak self] result in
self?.addingNewCardCompleted(result: result)
}
}
Expand Down Expand Up @@ -261,3 +267,9 @@ extension RootViewController {
present(alert, animated: true)
}
}

extension AddCardOptions {
static let cardOptions = AddCardOptions(
attachCardData: AdditionalData(data: ["/AttachKey": "/AttachValue"])
)
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
* [EACQAPW-5748] Core mocks regeneration
* [EACQAPW-5764] Update YandexPay mocks
* [EACQAPW-5827] Update fakes
* [EACQAPW-5625] Added Card Options to pass DATA field in /AttachCard

### Changed
* [EACQAPW-5617] Now Receipt initializer checks validity of mandatory fields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,13 @@ public struct AttachCardData {
expDate: String,
cvv: String,
requestKey: String,
data: FinishAuthorizeDataWrapper<ThreeDsDataBrowser>?
data: FinishAuthorizeDataEnum?
) {
self.cardNumber = cardNumber
self.expDate = expDate
self.cvv = cvv
self.requestKey = requestKey

if let data = data {
// В данный момент на МАПИ поддерживается только 3ds Browser Flow
self.data = .threeDsBrowser(data)
} else {
self.data = nil
}
self.data = data
}

func cardData() -> String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ final class AddCardControllerAssembly: IAddCardControllerAssembly {

// MARK: IAddCardControllerAssembly

func addCardController(customerKey: String) -> IAddCardController {
func addCardController(
customerKey: String,
addCardOptions: AddCardOptions
) -> IAddCardController {
return AddCardController(
addCardService: coreSDK,
threeDSDeviceInfoProvider: coreSDK.threeDSDeviceInfoProvider(),
webFlowController: webFlowControllerAssembly.threeDSWebFlowController(),
threeDSService: coreSDK,
customerKey: customerKey,
addCardOptions: addCardOptions,
checkType: configuration.addCardCheckType,
tdsController: appBasedFlowControllerAssembly.assemble()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
import Foundation

protocol IAddCardControllerAssembly {
func addCardController(customerKey: String) -> IAddCardController
func addCardController(customerKey: String, addCardOptions: AddCardOptions) -> IAddCardController
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ final class AddCardController {
// MARK: IAddCardController Properties

let customerKey: String
private let addCardOptions: AddCardOptions

// MARK: Dependencies

Expand All @@ -44,6 +45,7 @@ final class AddCardController {
webFlowController: IThreeDSWebFlowController,
threeDSService: IAcquiringThreeDSService,
customerKey: String,
addCardOptions: AddCardOptions,
checkType: PaymentCardCheckType,
tdsController: ITDSController,
successfulStatuses: Set<AcquiringStatus> = [.completed],
Expand All @@ -54,6 +56,7 @@ final class AddCardController {
self.webFlowController = webFlowController
self.threeDSService = threeDSService
self.customerKey = customerKey
self.addCardOptions = addCardOptions
self.checkType = checkType
self.tdsController = tdsController
cardStateSuccessfulStatuses = successfulStatuses
Expand All @@ -69,7 +72,7 @@ extension AddCardController: IAddCardController {
set { webFlowController.webFlowDelegate = newValue }
}

func addCard(options: CardOptions, completion: @escaping (AddCardStateResult) -> Void) {
func addCard(cardData: CardData, completion: @escaping (AddCardStateResult) -> Void) {
let completionDecorator: Completion = { result in
DispatchQueue.performOnMain { completion(result) }
}
Expand All @@ -80,7 +83,7 @@ extension AddCardController: IAddCardController {
switch result {
case let .success(payload):
self.check3DSVersionIfNeeded(
options: options,
cardData: cardData,
addCardPayload: payload,
completion: completionDecorator
)
Expand All @@ -96,7 +99,7 @@ extension AddCardController: IAddCardController {
extension AddCardController {
/// Выполняет проверку версии 3DS по необходимости, основываясь на заданном `checkType`
private func check3DSVersionIfNeeded(
options: CardOptions,
cardData: CardData,
addCardPayload: AddCardPayload,
completion: @escaping Completion
) {
Expand All @@ -107,34 +110,36 @@ extension AddCardController {
}

check3DSVersion(
options: options,
cardData: cardData,
paymentId: paymentId,
requestKey: addCardPayload.requestKey,
completion: completion
)
case .no, .hold:
attachCard(
requestKey: addCardPayload.requestKey,
options: options,
cardData: cardData,
data: .dictionary(addCardOptions.attachCardData ?? .empty()),
completion: completion
)
}
}

/// Выполняет проверку версии 3DS
private func check3DSVersion(
options: CardOptions,
cardData: CardData,
paymentId: String,
requestKey: String,
completion: @escaping Completion
) {
addCardService.check3DSVersion(data: .data(with: paymentId, options: options)) { [weak self] result in
addCardService.check3DSVersion(data: .data(with: paymentId, cardData: cardData)) { [weak self] result in
guard let self = self else { return }

switch result {
case let .success(payload):
self.complete3DSMethodIfNeededAndAttachCard(
options: options,
cardData: cardData,
addCardOptions: self.addCardOptions,
check3DSPayload: payload,
requestKey: requestKey,
completion: completion
Expand All @@ -149,14 +154,20 @@ extension AddCardController {
///
/// Параметры `tdsServerTransID`, `threeDSMethodURL` в `Check3DSVersionPayload` являются признаком проверки `3DS v2`
private func complete3DSMethodIfNeededAndAttachCard(
options: CardOptions,
cardData: CardData,
addCardOptions: AddCardOptions,
check3DSPayload: Check3DSVersionPayload,
requestKey: String,
completion: @escaping Completion
) {
switch check3DSPayload.receiveVersion() {
case .v1:
attachCard(requestKey: requestKey, options: options, completion: completion)
attachCard(
requestKey: requestKey,
cardData: cardData,
data: .dictionary(addCardOptions.attachCardData ?? .empty()),
completion: completion
)

// TODO: EACQAPW-5432 ждет задачу чтобы убрать appBased из case
case .v2, .appBased:
Expand All @@ -171,7 +182,8 @@ extension AddCardController {
)

complete3DSMethod(
options: options,
cardData: cardData,
addCardOptions: addCardOptions,
checking3DSURLData: checking3DSURLData,
requestKey: requestKey,
messageVersion: check3DSPayload.version,
Expand Down Expand Up @@ -207,7 +219,8 @@ extension AddCardController {

/// Завершает подготовку к привязке карты с использованием `3DS v2`, а затем привязывает карту
private func complete3DSMethod(
options: CardOptions,
cardData: CardData,
addCardOptions: AddCardOptions,
checking3DSURLData: Checking3DSURLData,
requestKey: String,
messageVersion: String,
Expand All @@ -223,12 +236,15 @@ extension AddCardController {
}

let browserData = self.threeDSDeviceInfoProvider.createThreeDsDataBrowser()
let data = FinishAuthorizeDataWrapper<ThreeDsDataBrowser>(
data: browserData,
additionalData: addCardOptions.attachCardData
)

self.attachCard(
requestKey: requestKey,
options: options,
// ТУДУ: Пробрасывать additionalData для AttachCard
data: FinishAuthorizeDataWrapper<ThreeDsDataBrowser>(data: browserData, additionalData: nil),
cardData: cardData,
data: .threeDsBrowser(data),
messageVersion: messageVersion,
completion: completion
)
Expand All @@ -238,15 +254,15 @@ extension AddCardController {
/// Привязывает карту
private func attachCard(
requestKey: String,
options: CardOptions,
data: FinishAuthorizeDataWrapper<ThreeDsDataBrowser>? = nil,
cardData: CardData,
data: FinishAuthorizeDataEnum?,
messageVersion: String? = nil,
completion: @escaping Completion
) {
let attachData = AttachCardData(
cardNumber: options.pan,
expDate: options.validThru,
cvv: options.cvc,
cardNumber: cardData.number,
expDate: cardData.validThru,
cvv: cardData.cvc,
requestKey: requestKey,
data: data
)
Expand Down Expand Up @@ -432,13 +448,13 @@ extension AddCardController.Error: LocalizedError {
// MARK: - Check3DSVersionData + Helpers

private extension Check3DSVersionData {
static func data(with paymentId: String, options: CardOptions) -> Check3DSVersionData {
static func data(with paymentId: String, cardData: CardData) -> Check3DSVersionData {
Check3DSVersionData(
paymentId: paymentId,
paymentSource: .cardNumber(
number: options.pan,
expDate: options.validThru,
cvv: options.cvc
number: cardData.number,
expDate: cardData.validThru,
cvv: cardData.cvc
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public protocol IAddCardController: AnyObject {

/// Привязывает новую карту с заданными параметрами к пользователю
/// - Parameters:
/// - options: Опции добавления карты
/// - cardData: Данные карты
/// - completion: Замыкание с результатом привязки карты, вызывающееся на главном потоке
func addCard(options: CardOptions, completion: @escaping (AddCardStateResult) -> Void)
func addCard(cardData: CardData, completion: @escaping (AddCardStateResult) -> Void)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// AddCardOptions.swift
// TinkoffASDKUI
//
// Created by Ivan Glushko on 07.08.2023.
//

import Foundation
import TinkoffASDKCore

/// Параметры для флоу привязки карты
public struct AddCardOptions {

/// DATA - дополнительные поля для отправки на запрос `/AttachCard`
///
/// `JSON` объект, содержащий дополнительные параметры в виде `[Key: Value]`
///
/// `Key: String` – 20 знаков,
/// `Value: DataValue` – 100 знаков.
/// - Warning: Максимальное количество пар параметров не может превышать 20.
/// Часть может быть зарезервирована `TinkoffAcquiringSDK`
public let attachCardData: AdditionalData?

public init(attachCardData: AdditionalData?) {
self.attachCardData = attachCardData
}
}

public extension AddCardOptions {

static let empty = AddCardOptions(attachCardData: nil)
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//
// CardOptions.swift
// CardData.swift
// TinkoffASDKUI
//
// Created by r.akhmadeev on 19.02.2023.
//

import Foundation

/// Параметры карты
public struct CardOptions: Equatable {
/// Даннные карты
public struct CardData: Equatable {
/// Номер карты
public let pan: String
public let number: String
/// Срок годности карты в формате `MM/YY`
public let validThru: String
/// Трехзначный cvc-код
Expand All @@ -21,8 +21,8 @@ public struct CardOptions: Equatable {
/// - pan: Номер карты
/// - validThru: Срок годности карты в формате `MM/YY`
/// - cvc: Трехзначный cvc-код
public init(pan: String, validThru: String, cvc: String) {
self.pan = pan
public init(number: String, validThru: String, cvc: String) {
self.number = number
self.validThru = validThru
self.cvc = cvc
}
Expand Down
Loading