-
Notifications
You must be signed in to change notification settings - Fork 295
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
[V7] Add Encodable
protocol for PayPal Checkout
#1491
base: v7
Are you sure you want to change the base?
Conversation
if payPalRequest.requestBillingAgreement { | ||
self.requestBillingAgreement = payPalRequest.requestBillingAgreement | ||
|
||
if let billingAgreementDescription = payPalRequest.billingAgreementDescription { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, this property belongs to class BTPayPalRequest
. After changing its properties to internal
in a previous PR, merchants can no longer access these properties, meaning there's no way to configure, for example, "billingAgreementDescription" when creating an instance of BTPayPalCheckoutRequest
or BTPayPalVaultRequest
. Do you think we should add the necessary properties to the init of BTPayPalCheckoutRequest
or BTPayPalVaultRequest
, or make the properties in BTPayPalRequest
public again and remove BTPayPalRequest.init
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great catch, I don't think we want to make the properties on BTPayPalRequest
public since that would allow merchants to use the dot syntax, which we would like to move away from. I think it makes sense to add the properties to BTPayPalCheckoutRequest
or BTPayPalVaultRequest
inits then pass them in the super.init? What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can opt to use a Protocol, this approach would be similar to the one we use on Android, where they use an AbstractClass
. The reason for using a protocol is to define a contract for the necessary properties in both models. Instead of inheritance, we would use conformance so that our BTPayPalClient
functions the same. I've updated the PR, let me know if you have any questions or comments. I'm happy to address any concerns.
with configuration: BTConfiguration, | ||
universalLink: URL? = nil, | ||
isPayPalAppInstalled: Bool = false | ||
) -> [String: Any] { | ||
var baseParameters = super.parameters(with: configuration) | ||
var experienceProfile: [String: Any] = [:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we won't have inheritance, I had to move this code from BTPayPalRequest.parameters
. In the next PR, this entire method will be removed because we are creating the PayPalCheckoutPOSTBody
model, which conforms to the Encodable protocol.
|
||
static var callbackURLHostAndPath: String { get } | ||
|
||
func parameters( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is to mimic the inheritance we used to do
isShippingAddressEditable: Bool = false, | ||
isShippingAddressRequired: Bool = false, | ||
landingPageType: BTPayPalRequestLandingPageType = .none, | ||
lineItems: [BTPayPalLineItem]? = nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comparing the implementation with Android, on Android, lineItems
is only used for the Checkout
flow. What do you think about removing this property from the PayPalRequest
protocol, so it's only visible in the Checkout flow? On Android, we would need to remove the property from the AbstractClass
PayPalRequest, and it wouldn't be overridden in PayPalCheckoutRequest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, let's confirm with the pay with paypal team if line items can be passed on vault requests. If not, I agree with you we can remove it from the protocol and make it only available on PayPalCheckoutRequest
let hermesPath: String | ||
let paymentType: BTPayPalPaymentType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a preference on harding these here or below in the init? I lean slightly towards having them hardcoded at the top of the file, but am open to what we feel is best.
experienceProfile["no_shipping"] = !isShippingAddressRequired | ||
experienceProfile["brand_name"] = displayName != nil ? displayName : configuration.json?["paypal"]["displayName"].asString() | ||
|
||
if landingPageType?.stringValue != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take it or leave it since I think this will change in the next PR, but we tend to prefer the if let
syntax over != nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated: e446f03
@@ -29,7 +29,7 @@ import BraintreeDataCollector | |||
var clientMetadataID: String? | |||
|
|||
/// Exposed for testing the intent associated with this request | |||
var payPalRequest: BTPayPalRequest? | |||
var payPalRequest: PayPalRequest? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we keep the name as BTPayPalRequest
for the protocol?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's an internal protocol, I think we can omit the BT
prefix. If we decide to keep the prefix, how about I change it in the next PR? Right now, there would be naming conflicts with the concrete class. Another option would be to choose a different name for the protocol 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change it in the next PR - I feel like it makes sense to keep the prefix for now just based on the class names but can be in the follow up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated: f90356b
if let unitTaxAmount, !unitTaxAmount.isEmpty { | ||
try container.encode(unitAmount, forKey: .unitTaxAmount) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to implement a custom encode()
method just for this case?
Does Encodable not by default just omit an optional value that is nil
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason is that on iOS, the value of unitAmount
is used with the keys unit_amount
"unit_amount": unitAmount, |
and unit_tax_amount
requestParameters["unit_tax_amount"] = unitAmount |
but it seems this has always been an error. On Android it's different 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the PR: e478437 let me know what do you think. Unfortunately, the enums need to implement a custom encode because they are of type Int, and we are encoding their string value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
Summary of changes
PayPalRequest
protocol to define the contract for the base properties forBTPayPalCheckoutRequest
andBTPayPalVaultRequest
post
bodies used in the PayPal Checkout flow.Note: Since we have two different classes (
PayPalCheckoutRequest
andPayPalVaultRequest
) used inPayPalClient
, it's currently not possible to useEncodable
until the same implementation is done forPayPalVaultRequest
. We tested the flow, but we need to complete taskDTMOBILES-1177
to be able to useEncodable
.Checklist
[ ] Added a changelog entryAuthors