Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vault with Purchase PayPalWeb #221

Merged
merged 7 commits into from
Nov 30, 2023
Merged

Vault with Purchase PayPalWeb #221

merged 7 commits into from
Nov 30, 2023

Conversation

KunJeongPark
Copy link
Collaborator

@KunJeongPark KunJeongPark commented Nov 16, 2023

Summary of changes

  • Created UI for vault option for PayPalWeb checkout in demo app
  • Added experience_context and vault parameters with vault option selected in create order
  • Display vaultID and customerID in capture/authorize if PayPal payment is vaulted with checkout
vaultPurchasePP3.mp4

Checklist

- [ ] Added a changelog entry

Authors

@KunJeongPark KunJeongPark changed the title vault with purchase create order PayPal Vault with Purchase PayPalWeb Nov 16, 2023
storeInVault: "ON_SUCCESS",
usageType: "MERCHANT",
customerType: "CONSUMER"
),
Copy link
Collaborator Author

@KunJeongPark KunJeongPark Nov 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just hard coded this for direct merchant but I am investigating what different parameters are for different selected merchant integrations.

Copy link
Collaborator

@jaxdesmarais jaxdesmarais Nov 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should get input from product on what we need to support here for v1 in the demo app.

-Victoria : yes, Walter referenced docs during stand and I plan on working with Nirvan and Walter on the specs.

So right now, in demo app we only have direct, connected and managed path configured, not specific paths like CP2 or CP4. The usageType would depend on specific integration patterns.

I think specs for server side inputs like auth headers and payee info should be made for each integration types in another PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, Walter referenced docs during stand and I plan on working with Nirvan and Walter on the specs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So right now, in demo app we only have direct, connected and managed path configured, not specific paths like CP2 or CP4. The usageType would depend on specific integration patterns.

I think specs for server side inputs like auth headers and payee info should be made for each integration types in another PR.

