Skip to content

Commit ae1adc3

Browse files
authored
Vault with Purchase PayPalWeb (#221)
* vault with purchase create order PayPal * remove unnecessary decoding of links field * remove customerID entry for PP vault with purchase * add initializer with default nil for customer * change Customer to Codable for reuse for Vault customer decoding * Add comments that required experienceContext for PayPal vault option in order create not used in SDK * Jax, Sammy PR feedback
1 parent 29307de commit ae1adc3

7 files changed

+99
-18
lines changed

Demo/Demo/Models/CreateOrderParams.swift

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ struct CreateOrderParams: Encodable {
33
let applicationContext: ApplicationContext?
44
let intent: String
55
var purchaseUnits: [PurchaseUnit]?
6-
var paymentSource: VaultCardPaymentSource?
6+
var paymentSource: VaultPaymentSource?
77
}
88

99
struct ApplicationContext: Codable {
@@ -17,6 +17,39 @@ struct ApplicationContext: Codable {
1717
}
1818
}
1919

20+
enum VaultPaymentSource: Encodable {
21+
case card(VaultCardPaymentSource)
22+
case paypal(VaultPayPalPaymentSource)
23+
24+
func encode(to encoder: Encoder) throws {
25+
var container = encoder.singleValueContainer()
26+
switch self {
27+
case .card(let cardSource):
28+
try container.encode(cardSource)
29+
case .paypal(let paypalSource):
30+
try container.encode(paypalSource)
31+
}
32+
}
33+
}
34+
35+
struct VaultPayPalPaymentSource: Encodable {
36+
37+
let paypal: VaultPayPal
38+
}
39+
40+
struct VaultPayPal: Encodable {
41+
42+
let attributes: Attributes
43+
let experienceContext: ExperienceContext
44+
}
45+
46+
struct ExperienceContext: Encodable {
47+
48+
// these fields are not encoded for our SDK but are required for create order with PayPal vault option
49+
let returnURL: String
50+
let cancelURL: String
51+
}
52+
2053
struct VaultCardPaymentSource: Encodable {
2154

2255
let card: VaultCard
@@ -30,20 +63,27 @@ struct VaultCard: Encodable {
3063
struct Attributes: Encodable {
3164

3265
let vault: Vault
33-
let customer: CardVaultCustomer?
66+
let customer: Customer?
67+
68+
init(vault: Vault, customer: Customer? = nil) {
69+
self.vault = vault
70+
self.customer = customer
71+
}
3472
}
3573

3674
struct Vault: Encodable {
3775

3876
let storeInVault: String
39-
}
40-
41-
struct CardVaultCustomer: Encodable {
77+
let usageType: String?
78+
let customerType: String?
4279

43-
let id: String
80+
init(storeInVault: String, usageType: String? = nil, customerType: String? = nil) {
81+
self.storeInVault = storeInVault
82+
self.usageType = usageType
83+
self.customerType = customerType
84+
}
4485
}
4586

46-
4787
struct PurchaseUnit: Encodable {
4888

4989
var shipping: Shipping?

Demo/Demo/Models/Order.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ struct Order: Codable, Equatable {
33
let id: String
44
let status: String
55
var paymentSource: PaymentSource?
6-
6+
77
struct PaymentSource: Codable, Equatable {
88

99
let card: Card?
@@ -25,7 +25,8 @@ struct Order: Codable, Equatable {
2525

2626
struct PayPal: Codable, Equatable {
2727

28-
let emailAddress: String
28+
let emailAddress: String?
29+
let attributes: Attributes?
2930
}
3031

3132
struct Attributes: Codable, Equatable {

Demo/Demo/Models/PaymentTokenResponse.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ struct PaymentTokenResponse: Decodable, Equatable {
77
let paymentSource: PaymentSource
88
}
99

10-
struct Customer: Decodable, Equatable {
11-
10+
struct Customer: Codable, Equatable {
11+
1212
let id: String
1313
}
1414

Demo/Demo/SwiftUIComponents/PayPalWebViews/CreateOrderPayPalWebView.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ struct CreateOrderPayPalWebView: View {
55
@ObservedObject var paypalWebViewModel: PayPalWebViewModel
66

77
@State private var selectedIntent: Intent = .authorize
8+
@State var shouldVaultSelected = false
89

910
let selectedMerchantIntegration: MerchantIntegration
1011

@@ -22,6 +23,10 @@ struct CreateOrderPayPalWebView: View {
2223
Text("CAPTURE").tag(Intent.capture)
2324
}
2425
.pickerStyle(SegmentedPickerStyle())
26+
HStack {
27+
Toggle("Should Vault with Purchase", isOn: $shouldVaultSelected)
28+
Spacer()
29+
}
2530
ZStack {
2631
Button("Create an Order") {
2732
Task {
@@ -30,7 +35,9 @@ struct CreateOrderPayPalWebView: View {
3035
try await paypalWebViewModel.createOrder(
3136
amount: "10.00",
3237
selectedMerchantIntegration: DemoSettings.merchantIntegration,
33-
intent: selectedIntent.rawValue)
38+
intent: selectedIntent.rawValue,
39+
shouldVault: shouldVaultSelected
40+
)
3441
} catch {
3542
print("Error in getting setup token. \(error.localizedDescription)")
3643
}

Demo/Demo/SwiftUIComponents/PayPalWebViews/PayPalWebOrderCompletionResultView.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ struct PayPalWebOrderCompletionResultView: View {
3939
LeadingText("Email", weight: .bold)
4040
LeadingText("\(email)")
4141
}
42+
if let vaultID = orderResponse.paymentSource?.paypal?.attributes?.vault.id {
43+
LeadingText("Vault ID / Payment Token", weight: .bold)
44+
LeadingText("\(vaultID)")
45+
}
46+
if let customerID = orderResponse.paymentSource?.paypal?.attributes?.vault.customer.id {
47+
LeadingText("Customer ID", weight: .bold)
48+
LeadingText("\(customerID)")
49+
}
4250
Text("")
4351
.id("bottomView")
4452
}

Demo/Demo/ViewModels/CardPaymentViewModel.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,20 @@ class CardPaymentViewModel: ObservableObject, CardDelegate {
2121
let amountRequest = Amount(currencyCode: "USD", value: amount)
2222
// TODO: might need to pass in payee as payee object or as auth header
2323

24-
var vaultPaymentSource: VaultCardPaymentSource?
24+
var vaultCardPaymentSource: VaultCardPaymentSource?
2525
if shouldVault {
26-
var customer: CardVaultCustomer?
26+
var customer: Customer?
2727
if let customerID {
28-
customer = CardVaultCustomer(id: customerID)
28+
customer = Customer(id: customerID)
2929
}
3030
let attributes = Attributes(vault: Vault(storeInVault: "ON_SUCCESS"), customer: customer)
3131
let card = VaultCard(attributes: attributes)
32-
vaultPaymentSource = VaultCardPaymentSource(card: card)
32+
vaultCardPaymentSource = VaultCardPaymentSource(card: card)
33+
}
34+
35+
var vaultPaymentSource: VaultPaymentSource?
36+
if let vaultCardPaymentSource {
37+
vaultPaymentSource = .card(vaultCardPaymentSource)
3338
}
3439

3540
let orderRequestParams = CreateOrderParams(

Demo/Demo/ViewModels/PayPalWebViewModel.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,35 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
1010

1111
let configManager = CoreConfigManager(domain: "PayPalWeb Payments")
1212

13-
func createOrder(amount: String, selectedMerchantIntegration: MerchantIntegration, intent: String) async throws {
13+
func createOrder(
14+
amount: String,
15+
selectedMerchantIntegration: MerchantIntegration,
16+
intent: String,
17+
shouldVault: Bool
18+
) async throws {
1419
// might need to pass in payee as payee object or as auth header
1520

1621
let amountRequest = Amount(currencyCode: "USD", value: amount)
1722
// TODO: might need to pass in payee as payee object or as auth header
23+
24+
var vaultPayPalPaymentSource: VaultPayPalPaymentSource?
25+
if shouldVault {
26+
let attributes = Attributes(vault: Vault(storeInVault: "ON_SUCCESS", usageType: "MERCHANT", customerType: "CONSUMER"))
27+
// The returnURL is not used in our mobile SDK, but a required field for create order with PayPal payment source. DTPPCPSDK-1492 to track this issue
28+
let paypal = VaultPayPal(attributes: attributes, experienceContext: ExperienceContext(returnURL: "https://example.com/returnUrl", cancelURL: "https://example.com/cancelUrl"))
29+
vaultPayPalPaymentSource = VaultPayPalPaymentSource(paypal: paypal)
30+
}
31+
32+
var vaultPaymentSource: VaultPaymentSource?
33+
if let vaultPayPalPaymentSource {
34+
vaultPaymentSource = .paypal(vaultPayPalPaymentSource)
35+
}
36+
1837
let orderRequestParams = CreateOrderParams(
1938
applicationContext: nil,
2039
intent: intent,
21-
purchaseUnits: [PurchaseUnit(amount: amountRequest)]
40+
purchaseUnits: [PurchaseUnit(amount: amountRequest)],
41+
paymentSource: vaultPaymentSource
2242
)
2343

2444
do {

0 commit comments

Comments
 (0)