-
Notifications
You must be signed in to change notification settings - Fork 997
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
Connect Account tokenization #876
Conversation
Stripe/PublicHeaders/STPAPIClient.h
Outdated
*/ | ||
@interface STPAPIClient (ConnectAccounts) | ||
|
||
- (void)createTokenWithConnectAccount:(id)obj completion:(__nullable STPTokenCompletionBlock)completion; |
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.
obj needs to turn into:
account: {
legal_entity: {...},
tos_shown_and_accepted: true,
}
with either legal_entity
or tos_shown_and_accepted
, or both.
I don't know whether I want to create another ...Params
class, or change this method to take two nullable parameters.
I also think it's unfortunate that Bool?
is nullable NSNumber
in Obj-C
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.
Hmm, I think it'd be better to make this method take parameters rather than make a parent AccountParams
class, but don't feel strongly.
Is it necessary to model tos_shown_and_accepted
as a Bool?
, or can we treat tos_shown_and_accepted: nil
as tos_shown_and_accepted: false
?
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 don't think that would work. Valid values for tos_shown_and_accepted
are {true, nil}
. Some basic use cases:
account: { tos_shown_and_accepted: true }
: minimum required to set up a new accountaccount: { legal_entity: { ... }, tos_shown_and_accepted: true }
: setting up new account with some data about the legal entityaccount: { legal_entity: { ... } }
: valid for updating a pre-existing accountaccount: { tos_shown_and_accepted: false, ... }
: rejected by the server as invalid
As I understand it, the initial purpose for this API is collecting positive affirmation that the user has seen & accepted the ToS, instead of the old world where the platform is allowed to vouch that fact as true. However, it's also just as usable for updating the legal entity info directly.
I'll think about AccountParams
a little more. I like that it's easier to add new fields in the future, and the possibility of providing >1 constructors to help understand the legal_entity/tos_shown_and_accepted
distinction. But it's a lot just for two optional fields
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.
ah interesting, if that's the case then perhaps an AccountParams
object with multiple constructors makes sense. thanks for the explanation!
Stripe/STPLegalEntityParams.h
Outdated
}; | ||
|
||
|
||
@interface STPLegalEntityParams : STPPersonParams |
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.
Any problems foreseen by inheriting from STPPersonParams
, which conforms to STPFormEncodable
?
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.
hmm, I can't think of any
Stripe/STPLegalEntityParams.h
Outdated
}; | ||
|
||
|
||
@interface STPLegalEntityParams : STPPersonParams |
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 STPVerificationParams
and STPPersonParams
belong in their own files? Or are they fine here?
They're only used here (for now?), and the inheritance also links STPLegalEntityParams
with STPPersonParams
pretty closely.
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 they're fine together!
@bg-stripe WDYT? Does this look ~reasonable? |
this looks reasonable to me! |
Adding a test to verify this works, and that this doesn't break other NSNumber instances that store 0 or 1.
80aa4e0
to
d59c935
Compare
This includes the commit for #881, and I think it's now complete. r? @bg-stripe |
d59c935
to
139c516
Compare
It takes a single parameter, an `STPConnectAccountParams` object. This has an optional BOOL and an optional STPLegalEntityParams object (one of fields must be provided). Still TODO: adding `description` implementations in STPLegalEntityParams.m, and testing!
This currently fails, because `legal_entity` is actually required all the time, contrary to what I thought.
These are pretty basic, but then so are the implementations of the classes. I wanted to add custom Asserts (like https://www.objc.io/issues/15-testing/xctest/#custom-assert-macros) for these *very* repetitive tests (which already exist 4x times), but I think this is okay-ish.
139c516
to
b93b5ac
Compare
Last night I had moved the public headers into the right directory to fix a different failure, and rebased that into 3f2bc39. Now that bg-stripe's reviewed this PR, not going to force-push anymore.
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.
looks good, just a few nits
/** | ||
Initialize `STPConnectAccountParams` with tosShownAndAccepted = YES | ||
|
||
This method cannot be called with `wasAccepted == NO`, guarded by a `NSParameterAssert()`. |
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.
Ah, interesting design choice forcing the user to explicitly pass YES
. I like it.
It finally clicked for me why we model this as true/nil
instead of true/false
:) with shownAndAccepted=false
it's unclear whether the TOS was not shown or not accepted. 🤓
@param wasAccepted Must be YES, but only if the user was shown & accepted the ToS | ||
@param legalEntity data about the legal entity | ||
*/ | ||
- (instancetype)initTosShownAndAccepted:(BOOL)wasAccepted |
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 probably be initWithTos...
.
#import "STPFormEncodable.h" | ||
|
||
@class STPAddress, STPVerificationParams; | ||
|
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.
NS_ASSUME_NONNULL
Stripe/STPAPIClient.m
Outdated
|
||
@implementation STPAPIClient (ConnectAccounts) | ||
|
||
- (void)createTokenWithConnectAccount:(__unused id)account completion:(__nullable STPTokenCompletionBlock)completion { |
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.
replace __unused id
with `STPConnectAccountParams *``
Stripe/STPAPIClient.m
Outdated
|
||
- (void)createTokenWithConnectAccount:(__unused id)account completion:(__nullable STPTokenCompletionBlock)completion { | ||
NSMutableDictionary *params = [[STPFormEncoder dictionaryForObject:account] mutableCopy]; | ||
[[STPTelemetryClient sharedInstance] addTelemetryFieldsToParams:params]; |
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 probably don't need to add telemetry data.
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.
Papertrail: bg and I discussed in Slack. Android sends telemetry for all tokens. We think this is fine, but I have an open ask out to the team that owns telemetry.
addressDict[@"country"] = address.country; | ||
params[@"address"] = [addressDict copy]; | ||
// Re-use STPFormEncoder | ||
params[@"address"] = [STPFormEncoder dictionaryForObject:address]; |
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.
👍
Stripe/STPLegalEntityParams.m
Outdated
return @{}; | ||
} | ||
|
||
- (void)setAdditionalAPIParameters:(__unused NSDictionary *)additionalAPIParameters { |
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.
👍
// | ||
|
||
#import "STPConnectAccountParams.h" | ||
|
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.
NS_ASSUME_NONNULL
// Copyright © 2017 Stripe, Inc. All rights reserved. | ||
// | ||
|
||
#import "STPLegalEntityParams.h" |
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.
NS_ASSUME_NONNULL
Also, cc @ksun-stripe, who implemented this in stripe/stripe-android#492 |
…ormance. Faux Pas (correctly) points out adding un-prefixed methods to a Foundation class via a category is dangerous. Probably a better thing to do is either prefix all of these methods in the protocol, or add custom support for `NSDateComponents` in `+[STPFormEncoder formEncodableValueForObject:]`. For now, I think this is safe enough.
@bg-stripe I've addressed your comments (thanks for all the help!), and fixed some other problems. Travis has a 1000+ build backlog and is running at half capacity. If you want to re-review now you can, or I'll assign to you again if/when the build has succeeded. |
…876) * Defines iDEAL form in JSON instead of code - Adds spec for custom_dropdown - Defines iDEAL form in JSON instead of code * Fix complaint * PR feedback * Oops, fix form specs
Summary
Add API method for creating Connect Account tokens.
Motivation
Supporting Stripe API changes.
Testing
Unit and functional tests have been added. Manually tested with tokens created by this code to ensure I could consume them from a connect platform (although the tokens generated by the fully specific fixture in the functional test aren't consumable, they don't pass the required data validation)