Skip to content

Commit

Permalink
Add FPX offline status endpoint (#1422)
Browse files Browse the repository at this point in the history
* Add FPX offline status endpoint
  • Loading branch information
davidme-stripe authored Oct 24, 2019
1 parent 56e916a commit 7152797
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 35 deletions.
12 changes: 12 additions & 0 deletions Stripe.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@
0731329E2277ABF60019CE3F /* STPPinManagementService.m in Sources */ = {isa = PBXBuildFile; fileRef = 0731328E2277A3F60019CE3F /* STPPinManagementService.m */; };
0731329F227CFE410019CE3F /* STPIssuingCardPin.h in Headers */ = {isa = PBXBuildFile; fileRef = 073132932277A72D0019CE3F /* STPIssuingCardPin.h */; settings = {ATTRIBUTES = (Public, ); }; };
3142E72722FCC19800DDA097 /* STPFPXBankBrand.h in Headers */ = {isa = PBXBuildFile; fileRef = 31F5B33322FCAC4000A71C64 /* STPFPXBankBrand.h */; settings = {ATTRIBUTES = (Public, ); }; };
314F9CC0235E66920059E2F6 /* STPFPXBankStatusResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 314F9CBE235E66920059E2F6 /* STPFPXBankStatusResponse.h */; };
314F9CC1235E66920059E2F6 /* STPFPXBankStatusResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 314F9CBE235E66920059E2F6 /* STPFPXBankStatusResponse.h */; };
314F9CC2235E66920059E2F6 /* STPFPXBankStatusResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 314F9CBF235E66920059E2F6 /* STPFPXBankStatusResponse.m */; };
314F9CC3235E66920059E2F6 /* STPFPXBankStatusResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 314F9CBF235E66920059E2F6 /* STPFPXBankStatusResponse.m */; };
315CB85322E7BD0E00E612A3 /* libStripe3DS2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 315CB85222E7BD0D00E612A3 /* libStripe3DS2.a */; };
315CB85522E7BD1400E612A3 /* Stripe3DS2.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 315CB85422E7BD1400E612A3 /* Stripe3DS2.bundle */; };
315CB86222E7D13600E612A3 /* libStripe3DS2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 315CB85222E7BD0D00E612A3 /* libStripe3DS2.a */; };
Expand Down Expand Up @@ -1594,6 +1598,8 @@
3142E72A22FCC26600DDA097 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
3142E72B22FCC26600DDA097 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
3142E72C22FCC26600DDA097 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
314F9CBE235E66920059E2F6 /* STPFPXBankStatusResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = STPFPXBankStatusResponse.h; sourceTree = "<group>"; };
314F9CBF235E66920059E2F6 /* STPFPXBankStatusResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPFPXBankStatusResponse.m; sourceTree = "<group>"; };
315CB85222E7BD0D00E612A3 /* libStripe3DS2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libStripe3DS2.a; path = InternalFrameworks/libStripe3DS2.a; sourceTree = "<group>"; };
315CB85422E7BD1400E612A3 /* Stripe3DS2.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Stripe3DS2.bundle; path = ../InternalFrameworks/Stripe3DS2.bundle; sourceTree = "<group>"; };
315CB8A322E7D95E00E612A3 /* STDSChallengeStatusReceiver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = STDSChallengeStatusReceiver.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3037,6 +3043,8 @@
8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */,
04CDB4C41A5F30A700B854EE /* STPFormEncoder.h */,
04CDB4C51A5F30A700B854EE /* STPFormEncoder.m */,
314F9CBE235E66920059E2F6 /* STPFPXBankStatusResponse.h */,
314F9CBF235E66920059E2F6 /* STPFPXBankStatusResponse.m */,
B32B175C20F6D2C4000D6EF8 /* STPGenericStripeObject.h */,
B32B175D20F6D2C4000D6EF8 /* STPGenericStripeObject.m */,
36239BB022960D52004FB1A5 /* STPIntentAction+Private.h */,
Expand Down Expand Up @@ -3442,6 +3450,7 @@
04F94DD31D22A23F004FC826 /* NSBundle+Stripe_AppName.h in Headers */,
3604007C22C18DB3004CF80B /* STPThreeDSUICustomization.h in Headers */,
F1D3A25B1EB014BD0095BFA9 /* UIImage+Stripe.h in Headers */,
314F9CC1235E66920059E2F6 /* STPFPXBankStatusResponse.h in Headers */,
B6B41F8022348A1E0020BA7F /* STPPaymentMethodiDEALParams.h in Headers */,
319A609A22E9186B00AACF66 /* STDSTextFieldCustomization.h in Headers */,
3142E72722FCC19800DDA097 /* STPFPXBankBrand.h in Headers */,
Expand Down Expand Up @@ -3746,6 +3755,7 @@
049880FC1CED5A2300EA4FFD /* STPPaymentConfiguration.h in Headers */,
C15608DD1FE08F2E0032AE66 /* UIView+Stripe_SafeAreaBounds.h in Headers */,
3621DDCA22A5E4FD00281BC4 /* STPAuthenticationContext.h in Headers */,
314F9CC0235E66920059E2F6 /* STPFPXBankStatusResponse.h in Headers */,
F1852F931D80B6EC00367C86 /* STPStringUtils.h in Headers */,
B6A46F7622FCDB81001991B2 /* STPPaymentIntentLastPaymentError.h in Headers */,
049A3FAE1CC9AA9900F57DE7 /* STPAddressViewModel.h in Headers */,
Expand Down Expand Up @@ -4643,6 +4653,7 @@
04B31DE91D09D25F00EF1631 /* STPPaymentOptionsInternalViewController.m in Sources */,
F12C8DC51D63DE9F00ADA0D7 /* STPPaymentContextAmountModel.m in Sources */,
04633B011CD129CB009D4FB5 /* STPPhoneNumberValidator.m in Sources */,
314F9CC3235E66920059E2F6 /* STPFPXBankStatusResponse.m in Sources */,
F152322D1EA9306100D65C67 /* NSURLComponents+Stripe.m in Sources */,
C159933F1D88089B0047950D /* STPShippingMethodsViewController.m in Sources */,
0413CB27233FECD5006429EA /* STPPushProvisioningDetails.m in Sources */,
Expand Down Expand Up @@ -4811,6 +4822,7 @@
31B9609222FE128C00DC6FD9 /* STPBankSelectionViewController.m in Sources */,
B63E42762231D78D007B5B95 /* STPPaymentMethodCardParams.m in Sources */,
049A3FAF1CC9AA9900F57DE7 /* STPAddressViewModel.m in Sources */,
314F9CC2235E66920059E2F6 /* STPFPXBankStatusResponse.m in Sources */,
073132972277A72D0019CE3F /* STPIssuingCardPin.m in Sources */,
04695ADC1C77F9EF00E08063 /* STPPhoneNumberValidator.m in Sources */,
C1785F5E1EC60B5E00E9CFAC /* STPCardIOProxy.m in Sources */,
Expand Down
9 changes: 9 additions & 0 deletions Stripe/PublicHeaders/STPBlocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@class STPSetupIntent;
@class STPPaymentMethod;
@class STPIssuingCardPin;
@class STPFPXBankStatusResponse;

