mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-04 11:50:38 +00:00
Support native provider
This commit is contained in:
parent
97f7004a1e
commit
5a31f90acf
@ -561,7 +561,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||||||
|
|
||||||
var dismissImpl: (() -> Void)?
|
var dismissImpl: (() -> Void)?
|
||||||
let canSave = paymentForm.canSaveCredentials || paymentForm.passwordMissing
|
let canSave = paymentForm.canSaveCredentials || paymentForm.passwordMissing
|
||||||
let controller = BotCheckoutNativeCardEntryController(context: strongSelf.context, additionalFields: additionalFields, publishableKey: publishableKey, completion: { method in
|
let controller = BotCheckoutNativeCardEntryController(context: strongSelf.context, provider: .stripe(additionalFields: additionalFields, publishableKey: publishableKey), completion: { method in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -616,6 +616,74 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||||||
controller?.dismiss()
|
controller?.dismiss()
|
||||||
}
|
}
|
||||||
strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
|
} else if let nativeProvider = paymentForm.nativeProvider, nativeProvider.name == "smartglocal" {
|
||||||
|
guard let paramsData = nativeProvider.params.data(using: .utf8) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let nativeParams = (try? JSONSerialization.jsonObject(with: paramsData)) as? [String: Any] else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let publicToken = nativeParams["public_token"] as? String else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var dismissImpl: (() -> Void)?
|
||||||
|
let canSave = paymentForm.canSaveCredentials || paymentForm.passwordMissing
|
||||||
|
let controller = BotCheckoutNativeCardEntryController(context: strongSelf.context, provider: .smartglobal(isTesting: paymentForm.invoice.isTest, publicToken: publicToken), completion: { method in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if canSave && paymentForm.passwordMissing {
|
||||||
|
switch method {
|
||||||
|
case let .webToken(webToken) where webToken.saveOnServer:
|
||||||
|
var text = strongSelf.presentationData.strings.Checkout_NewCard_SaveInfoEnableHelp
|
||||||
|
text = text.replacingOccurrences(of: "[", with: "")
|
||||||
|
text = text.replacingOccurrences(of: "]", with: "")
|
||||||
|
present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_NotNow, action: {
|
||||||
|
var updatedToken = webToken
|
||||||
|
updatedToken.saveOnServer = false
|
||||||
|
applyPaymentMethod(.webToken(updatedToken))
|
||||||
|
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: {
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if paymentForm.passwordMissing {
|
||||||
|
var updatedToken = webToken
|
||||||
|
updatedToken.saveOnServer = false
|
||||||
|
applyPaymentMethod(.webToken(updatedToken))
|
||||||
|
|
||||||
|
let controller = SetupTwoStepVerificationController(context: strongSelf.context, initialState: .automatic, stateUpdated: { update, shouldDismiss, controller in
|
||||||
|
if shouldDismiss {
|
||||||
|
controller.dismiss()
|
||||||
|
}
|
||||||
|
switch update {
|
||||||
|
case .noPassword, .awaitingEmailConfirmation:
|
||||||
|
break
|
||||||
|
case .passwordSet:
|
||||||
|
var updatedToken = webToken
|
||||||
|
updatedToken.saveOnServer = true
|
||||||
|
applyPaymentMethod(.webToken(updatedToken))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
|
} else {
|
||||||
|
var updatedToken = webToken
|
||||||
|
updatedToken.saveOnServer = true
|
||||||
|
applyPaymentMethod(.webToken(updatedToken))
|
||||||
|
}
|
||||||
|
})]), nil)
|
||||||
|
default:
|
||||||
|
applyPaymentMethod(method)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
applyPaymentMethod(method)
|
||||||
|
}
|
||||||
|
dismissImpl?()
|
||||||
|
})
|
||||||
|
dismissImpl = { [weak controller] in
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
} else {
|
} else {
|
||||||
var dismissImpl: (() -> Void)?
|
var dismissImpl: (() -> Void)?
|
||||||
let controller = BotCheckoutWebInteractionController(context: context, url: paymentForm.url, intent: .addPaymentMethod({ [weak self] token in
|
let controller = BotCheckoutWebInteractionController(context: context, url: paymentForm.url, intent: .addPaymentMethod({ [weak self] token in
|
||||||
|
@ -30,13 +30,17 @@ struct BotCheckoutNativeCardEntryAdditionalFields: OptionSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class BotCheckoutNativeCardEntryController: ViewController {
|
final class BotCheckoutNativeCardEntryController: ViewController {
|
||||||
|
enum Provider {
|
||||||
|
case stripe(additionalFields: BotCheckoutNativeCardEntryAdditionalFields, publishableKey: String)
|
||||||
|
case smartglobal(isTesting: Bool, publicToken: String)
|
||||||
|
}
|
||||||
|
|
||||||
private var controllerNode: BotCheckoutNativeCardEntryControllerNode {
|
private var controllerNode: BotCheckoutNativeCardEntryControllerNode {
|
||||||
return super.displayNode as! BotCheckoutNativeCardEntryControllerNode
|
return super.displayNode as! BotCheckoutNativeCardEntryControllerNode
|
||||||
}
|
}
|
||||||
|
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let additionalFields: BotCheckoutNativeCardEntryAdditionalFields
|
private let provider: Provider
|
||||||
private let publishableKey: String
|
|
||||||
private let completion: (BotCheckoutPaymentMethod) -> Void
|
private let completion: (BotCheckoutPaymentMethod) -> Void
|
||||||
|
|
||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
@ -46,10 +50,9 @@ final class BotCheckoutNativeCardEntryController: ViewController {
|
|||||||
private var doneItem: UIBarButtonItem?
|
private var doneItem: UIBarButtonItem?
|
||||||
private var activityItem: UIBarButtonItem?
|
private var activityItem: UIBarButtonItem?
|
||||||
|
|
||||||
public init(context: AccountContext, additionalFields: BotCheckoutNativeCardEntryAdditionalFields, publishableKey: String, completion: @escaping (BotCheckoutPaymentMethod) -> Void) {
|
public init(context: AccountContext, provider: Provider, completion: @escaping (BotCheckoutPaymentMethod) -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.additionalFields = additionalFields
|
self.provider = provider
|
||||||
self.publishableKey = publishableKey
|
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
@ -71,7 +74,7 @@ final class BotCheckoutNativeCardEntryController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public func loadDisplayNode() {
|
override public func loadDisplayNode() {
|
||||||
self.displayNode = BotCheckoutNativeCardEntryControllerNode(additionalFields: self.additionalFields, publishableKey: self.publishableKey, theme: self.presentationData.theme, strings: self.presentationData.strings, present: { [weak self] c, a in
|
self.displayNode = BotCheckoutNativeCardEntryControllerNode(provider: self.provider, theme: self.presentationData.theme, strings: self.presentationData.strings, present: { [weak self] c, a in
|
||||||
self?.present(c, in: .window(.root), with: a)
|
self?.present(c, in: .window(.root), with: a)
|
||||||
}, dismiss: { [weak self] in
|
}, dismiss: { [weak self] in
|
||||||
self?.presentingViewController?.dismiss(animated: false, completion: nil)
|
self?.presentingViewController?.dismiss(animated: false, completion: nil)
|
||||||
|
@ -42,7 +42,7 @@ private final class BotCheckoutNativeCardEntryScrollerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
||||||
private let publishableKey: String
|
private let provider: BotCheckoutNativeCardEntryController.Provider
|
||||||
|
|
||||||
private let present: (ViewController, Any?) -> Void
|
private let present: (ViewController, Any?) -> Void
|
||||||
private let dismiss: () -> Void
|
private let dismiss: () -> Void
|
||||||
@ -70,9 +70,11 @@ final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode,
|
|||||||
|
|
||||||
private var currentCardData: BotPaymentCardInputData?
|
private var currentCardData: BotPaymentCardInputData?
|
||||||
private var currentCountryIso2: String?
|
private var currentCountryIso2: String?
|
||||||
|
|
||||||
|
private var dataTask: URLSessionDataTask?
|
||||||
|
|
||||||
init(additionalFields: BotCheckoutNativeCardEntryAdditionalFields, publishableKey: String, theme: PresentationTheme, strings: PresentationStrings, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void, openCountrySelection: @escaping () -> Void, updateStatus: @escaping (BotCheckoutNativeCardEntryStatus) -> Void, completion: @escaping (BotCheckoutPaymentMethod) -> Void) {
|
init(provider: BotCheckoutNativeCardEntryController.Provider, theme: PresentationTheme, strings: PresentationStrings, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void, openCountrySelection: @escaping () -> Void, updateStatus: @escaping (BotCheckoutNativeCardEntryStatus) -> Void, completion: @escaping (BotCheckoutPaymentMethod) -> Void) {
|
||||||
self.publishableKey = publishableKey
|
self.provider = provider
|
||||||
|
|
||||||
self.present = present
|
self.present = present
|
||||||
self.dismiss = dismiss
|
self.dismiss = dismiss
|
||||||
@ -95,46 +97,53 @@ final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode,
|
|||||||
cardUpdatedImpl?(data)
|
cardUpdatedImpl?(data)
|
||||||
}
|
}
|
||||||
itemNodes.append([BotPaymentHeaderItemNode(text: strings.Checkout_NewCard_PaymentCard), self.cardItem])
|
itemNodes.append([BotPaymentHeaderItemNode(text: strings.Checkout_NewCard_PaymentCard), self.cardItem])
|
||||||
|
|
||||||
if additionalFields.contains(.cardholderName) {
|
switch provider {
|
||||||
var sectionItems: [BotPaymentItemNode] = []
|
case let .stripe(additionalFields, _):
|
||||||
|
if additionalFields.contains(.cardholderName) {
|
||||||
sectionItems.append(BotPaymentHeaderItemNode(text: strings.Checkout_NewCard_CardholderNameTitle))
|
var sectionItems: [BotPaymentItemNode] = []
|
||||||
|
|
||||||
let cardholderItem = BotPaymentFieldItemNode(title: "", placeholder: strings.Checkout_NewCard_CardholderNamePlaceholder, contentType: .name)
|
sectionItems.append(BotPaymentHeaderItemNode(text: strings.Checkout_NewCard_CardholderNameTitle))
|
||||||
self.cardholderItem = cardholderItem
|
|
||||||
sectionItems.append(cardholderItem)
|
let cardholderItem = BotPaymentFieldItemNode(title: "", placeholder: strings.Checkout_NewCard_CardholderNamePlaceholder, contentType: .name)
|
||||||
|
self.cardholderItem = cardholderItem
|
||||||
itemNodes.append(sectionItems)
|
sectionItems.append(cardholderItem)
|
||||||
} else {
|
|
||||||
self.cardholderItem = nil
|
itemNodes.append(sectionItems)
|
||||||
}
|
} else {
|
||||||
|
self.cardholderItem = nil
|
||||||
if additionalFields.contains(.country) || additionalFields.contains(.zipCode) {
|
}
|
||||||
var sectionItems: [BotPaymentItemNode] = []
|
|
||||||
|
if additionalFields.contains(.country) || additionalFields.contains(.zipCode) {
|
||||||
sectionItems.append(BotPaymentHeaderItemNode(text: strings.Checkout_NewCard_PostcodeTitle))
|
var sectionItems: [BotPaymentItemNode] = []
|
||||||
|
|
||||||
if additionalFields.contains(.country) {
|
sectionItems.append(BotPaymentHeaderItemNode(text: strings.Checkout_NewCard_PostcodeTitle))
|
||||||
let countryItem = BotPaymentDisclosureItemNode(title: "", placeholder: strings.CheckoutInfo_ShippingInfoCountryPlaceholder, text: "")
|
|
||||||
countryItem.action = {
|
if additionalFields.contains(.country) {
|
||||||
openCountrySelectionImpl?()
|
let countryItem = BotPaymentDisclosureItemNode(title: "", placeholder: strings.CheckoutInfo_ShippingInfoCountryPlaceholder, text: "")
|
||||||
|
countryItem.action = {
|
||||||
|
openCountrySelectionImpl?()
|
||||||
|
}
|
||||||
|
self.countryItem = countryItem
|
||||||
|
sectionItems.append(countryItem)
|
||||||
|
} else {
|
||||||
|
self.countryItem = nil
|
||||||
}
|
}
|
||||||
self.countryItem = countryItem
|
if additionalFields.contains(.zipCode) {
|
||||||
sectionItems.append(countryItem)
|
let zipCodeItem = BotPaymentFieldItemNode(title: "", placeholder: strings.Checkout_NewCard_PostcodePlaceholder, contentType: .address)
|
||||||
|
self.zipCodeItem = zipCodeItem
|
||||||
|
sectionItems.append(zipCodeItem)
|
||||||
|
} else {
|
||||||
|
self.zipCodeItem = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
itemNodes.append(sectionItems)
|
||||||
} else {
|
} else {
|
||||||
self.countryItem = nil
|
self.countryItem = nil
|
||||||
}
|
|
||||||
if additionalFields.contains(.zipCode) {
|
|
||||||
let zipCodeItem = BotPaymentFieldItemNode(title: "", placeholder: strings.Checkout_NewCard_PostcodePlaceholder, contentType: .address)
|
|
||||||
self.zipCodeItem = zipCodeItem
|
|
||||||
sectionItems.append(zipCodeItem)
|
|
||||||
} else {
|
|
||||||
self.zipCodeItem = nil
|
self.zipCodeItem = nil
|
||||||
}
|
}
|
||||||
|
case .smartglobal:
|
||||||
itemNodes.append(sectionItems)
|
self.cardholderItem = nil
|
||||||
} else {
|
|
||||||
self.countryItem = nil
|
self.countryItem = nil
|
||||||
self.zipCodeItem = nil
|
self.zipCodeItem = nil
|
||||||
}
|
}
|
||||||
@ -214,6 +223,7 @@ final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode,
|
|||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.verifyDisposable.dispose()
|
self.verifyDisposable.dispose()
|
||||||
|
self.dataTask?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateCountry(_ iso2: String) {
|
func updateCountry(_ iso2: String) {
|
||||||
@ -232,53 +242,149 @@ final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode,
|
|||||||
guard let cardData = self.currentCardData else {
|
guard let cardData = self.currentCardData else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let configuration = STPPaymentConfiguration.shared().copy() as! STPPaymentConfiguration
|
switch self.provider {
|
||||||
configuration.smsAutofillDisabled = true
|
case let .stripe(_, publishableKey):
|
||||||
configuration.publishableKey = self.publishableKey
|
let configuration = STPPaymentConfiguration.shared().copy() as! STPPaymentConfiguration
|
||||||
configuration.appleMerchantIdentifier = "merchant.ph.telegra.Telegraph"
|
configuration.smsAutofillDisabled = true
|
||||||
|
configuration.publishableKey = publishableKey
|
||||||
let apiClient = STPAPIClient(configuration: configuration)
|
configuration.appleMerchantIdentifier = "merchant.ph.telegra.Telegraph"
|
||||||
|
|
||||||
let card = STPCardParams()
|
let apiClient = STPAPIClient(configuration: configuration)
|
||||||
card.number = cardData.number
|
|
||||||
card.cvc = cardData.code
|
let card = STPCardParams()
|
||||||
card.expYear = cardData.year
|
card.number = cardData.number
|
||||||
card.expMonth = cardData.month
|
card.cvc = cardData.code
|
||||||
card.name = self.cardholderItem?.text
|
card.expYear = cardData.year
|
||||||
card.addressCountry = self.currentCountryIso2
|
card.expMonth = cardData.month
|
||||||
card.addressZip = self.zipCodeItem?.text
|
card.name = self.cardholderItem?.text
|
||||||
|
card.addressCountry = self.currentCountryIso2
|
||||||
let createToken: Signal<STPToken, Error> = Signal { subscriber in
|
card.addressZip = self.zipCodeItem?.text
|
||||||
apiClient.createToken(withCard: card, completion: { token, error in
|
|
||||||
if let error = error {
|
let createToken: Signal<STPToken, Error> = Signal { subscriber in
|
||||||
subscriber.putError(error)
|
apiClient.createToken(withCard: card, completion: { token, error in
|
||||||
} else if let token = token {
|
if let error = error {
|
||||||
subscriber.putNext(token)
|
subscriber.putError(error)
|
||||||
subscriber.putCompletion()
|
} else if let token = token {
|
||||||
|
subscriber.putNext(token)
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return ActionDisposable {
|
||||||
|
let _ = apiClient.publishableKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.isVerifying = true
|
||||||
|
self.verifyDisposable.set((createToken |> deliverOnMainQueue).start(next: { [weak self] token in
|
||||||
|
if let strongSelf = self, let card = token.card {
|
||||||
|
let last4 = card.last4()
|
||||||
|
let brand = STPAPIClient.string(with: card.brand)
|
||||||
|
strongSelf.completion(.webToken(BotCheckoutPaymentWebToken(title: "\(brand)*\(last4)", data: "{\"type\": \"card\", \"id\": \"\(token.tokenId)\"}", saveOnServer: strongSelf.saveInfoItem.isOn)))
|
||||||
|
}
|
||||||
|
}, error: { [weak self] error in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.isVerifying = false
|
||||||
|
strongSelf.updateDone()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
self.updateDone()
|
||||||
|
case let .smartglobal(isTesting, publicToken):
|
||||||
|
let url: String
|
||||||
|
if isTesting {
|
||||||
|
url = "https://tgb-playground.smart-glocal.com/cds/v1/tokenize/card"
|
||||||
|
} else {
|
||||||
|
url = "https://tgb.smart-glocal.com/cds/v1/tokenize/card"
|
||||||
|
}
|
||||||
|
|
||||||
|
let jsonPayload: [String: Any] = [
|
||||||
|
"card": [
|
||||||
|
"number": cardData.number,
|
||||||
|
"expiration_month": "\(cardData.month)",
|
||||||
|
"expiration_year": "\(cardData.year)",
|
||||||
|
"security_code": "\(cardData.code)"
|
||||||
|
] as [String: Any]
|
||||||
|
]
|
||||||
|
|
||||||
|
guard let parsedUrl = URL(string: url) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = URLRequest(url: parsedUrl)
|
||||||
|
request.httpMethod = "POST"
|
||||||
|
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
request.setValue(publicToken, forHTTPHeaderField: "X-PUBLIC-TOKEN")
|
||||||
|
guard let requestBody = try? JSONSerialization.data(withJSONObject: jsonPayload, options: []) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
request.httpBody = requestBody
|
||||||
|
|
||||||
|
let session = URLSession.shared
|
||||||
|
let dataTask = session.dataTask(with: request, completionHandler: { [weak self] data, response, error in
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ReponseError: Error {
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
guard let data = data else {
|
||||||
|
throw ReponseError.generic
|
||||||
|
}
|
||||||
|
|
||||||
|
let jsonRaw = try JSONSerialization.jsonObject(with: data, options: [])
|
||||||
|
guard let json = jsonRaw as? [String: Any] else {
|
||||||
|
throw ReponseError.generic
|
||||||
|
}
|
||||||
|
guard let resultData = json["data"] as? [String: Any] else {
|
||||||
|
throw ReponseError.generic
|
||||||
|
}
|
||||||
|
guard let resultInfo = resultData["info"] as? [String: Any] else {
|
||||||
|
throw ReponseError.generic
|
||||||
|
}
|
||||||
|
guard let token = resultData["token"] as? String else {
|
||||||
|
throw ReponseError.generic
|
||||||
|
}
|
||||||
|
guard let maskedCardNumber = resultInfo["masked_card_number"] as? String else {
|
||||||
|
throw ReponseError.generic
|
||||||
|
}
|
||||||
|
|
||||||
|
let responseJson: [String: Any] = [
|
||||||
|
"type": "card",
|
||||||
|
"id": "\(token)"
|
||||||
|
]
|
||||||
|
|
||||||
|
let serializedResponseJson = try JSONSerialization.data(withJSONObject: responseJson, options: [])
|
||||||
|
|
||||||
|
guard let serializedResponseString = String(data: serializedResponseJson, encoding: .utf8) else {
|
||||||
|
throw ReponseError.generic
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.completion(.webToken(BotCheckoutPaymentWebToken(
|
||||||
|
title: maskedCardNumber,
|
||||||
|
data: serializedResponseString,
|
||||||
|
saveOnServer: strongSelf.saveInfoItem.isOn
|
||||||
|
)))
|
||||||
|
} catch {
|
||||||
|
strongSelf.isVerifying = false
|
||||||
|
strongSelf.updateDone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
self.dataTask = dataTask
|
||||||
return ActionDisposable {
|
|
||||||
let _ = apiClient.publishableKey
|
self.isVerifying = true
|
||||||
}
|
self.updateDone()
|
||||||
|
|
||||||
|
dataTask.resume()
|
||||||
|
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
self.isVerifying = true
|
|
||||||
self.verifyDisposable.set((createToken |> deliverOnMainQueue).start(next: { [weak self] token in
|
|
||||||
if let strongSelf = self, let card = token.card {
|
|
||||||
let last4 = card.last4()
|
|
||||||
let brand = STPAPIClient.string(with: card.brand)
|
|
||||||
strongSelf.completion(.webToken(BotCheckoutPaymentWebToken(title: "\(brand)*\(last4)", data: "{\"type\": \"card\", \"id\": \"\(token.tokenId)\"}", saveOnServer: strongSelf.saveInfoItem.isOn)))
|
|
||||||
}
|
|
||||||
}, error: { [weak self] error in
|
|
||||||
if let strongSelf = self {
|
|
||||||
strongSelf.isVerifying = false
|
|
||||||
strongSelf.updateDone()
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
self.updateDone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateDone() {
|
private func updateDone() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user