Skip to content

Commit

Permalink
Deprecate non-APIClient sources of publishableKey, stripeAccount (#1474)
Browse files Browse the repository at this point in the history
* Unrecommend Stripe.setDefaultPublishableKey in favor of STPAPIClient.sharedClient.publishableKey

* Deprecate PaymentConfiguration.{publishableKey, stripeAccount}.

Usage | Before | After all configuration changes:
- PaymentContext configuration. This never worked and there's no use case. | Still doesn't work, still no use case.
- CustomerContext configuration. This worked, but there is no use case. | Now, it only works if you set before STPAPIClient.shared is initialized. There's still no use case.
- PaymentHandler, APIClient.shared configuration. This worked if you set before STPAPIClient.shared is initialized. | No change.

* unrecom

* Remove apiKey

* PaymentConfiguration is just another property in APIClient, instead of the sorta-source-of-truth of publishableKey.

* Actually, make Stripe.defaultPublishableKey do the expected thing instead of deprecating it

* In docstrings, rename STPAPIClient.shared to [STPAPIClient sharedClient]

* Make Stripe.defaultPublishableKey the default value of STPAPIClient publishableKey

* Deprecate initWithConfiguration

* Fix buggy default behavior, added test to catch it

* Make STPAPIClient.publishableKey readonly

* Revert "Make STPAPIClient.publishableKey readonly"

This reverts commit 314256004a790edd3c35b090c3ed0b0b9506b84e.

* Stripe.setDefaultPublishableKey sets the default value for publishableKey only (this is the status quo behavior).

* Fix test and add docstring

* Add Changelog, migrating, improve a deprecation string

* Update MIGRATING.md

Co-Authored-By: Cameron <36750494+csabol-stripe@users.noreply.github.com>

* Update MIGRATING.md

Co-Authored-By: Cameron <36750494+csabol-stripe@users.noreply.github.com>

* Update MIGRATING.md

Co-Authored-By: Cameron <36750494+csabol-stripe@users.noreply.github.com>

* Update MIGRATING.md

Co-Authored-By: Cameron <36750494+csabol-stripe@users.noreply.github.com>

* Fix typos, grammar

* English hard

Co-authored-by: Cameron <36750494+csabol-stripe@users.noreply.github.com>
  • Loading branch information
yuki-stripe and csabol-stripe authored Jan 23, 2020
1 parent 47a13b2 commit d4c7a71
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 59 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 19.0.0 ??
* Deprecates the `STPAPIClient` `initWithConfiguration:` method. Set the `configuration` property on the `STPAPIClient` instance instead. [#1474](https://github.com/stripe/stripe-ios/pull/1474)
* Deprecates `publishableKey` and `stripeAccount` properties of `STPPaymentConfiguration`. See [MIGRATING.md](https://github.com/stripe/stripe-ios/blob/master/MIGRATING.md) for more details. [#1474](https://github.com/stripe/stripe-ios/pull/1474)
* Adds explicit STPAPIClient properties on all SDK components that make API requests. These default to `[STPAPIClient sharedClient]`. This is a breaking change for some users of `stripeAccount`. See [MIGRATING.md](https://github.com/stripe/stripe-ios/blob/master/MIGRATING.md) for more details. [#1469](https://github.com/stripe/stripe-ios/pull/1469)

## 18.4.0 2020-01-15
* Adds support for Klarna Pay on Sources API [#1444](https://github.com/stripe/stripe-ios/pull/1444)
* Compresses images using `pngcrush` to reduce SDK size [#1471](https://github.com/stripe/stripe-ios/pull/1471)
Expand Down
43 changes: 43 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
## Migration Guides

### Migrating from versions < 19.0.0

* Deprecates `publishableKey` and `stripeAccount` properties of `STPPaymentConfiguration`.
* If you used `STPPaymentConfiguration.sharedConfiguration` to set `publishableKey` and/or `stripeAccount`, use `STPAPIClient.sharedClient` instead.
* If you passed a STPPaymentConfiguration instance to an SDK component, you should instead create an STPAPIClient, set publishableKey on it, and set the SDK component's APIClient property.
* The SDK now uses `STPAPIClient.sharedClient` to make API requests by default.

This changes the behavior of the following classes, which previously used API client instances configured from `STPPaymentConfiguration.shared`: `STPCustomerContext`, `STPPaymentOptionsViewController`, `STPAddCardViewController`, `STPPaymentContext`, `STPPinManagementService`, `STPPushProvisioningContext`.

You are affected by this change if:

1. You use `stripeAccount` to work with your Connected accounts
2. You use one of the above affected classes
3. You set different `stripeAccount` values on `STPPaymentConfiguration` and `STPAPIClient`, i.e. `STPPaymentConfiguration.shared.stripeAccount != STPAPIClient.shared.stripeAccount`

If all three of the above conditions are true, you must update your integration! The SDK used to send `STPPaymentConfiguration.shared.stripeAccount`, and will now send `STPAPIClient.shared.stripeAccount`.

For example, if you are a Connect user who stores Payment Methods on your platform, but clones PaymentMethods to a connected account and creates direct charges on that connected account i.e. if:

1. You never set `STPPaymentConfiguration.shared.stripeAccount`
2. You set `STPAPIClient.shared.stripeAccount`

We recommend you do the following:

```
// By default, you don't want the SDK to pass stripeAccount
STPAPIClient.shared().publishableKey = "pk_platform"
STPAPIClient.shared().stripeAccount = nil
// You do want the SDK to pass stripeAccount when it makes payments directly on your connected account, so
// you create a separate APIClient instance...
let connectedAccountAPIClient = STPAPIClient(publishableKey: "pk_platform")
// ...set stripeAccount on it...
connectedAccountAPIClient.stripeAccount = "your connected account's id"
// ...and either set the relevant SDK components' apiClient property to your custom APIClient instance:
STPPaymentHandler.shared().apiClient = connectedAccountAPIClient // e.g. if you are using PaymentIntents
// ...or use it directly to make API requests with `stripeAccount` set:
connectedAccountAPIClient.createToken(withCard:...) // e.g. if you are using Tokens + Charges
```

### Migrating from versions < 18.0.0
* Some error messages from the Payment Intents API are now localized to the user's display language. If your application's logic depends on specific `message` strings from the Stripe API, please use the error [`code`](https://stripe.com/docs/error-codes) instead.
* `STPPaymentResult` may contain a `paymentMethodParams` instead of a `paymentMethod` when using single-use payment methods such as FPX. Because of this, `STPPaymentResult.paymentMethod` is now nullable. Instead of setting the `paymentMethodId` manually on your `paymentIntentParams`, you may now call `paymentIntentParams.configure(with result: STPPaymentResult)`:
Expand Down
40 changes: 27 additions & 13 deletions Stripe/PublicHeaders/STPAPIClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ static NSString *const STPSDKVersion = @"18.4.0";
/**
Set your Stripe API key with this method. New instances of STPAPIClient will be initialized with this value. You should call this method as early as
possible in your application's lifecycle, preferably in your AppDelegate.
@param publishableKey Your publishable key, obtained from https://stripe.com/account/apikeys
@param publishableKey Your publishable key, obtained from https://dashboard.stripe.com/apikeys
@warning Make sure not to ship your test API keys to the App Store! This will log a warning if you use your test key in a release build.
*/
+ (void)setDefaultPublishableKey:(NSString *)publishableKey;
Expand All @@ -51,20 +51,13 @@ static NSString *const STPSDKVersion = @"18.4.0";
@interface STPAPIClient : NSObject

/**
A shared singleton API client. Its API key will be initially equal to [Stripe defaultPublishableKey].
A shared singleton API client.
By default, the SDK uses this instance to make API requests
eg in STPPaymentHandler, STPPaymentContext, STPCustomerContext, etc.
*/
+ (instancetype)sharedClient;


/**
Initializes an API client with the given configuration. Its API key will be
set to the configuration's publishable key.
@param configuration The configuration to use.
@return An instance of STPAPIClient.
*/
- (instancetype)initWithConfiguration:(STPPaymentConfiguration *)configuration NS_DESIGNATED_INITIALIZER;

/**
Initializes an API client with the given publishable key.
Expand All @@ -75,11 +68,15 @@ static NSString *const STPSDKVersion = @"18.4.0";

/**
The client's publishable key.
The default value is [Stripe defaultPublishableKey].
*/
@property (nonatomic, copy, nullable) NSString *publishableKey;

/**
The client's configuration.
Defaults to [STPPaymentConfiguration sharedConfiguration].
*/
@property (nonatomic, copy) STPPaymentConfiguration *configuration;

Expand Down Expand Up @@ -481,4 +478,21 @@ Converts the last 4 SSN digits into a Stripe token using the Stripe API.

@end

#pragma mark - Deprecated

/**
Deprecated STPAPIClient methods
*/
@interface STPAPIClient (Deprecated)

/**
Initializes an API client with the given configuration.
@param configuration The configuration to use.
@return An instance of STPAPIClient.
*/
- (instancetype)initWithConfiguration:(STPPaymentConfiguration *)configuration DEPRECATED_MSG_ATTRIBUTE("This initializer previously configured publishableKey and stripeAccount via the STPPaymentConfiguration instance. This behavior is deprecated; set the STPAPIClient configuration, publishableKey, and stripeAccount properties directly on the STPAPIClient instead.");

@end

NS_ASSUME_NONNULL_END
22 changes: 14 additions & 8 deletions Stripe/PublicHeaders/STPPaymentConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (instancetype)sharedConfiguration;

/**
Your Stripe publishable key
@see https://dashboard.stripe.com/account/apikeys
*/
@property (nonatomic, copy, readwrite) NSString *publishableKey;

/**
An enum value representing which payment options you will accept from your user
in addition to credit cards.
Expand Down Expand Up @@ -119,14 +112,27 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, assign, readwrite) BOOL canDeletePaymentOptions;

#pragma mark - Deprecated

/**
If you used [STPPaymentConfiguration sharedConfiguration].publishableKey, use [STPAPIClient sharedClient].publishableKey instead. The SDK uses [STPAPIClient sharedClient] to make API requests by default.
Your Stripe publishable key
@see https://dashboard.stripe.com/account/apikeys
*/
@property (nonatomic, copy, readwrite) NSString *publishableKey DEPRECATED_MSG_ATTRIBUTE("If you used [STPPaymentConfiguration sharedConfiguration].publishableKey, use [STPAPIClient sharedClient].publishableKey instead. If you passed a STPPaymentConfiguration instance to an SDK component, create an STPAPIClient, set publishableKey on it, and set the SDK component's APIClient property.");

/**
If you used [STPPaymentConfiguration sharedConfiguration].stripeAccount, use [STPAPIClient sharedClient].stripeAccount instead. The SDK uses [STPAPIClient sharedClient] to make API requests by default.
In order to perform API requests on behalf of a connected account, e.g. to
create charges for a connected account, set this property to the ID of the
account for which this request is being made.
@see https://stripe.com/docs/payments/payment-intents/use-cases#connected-accounts
*/
@property (nonatomic, copy, nullable) NSString *stripeAccount;
@property (nonatomic, copy, nullable) NSString *stripeAccount DEPRECATED_MSG_ATTRIBUTE("If you used [STPPaymentConfiguration sharedConfiguration].stripeAccount, use [STPAPIClient sharedClient].stripeAccount instead. If you passed a STPPaymentConfiguration instance to an SDK component, create an STPAPIClient, set stripeAccount on it, and set the SDK component's APIClient property.");;

@end

Expand Down
2 changes: 1 addition & 1 deletion Stripe/STPAPIClient+ApplePay.m
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ + (NSDictionary *)parametersForPayment:(PKPayment *)payment {
payload[@"pk_token"] = paymentString;
payload[@"card"] = [self addressParamsFromPKContact:payment.billingContact];

NSCAssert(!(paymentString.length == 0 && [[Stripe defaultPublishableKey] hasPrefix:@"pk_live"]), @"The pk_token is empty. Using Apple Pay with an iOS Simulator while not in Stripe Test Mode will always fail.");
NSCAssert(!(paymentString.length == 0 && [[STPAPIClient sharedClient].publishableKey hasPrefix:@"pk_live"]), @"The pk_token is empty. Using Apple Pay with an iOS Simulator while not in Stripe Test Mode will always fail.");

NSString *paymentInstrumentName = payment.token.paymentMethod.displayName;
if (paymentInstrumentName) {
Expand Down
52 changes: 24 additions & 28 deletions Stripe/STPAPIClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@
@implementation Stripe

static NSArray<PKPaymentNetwork> *_additionalEnabledApplePayNetworks;
static NSString *_defaultPublishableKey;

+ (void)setDefaultPublishableKey:(NSString *)publishableKey {
[STPAPIClient validateKey:publishableKey];
[STPPaymentConfiguration sharedConfiguration].publishableKey = publishableKey;
_defaultPublishableKey = [publishableKey copy];
}

+ (NSString *)defaultPublishableKey {
return [STPPaymentConfiguration sharedConfiguration].publishableKey;
return _defaultPublishableKey;
}

@end
Expand All @@ -89,7 +89,6 @@ @interface STPAPIClient()

@property (nonatomic, strong, readwrite) NSMutableDictionary<NSString *,NSObject *> *sourcePollers;
@property (nonatomic, strong, readwrite) dispatch_queue_t sourcePollersQueue;
@property (nonatomic, strong, readwrite) NSString *apiKey;

// See STPAPIClient+Private.h

Expand Down Expand Up @@ -117,33 +116,35 @@ + (instancetype)sharedClient {
}

- (instancetype)init {
return [self initWithConfiguration:[STPPaymentConfiguration sharedConfiguration]];
}

- (instancetype)initWithPublishableKey:(NSString *)publishableKey {
STPPaymentConfiguration *config = [[STPPaymentConfiguration alloc] init];
config.publishableKey = [publishableKey copy];
return [self initWithConfiguration:config];
}

- (instancetype)initWithConfiguration:(STPPaymentConfiguration *)configuration {
NSString *publishableKey = [configuration.publishableKey copy];
if (publishableKey) {
[self.class validateKey:publishableKey];
}
self = [super init];
if (self) {
_apiKey = publishableKey;
_apiURL = [NSURL URLWithString:APIBaseURL];
_configuration = configuration;
_stripeAccount = configuration.stripeAccount;
_configuration = [STPPaymentConfiguration sharedConfiguration];
_sourcePollers = [NSMutableDictionary dictionary];
_sourcePollersQueue = dispatch_queue_create("com.stripe.sourcepollers", DISPATCH_QUEUE_SERIAL);
_urlSession = [NSURLSession sessionWithConfiguration:[self.class sharedUrlSessionConfiguration]];
_publishableKey = [Stripe defaultPublishableKey];
}
return self;
}

- (instancetype)initWithPublishableKey:(NSString *)publishableKey {
STPAPIClient *apiClient = [self init];
apiClient.publishableKey = publishableKey;
return apiClient;
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (instancetype)initWithConfiguration:(STPPaymentConfiguration *)configuration {
// For legacy reasons, we'll support this initializer and use the deprecated configuration.{publishableKey, stripeAccount} properties
STPAPIClient *apiClient = [self init];
apiClient.publishableKey = configuration.publishableKey;
apiClient.stripeAccount = configuration.stripeAccount;
return apiClient;
}
#pragma clang diagnostic pop

+ (NSURLSessionConfiguration *)sharedUrlSessionConfiguration {
static NSURLSessionConfiguration *STPSharedURLSessionConfiguration;
static dispatch_once_t configToken;
Expand Down Expand Up @@ -175,12 +176,7 @@ - (NSMutableURLRequest *)configuredRequestForURL:(NSURL *)url additionalHeaders:

- (void)setPublishableKey:(NSString *)publishableKey {
[self.class validateKey:publishableKey];
self.configuration.publishableKey = [publishableKey copy];
self.apiKey = [publishableKey copy];
}

- (NSString *)publishableKey {
return self.configuration.publishableKey;
_publishableKey = [publishableKey copy];
}

- (void)createTokenWithParameters:(NSDictionary *)parameters
Expand Down Expand Up @@ -259,7 +255,7 @@ + (NSString *)stripeUserAgentDetailsWithAppInfo:(nullable STPAppInfo *)appInfo {
}

- (NSDictionary<NSString *, NSString *> *)authorizationHeaderUsingEphemeralKey:(STPEphemeralKey *)ephemeralKey {
NSString *authorizationBearer = self.apiKey ?: @"";
NSString *authorizationBearer = self.publishableKey ?: @"";
if (ephemeralKey != nil) {
authorizationBearer = ephemeralKey.secret;
}
Expand Down
2 changes: 1 addition & 1 deletion Stripe/STPAnalyticsClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ + (NSMutableDictionary *)commonPayload {

+ (NSDictionary *)serializeConfiguration:(STPPaymentConfiguration *)configuration {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
dictionary[@"publishable_key"] = configuration.publishableKey ?: @"unknown";
dictionary[@"publishable_key"] = [STPAPIClient sharedClient].publishableKey ?: @"unknown";

if (configuration.additionalPaymentOptions == STPPaymentOptionTypeDefault) {
dictionary[@"additional_payment_methods"] = @"default";
Expand Down
45 changes: 43 additions & 2 deletions Stripe/STPPaymentConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ @interface STPPaymentConfiguration ()

@implementation STPPaymentConfiguration

@synthesize publishableKey = _publishableKey;
@synthesize stripeAccount = _stripeAccount;

+ (void)initialize {
[STPAnalyticsClient initializeIfNeeded];
[STPTelemetryClient sharedInstance];
Expand Down Expand Up @@ -126,7 +129,6 @@ - (NSString *)description {
[NSString stringWithFormat:@"%@: %p", NSStringFromClass([self class]), self],

// Basic configuration
[NSString stringWithFormat:@"publishableKey = %@", (self.publishableKey) ? @"<redacted>" : nil],
[NSString stringWithFormat:@"additionalPaymentOptions = %@", additionalPaymentOptionsDescription],

// Billing and shipping
Expand All @@ -149,7 +151,6 @@ - (NSString *)description {

- (id)copyWithZone:(__unused NSZone *)zone {
STPPaymentConfiguration *copy = [self.class new];
copy.publishableKey = self.publishableKey;
copy.additionalPaymentOptions = self.additionalPaymentOptions;
copy.requiredBillingAddressFields = self.requiredBillingAddressFields;
copy.requiredShippingAddressFields = self.requiredShippingAddressFields;
Expand All @@ -159,7 +160,47 @@ - (id)copyWithZone:(__unused NSZone *)zone {
copy.appleMerchantIdentifier = self.appleMerchantIdentifier;
copy.canDeletePaymentOptions = self.canDeletePaymentOptions;
copy.availableCountries = _availableCountries;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
copy.publishableKey = self.publishableKey;
copy.stripeAccount = self.stripeAccount;
#pragma clang diagnostic pop

return copy;
}

#pragma mark - Deprecated

// For legacy reasons, we'll try to keep the same behavior as before if setting these properties on the singleton.

- (void)setPublishableKey:(NSString *)publishableKey {
if (self == [STPPaymentConfiguration sharedConfiguration]) {
[STPAPIClient sharedClient].publishableKey = publishableKey;
} else {
_publishableKey = [publishableKey copy];
}
}

- (NSString *)publishableKey {
if (self == [STPPaymentConfiguration sharedConfiguration]) {
return [STPAPIClient sharedClient].publishableKey;
}
return _publishableKey;
}

- (void)setStripeAccount:(NSString *)stripeAccount {
if (self == [STPPaymentConfiguration sharedConfiguration]) {
[STPAPIClient sharedClient].stripeAccount = stripeAccount;
} else {
_stripeAccount = [stripeAccount copy];
}
}

- (NSString *)stripeAccount {
if (self == [STPPaymentConfiguration sharedConfiguration]) {
return [STPAPIClient sharedClient].stripeAccount;
}
return _stripeAccount;
}

@end
Loading

0 comments on commit d4c7a71

Please sign in to comment.