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

Create Request Object for PayPalWebCheckoutClient.vault() #260

Merged
merged 10 commits into from
Mar 20, 2024

Conversation

KunJeongPark
Copy link
Collaborator

@KunJeongPark KunJeongPark commented Mar 1, 2024

Summary of changes

  • Create PayPalVaultRequest
  • Refactor PayPalWebCheckout.vault(url: String) to PayPalWebCheckout.vault(_ vaultRequest: PayPaylVaultRequest)
  • Adjust PayPalClient_Tests with modified vault function argument
  • Change demo app to pass in setupTokenID and url in PayPalVaultRequest into vault function

Checklist

  • Added a changelog entry

Authors

List GitHub usernames for everyone who contributed to this pull request.

@KunJeongPark KunJeongPark requested a review from a team as a code owner March 1, 2024 17:08
CHANGELOG.md Outdated Show resolved Hide resolved
Button("Vault PayPal") {
Task {
await paypalVaultViewModel.vault(url: url)
await paypalVaultViewModel.vault(url: urlString, setupTokenID: setupTokenID)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This may be a silly question but is there a reason our view is pulling these values from the view model only to send it to the view model? Can we just call await paypalVaultViewModel.vault() with nothing then pull the setup token and id from the state within the view model's vault method?

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Mar 1, 2024

Choose a reason for hiding this comment

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

It's just the way we have the demo app setup. I get the setup token from create API and update the state in viewModel.

And then to present button to vault PP, I check for existence of these values that were just stored in vault state and use the vault function in viewModel to launch the approval url.

I think it'd be weird for vault function in viewModel to just fetch these values without context.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I guess to me it just seems like a pretty big anti pattern to send data from ViewModel > View > ViewModel since that data already exists in the view model itself. I'm not sure if using something like a bool in the view model would be a better way of indicating that we can vault and to show this view. Just worth thinking about if you have ideas.

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Mar 4, 2024

Choose a reason for hiding this comment

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

the property is an optional field and nil until it is populated.
It's a pattern I've used in views before where I choose to present a UI element
depending on presence of some value in a published property.

So rather than checking in the view model's vault function for presence of its values, I just send the values from the view where it checks the value anyway. I wouldn't try to vault until setup token is there already.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That we need to launch this url as opposed to mobile SDK directly calling API was researched by Steven
@sshropshire

Copy link
Collaborator

Choose a reason for hiding this comment

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

This was guidance from the JS PPCP SDK. Apparently the URL given to us by PPaaS is lower latency than any URL we can create on our own using a setup token ID.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Gotcha, my question wasn't around the URL at all. It was around passing view model data from the view model back to the view model, which is a bit of an odd pattern. I know we do it in many places, so should think about if there is a better way vs having the view model passed it's own data. Really just something to think about!

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Mar 13, 2024

Choose a reason for hiding this comment

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

Oh I think I answered that part in the wrong section. That portion of my answer was in response to Sammy's question on the bottom.

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Mar 13, 2024

Choose a reason for hiding this comment

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

Yeah, on your point Jax, I don't need to pass it, I just check existence of those values in the view, so I just passed them so I don't have to check for nil values in the function in the viewModel. I just thought it would be weird that I'd have vault function check for nil when I wouldn't get there if the setup token value was nil.

This is all on the demo app side, so merchant can choose to handle it differently.

Button("Vault PayPal") {
Task {
await paypalVaultViewModel.vault(url: url)
await paypalVaultViewModel.vault(url: urlString, setupTokenID: setupTokenID)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I guess to me it just seems like a pretty big anti pattern to send data from ViewModel > View > ViewModel since that data already exists in the view model itself. I'm not sure if using something like a bool in the view model would be a better way of indicating that we can vault and to show this view. Just worth thinking about if you have ideas.

Sources/PayPalWebPayments/PayPalVaultRequest.swift Outdated Show resolved Hide resolved
public struct PayPalVaultRequest {

/// PayPal URL for the approval web page
public let url: URL
Copy link
Collaborator

Choose a reason for hiding this comment

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

Slight tangent here - but do you have context on why we have to require the URL? I assume some limitation with the API. Do we have it documented somewhere?

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Mar 8, 2024

Choose a reason for hiding this comment

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

PayPal vault works very differently than Card vault in that we just simply launch the url for API to be called outside of our SDK and we get results back. There is documentation for v3/vault/setup-tokens with PAYPAL WALLET in PPaas. Not sure if that is what you are asking.

It's also different from PayPal Checkout flow where we can just construct the url with an orderID.
The url from setup token API looks like this: "href": "https://api-m.paypal.com/agreements/approve?approval_session_id=xxxx"

Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we include that last piece in our docstring to make it more clear to us/merchants where this URL comes from? Something like:

/// PayPal approval URL returned as the `href` from the setup token API call

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Mar 14, 2024

Choose a reason for hiding this comment

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

Do we document things that happens on merchant's server side or do we leave that to our developer docs?
I like your suggestion of describing it in our SDK in this case because it's not self-explanatory where it comes from. For example, we don't include anything about the fact that orderID comes from merchant server side call in CardRequest at rely on developer docs to explain those portions.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it could help a merchant who maybe doesn't know where this URL comes from or which URL to pass in. I could certainly see a merchant passing in the wrong URL here so think giving some guidance would be beneficial.

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: dadbd5d

public struct PayPalVaultRequest {

/// PayPal URL for the approval web page
public let url: URL
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we include that last piece in our docstring to make it more clear to us/merchants where this URL comes from? Something like:

/// PayPal approval URL returned as the `href` from the setup token API call

@KunJeongPark KunJeongPark merged commit 7b8b608 into main Mar 20, 2024
5 checks passed
@KunJeongPark KunJeongPark deleted the PayPalVaultRequest branch March 20, 2024 14:27
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.

6 participants