前文
前段時間在空暇時間寫了GoogleMaps的使用指南,剛寫完的一段時間,發(fā)現(xiàn)并沒有人閱讀,所以不太想寫第二篇,覺得幫助意義不大,最近看到有幾個同行給我發(fā)私信和評論問我一些相關問題,這才有寫這篇文章的想法,我覺得一些東西,單單是自己知道,是沒有價值的,技術的價值體現(xiàn)在分享的過程中,你分享的越多,價值自然而然就體現(xiàn)出來了,大家都在你的文章中有所收獲,就是值得的。
- 廢話不多說,下面步入正文
關于Stripe
在沒有做公司海外項目之前,還沒有聽說過Stripe,所以做了一下簡單了解,其實就是一種信用卡支付方式的集成,相當于一個虛擬的信用卡卡包,里面裝有用戶的信用卡,然后在支付的時候,會讓用戶選擇自己的信用卡進行支付,很便捷,支持的信用卡種類很多。詳細了解請移步點擊進入Stripe官網(wǎng)
集成Stripe
關于集成,之前在說GoogleMaps的時候就有過相關闡述,我覺得CocoaPods是相對來說方便,并且安全系數(shù)相對較低的一種集成方式,如果用CocoaPods方式集成,尤其要注意相關用法。本文也只說明CocoaPods集成方式,對于其他方式,Stripe官網(wǎng)有指出點擊進入,因為是第一次集成Stripe,踩了一些坑,在這說明一下,Stripe的GitHub中有給出每次更新的內(nèi)容,但是當我下載完的時候對比官方文檔中少了幾個必須類,很是苦惱,之后才發(fā)現(xiàn)自己通過CocoaPods導入的并非最新版本,不過沒關系,只需要pod update一下就可以更新到最新版本,有點大驚小怪。
Stripe業(yè)務邏輯
在我現(xiàn)在做的項目中業(yè)務邏輯很簡單,在此說明一下,方便讀者理解。
- 在新建用戶的同時,后臺這邊根據(jù)一些用戶信息比如獨一無二的user_id類似字段去Stripe服務器申請一個用戶的Stripe標識,在拿到Stripe標識之后相當于這個用戶已經(jīng)在Stripe服務器上有了記錄。
- 在用戶進行第一次付款的時候,app會通過請求server數(shù)據(jù)進行判定當前用戶是否有綁定的信用卡或者默認的付款方式,如果判定用戶是第一次付款,先進行添加信用卡操作。
- 用戶可以自己在信用卡管理界面進行增加和刪除行用卡操作。
Stripe具體操作實踐--添加卡片
因為Stripe的操作難度并不復雜所以我覺得分開講更容易理解,這是添加信用卡片的代碼
- (IBAction)addCardAction:(id)sender {
_addCardBtn.userInteractionEnabled = NO;
STPCardParams *cardParams = [[STPCardParams alloc]init];
cardParams.number = _paymentTextField.cardParams.number;
cardParams.expMonth = _paymentTextField.cardParams.expMonth;
cardParams.expYear = _paymentTextField.cardParams.expYear;
cardParams.cvc = _paymentTextField.cardParams.cvc;
[SVProgressHUD showWithStatus:[NSString stringWithFormat:@"%@···",NSLocalizedString(@"cardGroupAddCardProgressKey", nil)]];
[[STPAPIClient sharedClient] createTokenWithCard:cardParams completion:^(STPToken * _Nullable token, NSError * _Nullable error) {
_addCardBtn.userInteractionEnabled = YES;
if (error) {
[SVProgressHUD dismiss];
NSLog(@"%@",[error description]);
[self.view makeToast:NSLocalizedString(@"addCardInfoErrorKey", nil) duration:1 position:CSToastPositionCenter];
} else {
NSLog(@"添加成功 tokenId:%@ cardId:%@",token.tokenId,token.card.cardId
);
[self stripePayActionWithTokenid:token.tokenId];
}
}];
}
代碼中出現(xiàn)了STPCardParams和STPAPIClient類,這兩個類簡單說明一下,前者是手機信用卡信息的一個類,包括信用卡的安全碼,卡號,日期之類的信息,服務器返回給前端的數(shù)據(jù)是一個json數(shù)據(jù),要轉model賦值給STPCardParams對象,STPAPIClient類是Stripe中的API類,一些和Stripe Server的交互都是從這個類里面調(diào)度,一些基本的操作大多是這樣,前端添加一張卡片,在填寫好卡片信息之后,根據(jù)API給出的提示填寫好param提交,會從Stripe server那里得到一個tokenId,這個tokenId要傳回給自己的server,然后公司的server會拿著這個tokenId去執(zhí)行對應的操作,所以真正的一些付款和添加卡片的操作都是服務器完成的,前端只是做一下調(diào)度。
Stripe具體操作實踐--付款
Stripe付款分為兩種,第一種是普通的付款行為,另外一種是集成ApplePay,
分開講一下,其實兩種的原理是相同的。
普通的付款流程
- (void)paymentActionWithCardId:(NSString *)cardId{
[SVProgressHUD showWithStatus:[NSString stringWithFormat:@"%@···",NSLocalizedString(@"cardGroupPayingKey", nil)]];
NSDictionary *param;
if ([_paySource isEqualToString:@"topupbalance"]) {
param = [NSDictionary dictionaryWithObjectsAndKeys:@"3",@"paysrc",@"3",@"type",cardId,@"card_id",_total_fee,@"total_fee", nil];
} else {
param = [NSDictionary dictionaryWithObjectsAndKeys:@"3",@"paysrc",@"1",@"type",cardId,@"card_id", nil];
}
NSString *url = [NSString stringWithFormat:@"%@deposit",REQUEST_HOST];
[JJBaseRequestHelper requestWithRequestMethod:@"post" isShowDialogView:YES parameters:param urlName:url formData:nil success:^(id ResponseObject) {
[SVProgressHUD dismiss];
if ([[[[[ResponseObject objectForKey:@"data"] objectForKey:@"param"] objectForKey:@"stripe"]description] isEqualToString:@"ok"]) {
NSLog(@"success");
[self.navigationController.view makeToast:NSLocalizedString(@"cardGroupPaymentSuccessKey", nil) duration:1 position:CSToastPositionCenter];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if ([_paySource isEqualToString:@"topupbalance"]) {
[self topupBalanceSuccessAction];
} else {
[self paymentDepositSuccessAction];
}
});
}
} failure:^(NSString *Message) {
[SVProgressHUD dismiss];
[self.navigationController.view makeToast:NSLocalizedString(@"cardGroupPaymentFailedKey", nil) duration:1 position:CSToastPositionCenter];
}];
}
這段代碼看起來很簡單,不需要多說吧,只是從信用卡列表中選擇了一個信用卡對象,然后拿到卡的CardId就可以傳回給公司的服務器進行付款了,很簡單。
ApplePay付款方式
//這個代理方法指的是支付過程中會進行調(diào)用
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
didAuthorizePayment:(PKPayment *)payment
completion:(void (^)(PKPaymentAuthorizationStatus status))completion
{
NSLog(@"%@",payment);
[[STPAPIClient sharedClient] createTokenWithPayment:payment completion:^(STPToken * _Nullable token, NSError * _Nullable error) {
NSLog(@"error = %@",error);
NSLog(@"token = %@",token);
if (!token) {
_isPaymentSuccess = NO;
completion(PKPaymentAuthorizationStatusFailure);
} else {
NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:@"4",@"paysrc",@"3",@"type",token,@"token",_total_fee,@"total_fee", nil];
NSString *url = [NSString stringWithFormat:@"%@recharge",REQUEST_HOST];
[JJBaseRequestHelper requestWithNSURLSessionMethod:@"post" parameters:param urlName:url success:^(id ResponseObject) {
if ([[[[[ResponseObject objectForKey:@"data"] objectForKey:@"param"] objectForKey:@"applepay"]description] isEqualToString:@"ok"]) {
_isPaymentSuccess = YES;
dispatch_async(dispatch_get_main_queue(), ^{
completion(PKPaymentAuthorizationStatusSuccess);
});
} else {
_isPaymentSuccess = NO;
completion(PKPaymentAuthorizationStatusFailure);
}
} failure:^(NSString *Message) {
_isPaymentSuccess = NO;
completion(PKPaymentAuthorizationStatusFailure);
}];
}
}];
}
用過ApplePay的應該知道這個代理方法,是支付過程中的Delegate方法,[[STPAPIClient sharedClient] createTokenWithPayment:payment completion,這個方法是STPAPIClient中對于蘋果支付單獨給出的一個方法,大致相同,區(qū)別在于蘋果支付的時候Stripe會在這個方法中把你再wallet中選擇的card轉換成Stripe中的信用卡對象,然后就和普通的支付流程一樣了,是不是很簡單。
總結
可能很多小伙伴在看Stripe文檔的時候都覺得很糊涂,其實不單是你們糊涂,我看的時候,也相當費解,我在文中并沒有提到STPPaymentContext這個類,因為我覺得作為初學者,想看懂這個難度還是有一點的,Stripe的官方代碼耦合度還是不低的,要看懂demo的付款流程,時間還是要一點的,總體來說demo里面只不過給你集成好了卡的管理界面和添加卡片的界面 ,但是我覺得如果你想更好的利用Stripe,就不要去采用這些東西,為了耦合度更低,最好是自己像我這樣通過Stripe給出來的組件自己集成界面,這樣很簡單,而且也降低了界面耦合度,以后維護起來,也只需要改動一下View層即可,有看完這篇文章依然很困惑的小伙伴,可以在評論區(qū)評論,看到評論我會及時回復,露珠可能最近要換一份新工作,祝我好運吧!