工作笔记之难点记录
最近项目中用到了Stripe进行支付,我们公司主要是做一些国外的项目,当然也有国内的项目,国外的项目居多,言归正传,那么stripe是什么?网上一搜,其实可以搜到一大堆,关于这个公司的介绍,这个公司主要是做信用卡支付的一个公司,那么我们公司的需求是是什么,第一,信用卡支付,第二debit卡取现,所以我们就得用到了Stripe的SDK
相对于来,支付流程是很简单的,因为这个sdk中为我们封装了几个特别好用的页面,如果没有特殊的需求直接用这个就好了。
支付的时候我们主要用到了一个“STPPaymentContext”,“STPPaymentMethodsViewController”,“STPAddCardViewController”这两个类,那么这两个类是干什么的呢?第一个类其实是一个管理上下文,第二个其实就是一个选择支付方式的controller,第三个是添加卡的一个VIewController。其实这一切都是stripeSDK封装好了,我们需要写一个和我们自己后台沟通的类遵循STPBackendAPIAdapter协议,实现协议的方法,在SDK内部会调用这些方法,获取数据,这时我就不得不说这就是大神写的啊!!思路,这种设计模式用的太恰当了。强力推荐看一下源码,这个sdk中有许多特别好的设计模式,实战。然后初始化context,初始化会用到我们刚才提到的类,基本的初始化好了之后,我们只要在需要选择支付的地方,用context调用pushPaymentMethodsViewController或者presentPaymentMethodsViewController,就可以了,接下来的事情,就是在代理方法中做了,我们发送该有token和数据等等给我们后台,让他们跟stripe交互,完成支付。这都有example,和详细的文档,所以很简单,重点我要说的是第二个问题payout,自动体现。
payout 这里边的坑真是不少啊,让我寝食难安了好多天。因为什么,官网中只字未提到,ios或者安卓的payout,没有example,这怎么办,那就得靠自己去看源码,有没有关于payout的东西,自己一点一点发觉。由于这部分内容很少,所以包括后台的文档也很少,所以我们都是在一点点的探索中弄出来的,开始的时候,产品需求也没实际弄明白这部分东西,所以就给了和payment一样的支付方式页面,和添加卡页面,开始我和PL都以为可能payment和payout这两个页面是公用的,可是很快我就发现了不对劲,于是乎我通读了文档中后台api文档关于payout相关的,发现大家都搞错了,这是两码事,而且这个页面也不能用一个页面,payment的卡token和payout的token生成不一样,并且生成方式不一样。于是我和PL开了一个小会,怎么弄。PL说要不用分别给STPAddCardViewController,STPPaymentMethodsViewController写个分类,我觉得这种方式不行,因为这两个类里边有很多的逻辑,写一个分类,即使写好多方法,也不能确定能控制以前payment的逻辑变成payout的逻辑,然后我提出用继承,重写有关于这部分的方法,虽然也不容易控制但是毕竟会比分类好很多,但是实际情况又是不行,因为stripe在做sdk的时候有很多文件都是private的,所以不允许我们继承,这个也不行,那个也不行,这怎么办呢,已经两天过去了,PL也着急,我也着急,之后那天晚上回家,我又仔细看了一遍文档,突然眼前一亮,有了想法,为什么我们要依赖SDK呢,我们就自己写一个卡列表页面,和添加卡页面,这样所有的逻辑都由我们自己控制了,于是第二天迫不及待的和PL提出了我的想法,PL同意了说,就按照你的想法做吧。很快,一天搞定了这两个东西,下面贴出重要的代码:
ACPayoutAddCardViewController
- (void)nextPressed:(UIButton *)btn{
self.loading = YES;
STPBankAccountParams *params = [[STPBankAccountParams alloc] init];
params.accountNumber = [_accountNumCell.textField.textstringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
params.routingNumber = [_routingNumCell.textField.textstringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
params.accountHolderName = _accountNameCell.textField.text;
NSString *accountType = [_accountTypeCell.textField.textstringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
params.accountHolderType = [accountType isEqualToString:@"Individual"] ?STPBankAccountHolderTypeIndividual:STPBankAccountHolderTypeCompany;
params.currency = @"usd";
params.country = @"US";
[[STPAPIClientsharedClient]createTokenWithBankAccount:params completion:^(STPToken * _Nullable token, NSError * _Nullable error) {
if (error) {
[self handleCardTokenError:error];
} else {
[self creatPayoutBankAccountWithToken:token.tokenIdandComplete:^(NSError* _Nullable error) {
NSLog(@"%@", error.localizedDescription);
self.loading = NO;
if (error) {
[self handleCardTokenError:error];
} else {
[self.delegate payoutAddCardViewControllerDidAddCardSuccess:selfandToken:token];
}
}];
}
}];
}
ACPayoutMethodViewController
- (void)loadData {
if(!_activityIndicator) {
[selfsetUp];
}
self.activityIndicator.animating =YES;
self.tableView.hidden =YES;
[_apiAdapter retrieveCustomer:^(STPCustomer * _Nullable customer,NSError* _Nullable error) {
if(error) {
[selfshowSystemAlertViewWithTitle:@""andText:error.localizedDescription andHandle:nil];
}else{
self.tableView.hidden =NO;
self.activityIndicator.hidden =YES;
[self.activityIndicator removeFromSuperview];
STPCard *selectedCard;
NSMutableArray *cards = [NSMutableArrayarray];
for(id sourceincustomer.sources) {
if([source isKindOfClass:[STPCardclass]]) {
STPCard *card = (STPCard *)source;
[cards addObject:card];
if([card.stripeID isEqualToString:customer.defaultSource.stripeID]) {
selectedCard = card;
}
}
}
ACPayoutCardTuple *cardTuple = [ACPayoutCardTuple payoutCardTupleWithCards:cards andSelectedCard:selectedCard];
_cardTuple = cardTuple;
[self.tableView reloadData];
}
}];
}
#pragma mark - ADD Card Delegate
- (void)payoutAddCardViewControllerDidAddCardSuccess:(ACPayoutAddCardViewController *) payoutAddCardViewController andToken:(STPToken *)token{
NSMutableArray*array = [NSMutableArrayarrayWithArray:self.cardTuple.cards];
if(token.card) {
[array addObject:token.card];
}else{
STPCard *card = [[STPCard alloc] initWithID:token.bankAccount.bankAccountId brand:STPCardBrandUnknown last4:token.bankAccount.last4 expMonth:0expYear:0funding:STPCardFundingTypeDebit];
[array addObject:card];
}
[payoutAddCardViewController.navigationController popViewControllerAnimated:YES];
self.cardTuple.cards = [array mutableCopy];
[self.tableView reloadData];
}