Skip to content

Commit

Permalink
Vault Without Purchase PayPal (#225)
Browse files Browse the repository at this point in the history
* setupTokenPaymentSource

* setup token output, UI for PP vault

* vault(url:) method, custom url scheme

* comma omission typo in demo pbxproj file

* Display parsed vault token

* PaymentToken endpoint and output

* add MockPayPalVaultDelegate and unit tests

* add comments on PayPalVaultDelegate

* PayPalVaultResult to include approvalSessionID
Co-authored-by: Ricardo Herrera <<[email protected]>

* move payment specific properties out of parent viewModel

* make PayPalResultView look consisitent with CardVaultResultView

* Create new VaultViews folder, move files

* Rich PR feedback

* Encodable for setupToken payment source, pr feedback

Co-authored-by: Ricardo Herrera <[email protected]>

* vault function comments and changelog

Co-authored-by: Ricardo Herrera <[email protected]>

---------

Co-authored-by: Ricardo Herrera <[email protected]>
  • Loading branch information
KunJeongPark and richherrera authored Dec 18, 2023
1 parent 2e7393c commit 52f2106
Show file tree
Hide file tree
Showing 26 changed files with 676 additions and 119 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@

# PayPal iOS SDK Release Notes

## unreleased
* PayPalWebPayments
* Add `vault(url:)` method to `PayPalWebCheckoutClient`
* Add `PayPalVaultResult` type to return vault result
* Add `PayPalVaultDelegate` to handle results from vault flow
* Add `PayPalWebCheckoutClientError.paypalVaultResponseError` for missing or invalid response from vaulting

## 1.1.0 (2023-11-16)
* PayPalNativePayments
* Bump `PayPalCheckout` to `1.2.0`
Expand Down
48 changes: 40 additions & 8 deletions Demo/Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@
/* Begin PBXBuildFile section */
3B20273D2A89E3F00007907E /* CreateSetupTokenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B20273C2A89E3F00007907E /* CreateSetupTokenView.swift */; };
3B20273F2A89F24E0007907E /* CardVaultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B20273E2A89F24E0007907E /* CardVaultViewModel.swift */; };
3B2027412A8A72050007907E /* CardVaultState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2027402A8A72050007907E /* CardVaultState.swift */; };
3B2027412A8A72050007907E /* VaultState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2027402A8A72050007907E /* VaultState.swift */; };
3B2027432A8A95EF0007907E /* SetupTokenResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2027422A8A95EF0007907E /* SetupTokenResultView.swift */; };
3B2027452A8AA78B0007907E /* UpdateSetupTokenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2027442A8AA78B0007907E /* UpdateSetupTokenView.swift */; };
3B22E8BA2A842D8900962E34 /* PaymentTokenRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B22E8B92A842D8900962E34 /* PaymentTokenRequest.swift */; };
3B22E8BC2A84397600962E34 /* PaymentTokenResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B22E8BB2A84397600962E34 /* PaymentTokenResponse.swift */; };
3B3C51142B20F7CE009125FE /* PayPalVaultResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3C51132B20F7CE009125FE /* PayPalVaultResultView.swift */; };
3B4DD9A02A892A7000F4A716 /* CardVaultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B4DD99F2A892A7000F4A716 /* CardVaultView.swift */; };
3B4DD9A22A8982B000F4A716 /* CardFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B4DD9A12A8982B000F4A716 /* CardFormView.swift */; };
3B6472A72AFAEB3A004745C4 /* PayPalWebTransactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B6472A62AFAEB3A004745C4 /* PayPalWebTransactionView.swift */; };
3B80D50E2A291C0800D2EAC4 /* ClientIDRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80D50D2A291C0800D2EAC4 /* ClientIDRequest.swift */; };
3B80D5102A291CB100D2EAC4 /* ClientIDResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80D50F2A291CB100D2EAC4 /* ClientIDResponse.swift */; };
3B8EF4DB2A932DA300A70D0B /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B8EF4DA2A932DA300A70D0B /* ErrorView.swift */; };
3BA0A58B2B1E240300330681 /* VaultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA0A58A2B1E240300330681 /* VaultViewModel.swift */; };
3BA56FE72A9DC9D70081D14F /* CardPaymentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA56FE62A9DC9D70081D14F /* CardPaymentViewModel.swift */; };
3BA56FE92A9DCA520081D14F /* CardPaymentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA56FE82A9DCA520081D14F /* CardPaymentState.swift */; };
3BA56FEC2A9DCBF30081D14F /* CreateOrderCardPaymentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA56FEB2A9DCBF30081D14F /* CreateOrderCardPaymentView.swift */; };
Expand All @@ -35,6 +37,8 @@
3BA570032AA053AE0081D14F /* PayPalWebCreateOrderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA570022AA053AE0081D14F /* PayPalWebCreateOrderView.swift */; };
3BA570072AA0DF330081D14F /* PayPalWebButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA570062AA0DF330081D14F /* PayPalWebButtonsView.swift */; };
3BA5700B2AA13C1C0081D14F /* CoreConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA5700A2AA13C1C0081D14F /* CoreConfigManager.swift */; };
3BB60B532B1F9F1100A298CF /* PayPalVaultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB60B522B1F9F1100A298CF /* PayPalVaultView.swift */; };
3BB60B552B1FA00C00A298CF /* PayPalVaultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB60B542B1FA00C00A298CF /* PayPalVaultViewModel.swift */; };
3BB7A9772A5CA6FD00C05140 /* MerchantIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB7A9762A5CA6FD00C05140 /* MerchantIntegration.swift */; };
3BC622072A97115700251B85 /* RoundedBlueButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC622062A97115700251B85 /* RoundedBlueButtonStyle.swift */; };
3BC622092A97198500251B85 /* LeadingText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC622082A97198500251B85 /* LeadingText.swift */; };
Expand Down Expand Up @@ -126,17 +130,19 @@
/* Begin PBXFileReference section */
3B20273C2A89E3F00007907E /* CreateSetupTokenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateSetupTokenView.swift; sourceTree = "<group>"; };
3B20273E2A89F24E0007907E /* CardVaultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardVaultViewModel.swift; sourceTree = "<group>"; };
3B2027402A8A72050007907E /* CardVaultState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardVaultState.swift; sourceTree = "<group>"; };
3B2027402A8A72050007907E /* VaultState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VaultState.swift; sourceTree = "<group>"; };
3B2027422A8A95EF0007907E /* SetupTokenResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupTokenResultView.swift; sourceTree = "<group>"; };
3B2027442A8AA78B0007907E /* UpdateSetupTokenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateSetupTokenView.swift; sourceTree = "<group>"; };
3B22E8B92A842D8900962E34 /* PaymentTokenRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentTokenRequest.swift; sourceTree = "<group>"; };
3B22E8BB2A84397600962E34 /* PaymentTokenResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentTokenResponse.swift; sourceTree = "<group>"; };
3B3C51132B20F7CE009125FE /* PayPalVaultResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalVaultResultView.swift; sourceTree = "<group>"; };
3B4DD99F2A892A7000F4A716 /* CardVaultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardVaultView.swift; sourceTree = "<group>"; };
3B4DD9A12A8982B000F4A716 /* CardFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardFormView.swift; sourceTree = "<group>"; };
3B6472A62AFAEB3A004745C4 /* PayPalWebTransactionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PayPalWebTransactionView.swift; sourceTree = "<group>"; };
3B80D50D2A291C0800D2EAC4 /* ClientIDRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientIDRequest.swift; sourceTree = "<group>"; };
3B80D50F2A291CB100D2EAC4 /* ClientIDResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientIDResponse.swift; sourceTree = "<group>"; };
3B8EF4DA2A932DA300A70D0B /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
3BA0A58A2B1E240300330681 /* VaultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VaultViewModel.swift; sourceTree = "<group>"; };
3BA56FE62A9DC9D70081D14F /* CardPaymentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPaymentViewModel.swift; sourceTree = "<group>"; };
3BA56FE82A9DCA520081D14F /* CardPaymentState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPaymentState.swift; sourceTree = "<group>"; };
3BA56FEB2A9DCBF30081D14F /* CreateOrderCardPaymentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateOrderCardPaymentView.swift; sourceTree = "<group>"; };
Expand All @@ -152,6 +158,8 @@
3BA570022AA053AE0081D14F /* PayPalWebCreateOrderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalWebCreateOrderView.swift; sourceTree = "<group>"; };
3BA570062AA0DF330081D14F /* PayPalWebButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalWebButtonsView.swift; sourceTree = "<group>"; };
3BA5700A2AA13C1C0081D14F /* CoreConfigManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreConfigManager.swift; sourceTree = "<group>"; };
3BB60B522B1F9F1100A298CF /* PayPalVaultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalVaultView.swift; sourceTree = "<group>"; };
3BB60B542B1FA00C00A298CF /* PayPalVaultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalVaultViewModel.swift; sourceTree = "<group>"; };
3BB7A9762A5CA6FD00C05140 /* MerchantIntegration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantIntegration.swift; sourceTree = "<group>"; };
3BC622062A97115700251B85 /* RoundedBlueButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedBlueButtonStyle.swift; sourceTree = "<group>"; };
3BC622082A97198500251B85 /* LeadingText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeadingText.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -236,17 +244,24 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
3B43290F2A8FD7FD00C5441A /* CardVaultViews */ = {
3B2501052B2679F000903EAB /* VaultViews */ = {
isa = PBXGroup;
children = (
3B4DD99F2A892A7000F4A716 /* CardVaultView.swift */,
3B20273C2A89E3F00007907E /* CreateSetupTokenView.swift */,
3B2027422A8A95EF0007907E /* SetupTokenResultView.swift */,
3B2027442A8AA78B0007907E /* UpdateSetupTokenView.swift */,
3BF999752A8AC093009CBDF2 /* UpdateSetupTokenResultView.swift */,
3BF999772A8AD072009CBDF2 /* CreatePaymentTokenView.swift */,
3BF999792A8AE12C009CBDF2 /* PaymentTokenResultView.swift */,
);
path = VaultViews;
sourceTree = "<group>";
};
3B43290F2A8FD7FD00C5441A /* CardVaultViews */ = {
isa = PBXGroup;
children = (
3B4DD99F2A892A7000F4A716 /* CardVaultView.swift */,
3B2027442A8AA78B0007907E /* UpdateSetupTokenView.swift */,
3BF999752A8AC093009CBDF2 /* UpdateSetupTokenResultView.swift */,
);
path = CardVaultViews;
sourceTree = "<group>";
};
Expand Down Expand Up @@ -279,6 +294,15 @@
path = PayPalWebPayments;
sourceTree = "<group>";
};
3BB60B512B1F9EE400A298CF /* PayPalVaultViews */ = {
isa = PBXGroup;
children = (
3BB60B522B1F9F1100A298CF /* PayPalVaultView.swift */,
3B3C51132B20F7CE009125FE /* PayPalVaultResultView.swift */,
);
path = PayPalVaultViews;
sourceTree = "<group>";
};
3BCCFE472A9D962E00C5102F /* CommonComponents */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -412,9 +436,11 @@
children = (
CB34B32228BE3A9A001325B9 /* PayPalViewModel.swift */,
3B20273E2A89F24E0007907E /* CardVaultViewModel.swift */,
3B2027402A8A72050007907E /* CardVaultState.swift */,
3BA0A58A2B1E240300330681 /* VaultViewModel.swift */,
3B2027402A8A72050007907E /* VaultState.swift */,
3BA56FE62A9DC9D70081D14F /* CardPaymentViewModel.swift */,
3BA56FE82A9DCA520081D14F /* CardPaymentState.swift */,
3BB60B542B1FA00C00A298CF /* PayPalVaultViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
Expand All @@ -441,6 +467,8 @@
BEDE3047275E998700D275FD /* SwiftUIComponents */ = {
isa = PBXGroup;
children = (
3B2501052B2679F000903EAB /* VaultViews */,
3BB60B512B1F9EE400A298CF /* PayPalVaultViews */,
3BA56FFF2A9FF6630081D14F /* PayPalWebPayments */,
3BA56FEA2A9DCBB30081D14F /* CardPaymentViews */,
3BCCFE472A9D962E00C5102F /* CommonComponents */,
Expand Down Expand Up @@ -570,7 +598,7 @@
buildActionMask = 2147483647;
files = (
3BA56FE92A9DCA520081D14F /* CardPaymentState.swift in Sources */,
3B2027412A8A72050007907E /* CardVaultState.swift in Sources */,
3B2027412A8A72050007907E /* VaultState.swift in Sources */,
80F33CED26F8E7A9006811B1 /* Order.swift in Sources */,
3B4DD9A02A892A7000F4A716 /* CardVaultView.swift in Sources */,
BE8117642B07E778009867B9 /* PayPalWebResultView.swift in Sources */,
Expand All @@ -592,10 +620,13 @@
53B9E8EA28C93B4400719239 /* OrderRequestHelpers.swift in Sources */,
3BCCFE4B2A9D985F00C5102F /* FeatureSelectionView.swift in Sources */,
CB9ED44C283FDA900081F4DE /* PaymentButtonEnums+Extension.swift in Sources */,
3BB60B552B1FA00C00A298CF /* PayPalVaultViewModel.swift in Sources */,
3BB60B532B1F9F1100A298CF /* PayPalVaultView.swift in Sources */,
3B80D50E2A291C0800D2EAC4 /* ClientIDRequest.swift in Sources */,
3BA56FF02A9DCCFD0081D14F /* CardOrderApproveView.swift in Sources */,
BE8117682B080472009867B9 /* CurrentState.swift in Sources */,
3BDB348E2A7CB02C008100D7 /* SetupTokenRequest.swift in Sources */,
3BA0A58B2B1E240300330681 /* VaultViewModel.swift in Sources */,
80F33CF326F8EA50006811B1 /* DemoSettings.swift in Sources */,
3BA56FE72A9DC9D70081D14F /* CardPaymentViewModel.swift in Sources */,
BE8117662B080202009867B9 /* PayPalWebStatusView.swift in Sources */,
Expand All @@ -615,6 +646,7 @@
3BA56FFC2A9FEFE90081D14F /* PayPalWebViewModel.swift in Sources */,
3BDB34922A7CB5DE008100D7 /* SetupTokenResponse.swift in Sources */,
3BA56FF22A9DCD440081D14F /* CardApprovalResultView.swift in Sources */,
3B3C51142B20F7CE009125FE /* PayPalVaultResultView.swift in Sources */,
3BA570012AA052E80081D14F /* PayPalWebPaymentsView.swift in Sources */,
CBC16DD929ED90B600307117 /* UpdateOrderParams.swift in Sources */,
3BA56FFA2A9FE4180081D14F /* CardOrderCompletionResultView.swift in Sources */,
Expand Down
12 changes: 9 additions & 3 deletions Demo/Demo/Models/PaymentTokenResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ struct Customer: Codable, Equatable {

struct PaymentSource: Decodable, Equatable {

let card: BasicCard
var card: CardPaymentSource?
var paypal: PayPalPaymentSource?
}

struct BasicCard: Decodable, Equatable {
struct CardPaymentSource: Decodable, Equatable {

let brand: String?
let lastDigits: String
let expiry: String
}

struct PayPalPaymentSource: Decodable, Equatable {

let emailAddress: String
}
82 changes: 68 additions & 14 deletions Demo/Demo/Models/SetupTokenRequest.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,71 @@
import Foundation

struct SetUpTokenRequest {

struct VaultExperienceContext: Encodable {

let returnUrl = "sdk.ios.paypal://vault/success"
let cancelUrl = "sdk.ios.paypal://vault/cancel"

enum CodingKeys: String, CodingKey {
case returnUrl = "return_url"
case cancelUrl = "cancel_url"
}
}

struct PayPal: Encodable {

var usageType: String
let experienceContext = VaultExperienceContext()

enum CodingKeys: String, CodingKey {
case usageType = "usage_type"
case experienceContext = "experience_context"
}
}

enum PaymentSourceType: Encodable {
case card
case paypal(usageType: String)

private enum CodingKeys: String, CodingKey {
case card, paypal
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .card:
try container.encode(EmptyBodyParams(), forKey: .card)
case .paypal(let usageType):
try container.encode(PayPal(usageType: usageType), forKey: .paypal)
}
}
}

struct VaultCustomer: Encodable {

var id: String?

private enum CodingKeys: String, CodingKey {
case id
}
}

struct SetupTokenRequestBody: Encodable {

var customer: VaultCustomer?
let paymentSource: PaymentSourceType

enum CodingKeys: String, CodingKey {
case paymentSource = "payment_source"
case customer
}
}

struct SetUpTokenRequest: Encodable {

let customerID: String?

let paymentSource: PaymentSourceType

var path: String {
"/setup_tokens/"
}
Expand All @@ -15,17 +77,9 @@ struct SetUpTokenRequest {
var headers: [String: String] {
["Content-Type": "application/json"]
}

var body: Data? {
let requestBody: [String: Any] = [
"customer": [
"id": customerID
],
"payment_source": [
"card": [:]
]
]

return try? JSONSerialization.data(withJSONObject: requestBody)
let requestBodyParam = SetupTokenRequestBody(customer: VaultCustomer(id: customerID), paymentSource: paymentSource)
return try? JSONEncoder().encode(requestBodyParam)
}
}
9 changes: 9 additions & 0 deletions Demo/Demo/Models/SetupTokenResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@ struct SetUpTokenResponse: Decodable, Equatable {

let id, status: String
let customer: Customer?
let links: [Link]
var paypalURL: String? {
links.first { $0.rel == "approve" }?.href
}

struct Customer: Decodable {

let id: String
}

struct Link: Decodable {

let href, rel, method: String
}
}
10 changes: 7 additions & 3 deletions Demo/Demo/Networking/DemoMerchantAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ final class DemoMerchantAPI {
private init() {}

// MARK: Public Methods

func getSetupToken(customerID: String? = nil, selectedMerchantIntegration: MerchantIntegration) async throws -> SetUpTokenResponse {

func getSetupToken(
customerID: String? = nil,
selectedMerchantIntegration: MerchantIntegration,
paymentSourceType: PaymentSourceType
) async throws -> SetUpTokenResponse {
do {
// TODO: pass in headers depending on integration type
// Different request struct or integration type property
// in SetUpTokenRequest to conditionally add header
let request = SetUpTokenRequest(customerID: customerID)
let request = SetUpTokenRequest(customerID: customerID, paymentSource: paymentSourceType)
let urlRequest = try createSetupTokenUrlRequest(
setupTokenRequest: request,
environment: DemoSettings.environment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@ struct CardVaultView: View {
VStack(spacing: 16) {
CreateSetupTokenView(
selectedMerchantIntegration: DemoSettings.merchantIntegration,
cardVaultViewModel: cardVaultViewModel
vaultViewModel: cardVaultViewModel,
paymentSourceType: PaymentSourceType.card
)
SetupTokenResultView(cardVaultViewModel: cardVaultViewModel)
SetupTokenResultView(vaultViewModel: cardVaultViewModel)
if let setupToken = cardVaultViewModel.state.setupToken {
UpdateSetupTokenView(cardVaultViewModel: cardVaultViewModel, setupToken: setupToken.id)
}
UpdateSetupTokenResultView(cardVaultViewModel: cardVaultViewModel)
if let updateSetupToken = cardVaultViewModel.state.updateSetupToken {
CreatePaymentTokenView(
cardVaultViewModel: cardVaultViewModel,
vaultViewModel: cardVaultViewModel,
selectedMerchantIntegration: DemoSettings.merchantIntegration,
setupToken: updateSetupToken.id
)
}
PaymentTokenResultView(cardVaultViewModel: cardVaultViewModel)
PaymentTokenResultView(vaultViewModel: cardVaultViewModel)
switch cardVaultViewModel.state.paymentTokenResponse {
case .loaded, .error:
VStack {
Expand Down
Loading

0 comments on commit 52f2106

Please sign in to comment.