Skip to content

Commit

Permalink
* [EACQAPW-5625] Added Card Options to pass DATA field in /AttachCard
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanglushko committed Aug 8, 2023
1 parent 388823a commit 59676b4
Show file tree
Hide file tree
Showing 31 changed files with 199 additions and 95 deletions.
11 changes: 8 additions & 3 deletions ASDKSample/ASDKSample/BuyProductsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import TinkoffASDKUI
import TinkoffASDKYandexPay
import UIKit

extension AdditionalData {
static let paymentInit = AdditionalData(data: ["/InitKey": "/InitValue"])
static let paymentFinish = AdditionalData(data: ["/FinishKey": "/FinishValue"])
}

class BuyProductsViewController: UIViewController {

enum TableViewCellType {
Expand Down Expand Up @@ -56,7 +61,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 +620,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
14 changes: 13 additions & 1 deletion ASDKSample/ASDKSample/RootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ import UIKit
import TinkoffASDKCore
import TinkoffASDKUI

extension AddCardOptions {
static let cardOptions = AddCardOptions(
attachCardData: AdditionalData(data: ["/AttachKey": "/AttachValue"])
)
}

struct Product: Codable {

var price: NSDecimalNumber
Expand Down Expand Up @@ -159,6 +165,7 @@ class RootViewController: UITableViewController {
sdk.presentCardList(
on: self,
customerKey: AppSetting.shared.activeSdkCredentials.customerKey,
addCardOptions: .cardOptions,
cardScannerDelegate: self
)
}
Expand All @@ -172,7 +179,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
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.pan,
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.pan,
expDate: cardData.validThru,
cvv: cardData.cvc
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ public protocol IAddCardController: AnyObject {
/// - Parameters:
/// - options: Опции добавления карты
/// - 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,14 +1,14 @@
//
// 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
/// Срок годности карты в формате `MM/YY`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ final class CardsControllerAssembly: ICardsControllerAssembly {

// MARK: ICardsControllerAssembly

func cardsController(customerKey: String) -> ICardsController {
func cardsController(customerKey: String, addCardOptions: AddCardOptions) -> ICardsController {
CardsController(
cardService: coreSDK,
addCardController: addCardControllerAssembly.addCardController(customerKey: customerKey)
addCardController: addCardControllerAssembly.addCardController(
customerKey: customerKey,
addCardOptions: addCardOptions
)
)
}
}
Loading

0 comments on commit 59676b4

Please sign in to comment.