@KunJeongPark KunJeongPark marked this pull request as ready for review November 20, 2023 18:25
@KunJeongPark KunJeongPark requested a review from a team as a code owner November 20, 2023 18:25
@@ -30,15 +62,17 @@ struct VaultCard: Encodable {
struct Attributes: Encodable {

let vault: Vault
let customer: CardVaultCustomer?
let customer: VaultCustomer?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can just call this Customer instead of VaultCustomer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed here: 62480f6

@@ -5,6 +5,8 @@ struct CreateOrderPayPalWebView: View {
@ObservedObject var paypalWebViewModel: PayPalWebViewModel

@State private var selectedIntent: Intent = .authorize
@State private var vaultCustomerID: String = ""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you had said during stand that regardless of what's customer ID is passed in the API always generates one? If that's the case, I think we should remove this from our demo.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, my plan is to do that today.

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Nov 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit dc0c32e and f07d0bc

Comment on lines +42 to +45
if let vaultID = orderResponse.paymentSource?.paypal?.attributes?.vault.id {
LeadingText("Vault ID / Payment Token", weight: .bold)
LeadingText("\(vaultID)")
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General question: is there an agreed upon name that JS calls this in our public docs? I see we use both vault ID and payment token here. We should use whichever name is used in our public docs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for the customer point of view, we call it payment token , but we reference it as vault ID in the APIs.
I just referenced vault Id on the label to clarify that they are the same.

storeInVault: "ON_SUCCESS",
usageType: "MERCHANT",
customerType: "CONSUMER"
),
Copy link
Collaborator

@jaxdesmarais jaxdesmarais Nov 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should get input from product on what we need to support here for v1 in the demo app.

-Victoria : yes, Walter referenced docs during stand and I plan on working with Nirvan and Walter on the specs.

So right now, in demo app we only have direct, connected and managed path configured, not specific paths like CP2 or CP4. The usageType would depend on specific integration patterns.

I think specs for server side inputs like auth headers and payee info should be made for each integration types in another PR.

@KunJeongPark
Copy link
Collaborator Author

62480f6 commit message should have been "reuse for Vault customer encoding"

@@ -3,7 +3,7 @@ struct CreateOrderParams: Encodable {
let applicationContext: ApplicationContext?
let intent: String
var purchaseUnits: [PurchaseUnit]?
var paymentSource: VaultCardPaymentSource?
var paymentSource: VaultPaymentSource?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify my understanding - a merchant only needs to set the paymentSource in their create order call if they want to vault, correct?

How do we document this to a merchant?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, JS SDK has documentation on this on their developer site. We should do something similar.

@@ -22,6 +23,10 @@ struct CreateOrderPayPalWebView: View {
Text("CAPTURE").tag(Intent.capture)
}
.pickerStyle(SegmentedPickerStyle())
HStack {
Toggle("Should Vault with Purchase", isOn: $shouldVaultSelected)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!

customerType: "CONSUMER"
)
)
let paypal = VaultPayPal(attributes: attributes, experienceContext: ExperienceContext(returnURL: "https://example.com/returnUrl", cancelURL: "https://example.com/cancelUrl"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your video, the redirect back to the Demo app looked fine, even though you would think the experienceContext should be a URL scheme to the app. What happens if the merchant doesn't set these URLs?

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The endpoint throws an error without the experienceContext field for PayPal vaulting.

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In our SDK, when we launch the ASWebSession for PayPalWeb, we construct the redirectURLString and append it as a query parameter to the checkout url :

func payPalCheckoutReturnURL(payPalCheckoutURL: URL) -> URL? {

The redirect url is included as a parameter in the url that we construct to launch the webSession.
I don't know if this is a typo or intentional but query parameter name for redirect url is strange.

So this experienceContext in create Order API is only relevant to JS SDK but the API fails nonetheless
without it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:sigh: That's right, this is an issue with the create-order API. It doesn't accept non-https URLs.

We should add a comment to make this issue clear in the code. That basically createOrder requires an https URL, which doesn't get used by the SDK flow at all. The merchant could put https://bogus.com and things will work fine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That might be an actual site.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments above to clarify that required experienceContext fields for PayPal vault with purchase are not used in the SDK.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't suppose there is a way for use to pass a URL on our merchants behalf so they don't need to do this step?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The createOrder will just error if that URL value isn't set or is an empty string. It also errors if the string doesn't start with https. Victoria - can we make a JIRA for tracking taking up this issue with the API team?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roger

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created - DTPPCPSDK-1492

}
let attributes = Attributes(vault: Vault(storeInVault: "ON_SUCCESS"), customer: customer)
let attributes = Attributes(vault: Vault(storeInVault: "ON_SUCCESS", usageType: nil, customerType: nil), customer: customer)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we default usageType and customerType to nil in the struct?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed here: c77464c

Comment on lines 26 to 32
let attributes = Attributes(
vault: Vault(
storeInVault: "ON_SUCCESS",
usageType: "MERCHANT",
customerType: "CONSUMER"
)
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if we single line this are we still under our linter warning?

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try it. No warning and it's much more readable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed here: c77464c

customerType: "CONSUMER"
)
)
let paypal = VaultPayPal(attributes: attributes, experienceContext: ExperienceContext(returnURL: "https://example.com/returnUrl", cancelURL: "https://example.com/cancelUrl"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't suppose there is a way for use to pass a URL on our merchants behalf so they don't need to do this step?

customerType: "CONSUMER"
)
)
// The returnURL is not used in our mobile SDK, but a required field for create order with PayPal payment source.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick - I would also add a reference to the JIRA ticket # that summarizes this issue we need to take up with the API team!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed here: c77464c

@KunJeongPark KunJeongPark merged commit ae1adc3 into main Nov 30, 2023
4 checks passed
@KunJeongPark KunJeongPark deleted the vaultwithPurchasePayPal branch November 30, 2023 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants