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

Get rid of ExternalAccount #417

Merged
merged 1 commit into from
Jan 10, 2018
Merged

Conversation

ob-stripe
Copy link
Contributor

r? @brandur-stripe
cc @stripe/api-libraries

Okay, I'm not 100% sure we actually want this change, but since we're going to release a new major version I thought I'd open the PR to gather feedback.

This PR removes the ExternalAccount class entirely. The existing implementation has a number of flaws:

  • generic instanceUrl() method that assumes every external account can be attached to a customer, an account or a recipient
  • generic verify() method that assumes every external account can be verified
    • in practice, only bank accounts can be verified, and BankAccount has its own verify() method
  • Source does not derive from ExternalAccount

This change makes the implementation closer to what we have in stripe-ruby and stripe-python: all "external accounts" (namely: cards, bank accounts, sources, Alipay accounts and Bitcoin receivers) derive directly from APIResource and have their own instanceUrl() method that knows which type of owner each resource can have (e.g. bank accounts cannot be attached to recipients, etc.), plus custom retrieve() and update() methods that return an helpful error message.

Copy link

@fred-stripe fred-stripe left a comment

Choose a reason for hiding this comment

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

Overall I think this is a good change, as it eliminates the inconsistencies of the ExternalAccount approach. Folks shouldn't be explicitly relying on that class anyway and, if they are, they can easily change from ExternalAccount to ApiResource.

$msg = "Bank accounts cannot be accessed without a customer ID or account ID.";
throw new Error\InvalidRequest($msg, null);
}
$parentExtn = urlencode(Util\Util::utf8($parent));

Choose a reason for hiding this comment

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

It feels weird to encode so much knowledge about the URL structure in this object, but this is similar to, stripe-ruby, for example:

https://github.com/stripe/stripe-ruby/blob/master/lib/stripe/bank_account.rb

On the one hand, this leads to duplicated logic; on the other hand, it simplifies this object's dependencies and leads to more explicit tests.

@brandur-stripe
Copy link
Contributor

Great implementation (with nice test additions!).

I think others would have a better idea as to whether this is a desirable change or not, but the reduction in special casing seems like a good idea to me in concept at least. +1.

lib/Account.php Outdated
@@ -120,7 +120,7 @@ public function deauthorize($clientId = null, $opts = null)
* @param array|null $params
* @param array|string|null $opts
*
* @return ExternalAccount
* @return ApiResource
*/
public static function createExternalAccount($id, $params = null, $opts = null)
Copy link
Contributor

@remi-stripe remi-stripe Jan 9, 2018

Choose a reason for hiding this comment

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

Should we remove those methods explicitly in favor of $account->external_accounts->create() instead? This avoids the confusion and we would automatically return the right class based on the type of external accounts

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, these methods let users manipulate external accounts without having to retrieve the account first (like other nested resource methods). Also, to clarify, these methods will return the correct type -- though of course we cannot know what this type will be in the PHPDoc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, I've updated the PHPDoc to use BankAccount|Card instead of ApiResource.

@@ -7,7 +7,60 @@
*
* @package Stripe
*/
class AlipayAccount extends ExternalAccount
class AlipayAccount extends ApiResource
Copy link
Contributor

Choose a reason for hiding this comment

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

Where are we on the idea that we should remove those classes entirely since we don't support them anymore and have not for over a year? Since PHP is dynamic and would return an ApiResource anyway when you get one of those on a Charge for example, is it time to get rid of it at the same time?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we can keep the classes around -- the definitions do still exist in the OpenAPI spec, and in the case of Bitcoin some users do still send requests to the top-level endpoint /v1/bitcoin/receivers.

I've removed the refund() method from BitcoinReceiver though, and updated the PHPDoc to include links to the sources API documentation.

lib/Card.php Outdated
public static function retrieve($_id, $_opts = null)
{
$msg = "Cards cannot be accessed without a customer, recipient or account ID. " .
"Retrieve a bank account using \$customer->sources->retrieve('card_id'), " .
Copy link
Contributor

Choose a reason for hiding this comment

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

s/bank account/card/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Thanks!

@ob-stripe ob-stripe force-pushed the ob-drop-externalaccount branch 2 times, most recently from 76ad07d to c6f5857 Compare January 9, 2018 21:59
@ob-stripe
Copy link
Contributor Author

Okay, since the consensus seems to be in favor, I'm going to pull this in the integration branch for v6.

@ob-stripe ob-stripe merged commit ce6a216 into integration-v6 Jan 10, 2018
@ob-stripe ob-stripe deleted the ob-drop-externalaccount branch January 10, 2018 09:15
@ob-stripe ob-stripe mentioned this pull request Jan 10, 2018
9 tasks
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.

4 participants