/**
These values control the labels used in the shipping info collection form.
Expand Down Expand Up @@ -229,6 +230,14 @@ typedef void (^STPPinCompletionBlock)(STPIssuingCardPin * __nullable cardPin, ST
*/
typedef void (^STP3DS2AuthenticateCompletionBlock)(STP3DS2AuthenticateResponse * _Nullable authenticateResponse, NSError * _Nullable error);

/**
A callback to be run with a response from the Stripe API containing information about the online status of FPX banks.
@param bankStatusResponse The response from Stripe containing the status of the various banks. Will be nil if an error occurs. @see STPFPXBankStatusResponse
@param error The error returned from the response, or nil if none occurs.
*/
typedef void (^STPFPXBankStatusCompletionBlock)(STPFPXBankStatusResponse * _Nullable bankStatusResponse, NSError * _Nullable error);

/**
A block called with a payment status and an optional error.
Expand Down
75 changes: 43 additions & 32 deletions Stripe/PublicHeaders/STPFPXBankBrand.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,45 @@
typedef NS_ENUM(NSInteger, STPFPXBankBrand) {

/**
Affin Bank
Maybank2U
*/
STPFPXBankBrandAffinBank,
STPFPXBankBrandMaybank2U,

/**
Alliance Bank
CIMB Clicks
*/
STPFPXBankBrandAllianceBank,
STPFPXBankBrandCIMB,

/**
Public Bank
*/
STPFPXBankBrandPublicBank,

/**
RHB Bank
*/
STPFPXBankBrandRHB,

/**
Hong Leong Bank
*/
STPFPXBankBrandHongLeongBank,

/**
AmBank
*/
STPFPXBankBrandAmbank,

/**
Affin Bank
*/
STPFPXBankBrandAffinBank,

/**
Alliance Bank
*/
STPFPXBankBrandAllianceBank,

/**
Bank Islam
*/
Expand All @@ -48,16 +73,6 @@ typedef NS_ENUM(NSInteger, STPFPXBankBrand) {
*/
STPFPXBankBrandBSN,

/**
CIMB Clicks
*/
STPFPXBankBrandCIMB,

/**
Hong Leong Bank
*/
STPFPXBankBrandHongLeongBank,

/**
HSBC BANK
*/
Expand All @@ -73,26 +88,11 @@ typedef NS_ENUM(NSInteger, STPFPXBankBrand) {
*/
STPFPXBankBrandMaybank2E,

/**
Maybank2U
*/
STPFPXBankBrandMaybank2U,

/**
OCBC Bank
*/
STPFPXBankBrandOcbc,

/**
Public Bank
*/
STPFPXBankBrandPublicBank,

/**
RHB Bank
*/
STPFPXBankBrandRHB,

/**
Standard Chartered
*/
Expand All @@ -113,7 +113,7 @@ typedef NS_ENUM(NSInteger, STPFPXBankBrand) {
Returns a string representation for the provided bank brand;
i.e. `[NSString stringFromBrand:STPCardBrandUob] == @"UOB Bank"`.
@param brand the brand you want to convert to a string
@param brand The brand you want to convert to a string
@return A string representing the brand, suitable for displaying to a user.
*/
Expand All @@ -133,8 +133,19 @@ STPFPXBankBrand STPFPXBankBrandFromIdentifier(NSString *identifier);
Returns a string representation identifying the provided bank brand;
i.e. `STPIdentifierFromFPXBankBrand(STPCardBrandUob) == @"uob"`.
@param brand the brand you want to convert to a string
@param brand The brand you want to convert to a string
@return A string representing the brand, suitable for using with the service.
@return A string representing the brand, suitable for using with the Stripe API.
*/
NSString * STPIdentifierFromFPXBankBrand(STPFPXBankBrand brand);

/**
Returns the code identifying the provided bank brand in the FPX status API;
i.e. `STPIdentifierFromFPXBankBrand(STPCardBrandUob) == @"UOB0226"`.
@param brand The brand you want to convert to an FPX bank code
@param isBusiness Requests the code for the business version of this bank brand, which may be different from the code used for individual accounts
@return A string representing the brand, suitable for checking against the FPX status API.
*/
NSString * STPBankCodeFromFPXBankBrand(STPFPXBankBrand brand, BOOL isBusiness);
12 changes: 12 additions & 0 deletions Stripe/STPAPIClient+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,16 @@ fromCustomerUsingKey:(STPEphemeralKey *)ephemeralKey
+ (NSArray<NSString *> *)supportedPKPaymentNetworks;

@end

@interface STPAPIClient (FPXPrivate)

/**
Retrieves the online status of the FPX banks from the Stripe API.
@param completion The callback to run with the returned FPX bank list, or an error.
*/
- (void)retrieveFPXBankStatusWithCompletion:(STPFPXBankStatusCompletionBlock)completion;

@end

NS_ASSUME_NONNULL_END
14 changes: 14 additions & 0 deletions Stripe/STPAPIClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#import "STPEmptyStripeResponse.h"
#import "STPEphemeralKey.h"
#import "STPFormEncoder.h"
#import "STPFPXBankStatusResponse.h"
#import "STPGenericStripeObject.h"
#import "STPAppInfo.h"
#import "STPMultipartFormDataEncoder.h"
Expand Down Expand Up @@ -61,6 +62,7 @@
static NSString * const APIEndpointSetupIntents = @"setup_intents";
static NSString * const APIEndpointPaymentMethods = @"payment_methods";
static NSString * const APIEndpoint3DS2 = @"3ds2";
static NSString * const APIEndpointFPXStatus = @"fpx/bank_statuses";

#pragma mark - Stripe

Expand Down Expand Up @@ -813,4 +815,16 @@ - (void)createPaymentMethodWithParams:(STPPaymentMethodParams *)paymentMethodPar

}

#pragma mark - FPX

- (void)retrieveFPXBankStatusWithCompletion:(STPFPXBankStatusCompletionBlock)completion {
[STPAPIRequest<STPFPXBankStatusResponse *> getWithAPIClient:self
endpoint:APIEndpointFPXStatus
parameters:@{ @"account_holder_type": @"individual" }
deserializer:[STPFPXBankStatusResponse new]
completion:^(STPFPXBankStatusResponse *statusResponse, __unused NSHTTPURLResponse *response, NSError *error) {
completion(statusResponse, error);
}];
}

@end
2 changes: 1 addition & 1 deletion Stripe/STPBankSelectionTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN

@interface STPBankSelectionTableViewCell : UITableViewCell

- (void)configureWithBank:(STPFPXBankBrand)bankBrand theme:(STPTheme *)theme selected:(BOOL)selected enabled:(BOOL)enabled;
- (void)configureWithBank:(STPFPXBankBrand)bankBrand theme:(STPTheme *)theme selected:(BOOL)selected offline:(BOOL)offline enabled:(BOOL)enabled;

@end

Expand Down
7 changes: 6 additions & 1 deletion Stripe/STPBankSelectionTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import "STPCard.h"
#import "STPImageLibrary+Private.h"
#import "STPSource.h"
#import "STPLocalizationUtils.h"
#import "STPTheme.h"

@interface STPBankSelectionTableViewCell ()
Expand Down Expand Up @@ -82,7 +83,7 @@ - (void)layoutSubviews {
self.titleLabel.frame = labelFrame;
}

- (void)configureWithBank:(STPFPXBankBrand)bankBrand theme:(STPTheme *)theme selected:(BOOL)selected enabled:(BOOL)enabled {
- (void)configureWithBank:(STPFPXBankBrand)bankBrand theme:(STPTheme *)theme selected:(BOOL)selected offline:(BOOL)offline enabled:(BOOL)enabled {
self.bank = bankBrand;
self.theme = theme;

Expand All @@ -95,6 +96,10 @@ - (void)configureWithBank:(STPFPXBankBrand)bankBrand theme:(STPTheme *)theme sel
// Title label
self.titleLabel.font = theme.font;
self.titleLabel.text = STPStringFromFPXBankBrand(self.bank);
if (offline) {
NSString *format = STPLocalizedString(@"%@ - Offline", @"Bank name when bank is offline for maintenance.");
self.titleLabel.text = [NSString stringWithFormat:format, STPStringFromFPXBankBrand(self.bank)];
}
self.titleLabel.textColor = [self primaryColorForPaymentOptionWithSelected:self.selected enabled:enabled];

// Loading indicator
Expand Down
29 changes: 28 additions & 1 deletion Stripe/STPBankSelectionViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#import "NSArray+Stripe.h"
#import "STPAPIClient+Private.h"
#import "STPFPXBankStatusResponse.h"
#import "STPColorUtils.h"
#import "STPCoreTableViewController+Private.h"
#import "STPDispatchFunctions.h"
Expand All @@ -34,6 +35,7 @@ @interface STPBankSelectionViewController () <UITableViewDataSource, UITableView
@property (nonatomic, weak) UIImageView *imageView;
@property (nonatomic) STPSectionHeaderView *headerView;
@property (nonatomic) BOOL loading;
@property (nonatomic) STPFPXBankStatusResponse *bankStatus;
@end

@implementation STPBankSelectionViewController
Expand All @@ -52,11 +54,27 @@ - (instancetype)initWithBankMethod:(STPBankSelectionMethod)bankMethod
_configuration = configuration;
_selectedBank = STPFPXBankBrandUnknown;
_apiClient = [[STPAPIClient alloc] initWithConfiguration:configuration];
if (bankMethod == STPBankSelectionMethodFPX) {
[self _refreshFPXStatus];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_refreshFPXStatus) name:UIApplicationDidBecomeActiveNotification object:nil];
}
self.title = STPLocalizedString(@"Bank Account", @"Title for bank account selector");
}
return self;
}

- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)_refreshFPXStatus {
[self.apiClient retrieveFPXBankStatusWithCompletion:^(STPFPXBankStatusResponse * _Nullable bankStatusResponse, NSError * _Nullable error) {
if (error == nil && bankStatusResponse != nil) {
[self _updateWithBankStatus:bankStatusResponse];
}
}];
}

- (void)createAndSetupViews {
[super createAndSetupViews];

Expand All @@ -76,6 +94,14 @@ - (BOOL)useSystemBackButton {
return YES;
}

- (void)_updateWithBankStatus:(STPFPXBankStatusResponse *)bankStatusResponse {
self.bankStatus = bankStatusResponse;

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:self.tableView.indexPathsForVisibleRows withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}

#pragma mark - UITableView

- (NSInteger)numberOfSectionsInTableView:(__unused UITableView *)tableView {
Expand All @@ -91,7 +117,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView
STPBankSelectionTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:STPBankSelectionCellReuseIdentifier forIndexPath:indexPath];
STPFPXBankBrand bankBrand = indexPath.row;
BOOL selected = self.selectedBank == bankBrand;
[cell configureWithBank:bankBrand theme:self.theme selected:selected enabled:!self.loading];
BOOL offline = self.bankStatus && ![self.bankStatus bankBrandIsOnline:bankBrand];
[cell configureWithBank:bankBrand theme:self.theme selected:selected offline:offline enabled:!self.loading];
return cell;
}

Expand Down
Loading

0 comments on commit 7152797

Please sign in to comment.