支付授權(quán)過(guò)程是由支付授權(quán)視圖控制器與其委托合作完成的。支付授權(quán)視圖控制器做了兩件事:
用戶與視圖控制器交互時(shí),委托方法會(huì)被系統(tǒng)調(diào)用,所以在這些方法中你的應(yīng)用可以更新所要顯示的信息。例如在配送地址修改后更新配送價(jià)格。在用戶授權(quán)支付請(qǐng)求后此方法還會(huì)被調(diào)用一次。
注意:
在實(shí)現(xiàn)這些委托方法時(shí),你應(yīng)該謹(jǐn)記它們會(huì)被多次調(diào)用并且這些方法調(diào)用的順序是取決與用戶的操作順序的。
所有的這些委托方法在授權(quán)過(guò)程中都會(huì)被調(diào)用,傳入該方法的其中一個(gè)參數(shù)是一個(gè)完成塊 (completion block)。支付授權(quán)視圖控制器等待一個(gè)委托完成相應(yīng)的方法后 (通過(guò)調(diào)用完成塊) 再依次調(diào)用其它的委托方法。paymentAuthorizationViewControllerDidFinish: 方法是唯一例外:它并不需要一個(gè)完成塊作為參數(shù),它可以在任何時(shí)候被調(diào)用。
完成塊接受一個(gè)輸入?yún)?shù),該參數(shù)為應(yīng)用程序根據(jù)信息判斷得到的支付事務(wù)的當(dāng)前狀態(tài)。如果支付事務(wù)一切正常,則應(yīng)傳入值 PKPaymentAuthorizationStatusSuccess。否則,可以傳入能識(shí)別出錯(cuò)誤的值。
創(chuàng)建 PKPaymentAuthorizationViewController 類(lèi)的實(shí)例時(shí),你需要將已初始化后的支付請(qǐng)求傳遞給視圖控制器初始化函數(shù)。接著,設(shè)置視圖控制器的委托;然后再顯示它:
PKPaymentAuthorizationViewController *viewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
if (!viewController) { /* ... Handle error ... */ }
viewController.delegate = self;
[self presentViewController:viewController animated:YES completion:nil];
當(dāng)用戶與視圖控制器交互時(shí),視圖控制器就會(huì)調(diào)用其委托方法:
注意:
在 Xcode 7.0 及其后的版本中,你可以在模擬器中測(cè)試支付授權(quán)視圖控制器。這些版本的模擬器提供了支持所有支付網(wǎng)絡(luò)的虛擬卡,它會(huì)以純文本的方式返回虛擬支付數(shù)據(jù)。在設(shè)備上時(shí),這些數(shù)據(jù)會(huì)使用商戶 ID 進(jìn)行加密。
雖然模擬器可以方便快捷地測(cè)試支付代碼,但是你仍然需要在物理設(shè)備上測(cè)試你的支付功能。
如果你使用的是較早版本的 Xcode,那么你就只能在物理設(shè)備上測(cè)試你的支付功能了。
當(dāng)用戶輸入配送信息時(shí),授權(quán)視圖控制器會(huì)調(diào)用委托的 paymentAuthorizationViewController:didSelectShippingContact:completion: 方法和 paymentAuthorizationViewController:didSelectShippingMethod:completion: 方法。你可以實(shí)現(xiàn)這兩個(gè)方法來(lái)更新你的支付請(qǐng)求。
- (void) paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
didSelectShippingContact:(CNContact *)contact
completion:(void (^)(PKPaymentAuthorizationStatus, NSArray *, NSArray *))completion
{
self.selectedContact = contact;
[self updateShippingCost];
NSArray *shippingMethods = [self shippingMethodsForContact:contact];
completion(PKPaymentAuthorizationStatusSuccess, shippingMethods, self.summaryItems);
}
- (void) paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
didSelectShippingMethod:(PKShippingMethod *)shippingMethod
completion:(void (^)(PKPaymentAuthorizationStatus, NSArray *))completion
{
self.selectedShippingMethod = shippingMethod;
[self updateShippingCost];
completion(PKPaymentAuthorizationStatusSuccess, self.summaryItems);
}
注意:
為了保護(hù)用戶隱私,提供給方法 paymentAuthorizationViewController:didSelectShippingContact:completion: 的配送信息是經(jīng)過(guò)匿名化處理后的數(shù)據(jù)。返回的 contact 包含了計(jì)算配送費(fèi)用的所有信息同時(shí)隱藏了用戶的敏感信息。只有在用戶授權(quán)支付后,你才能得到用戶完整的配送信息。此外, contact 中的數(shù)據(jù)會(huì)隨著國(guó)家的不同而不同,同時(shí)還會(huì)隨著版本的更新而變化。請(qǐng)仔細(xì)測(cè)試你的應(yīng)用程序。
當(dāng)用戶授權(quán)一個(gè)支付請(qǐng)求時(shí),支付框架的 Apple 服務(wù)器與安全模塊會(huì)協(xié)作創(chuàng)建一個(gè)支付令牌。你可以在委托方法 paymentAuthorizationViewController:didAuthorizePayment:completion: 中將支付信息以及其它你需要處理的信息,例如配送地址和購(gòu)物車(chē)標(biāo)識(shí)符,一起發(fā)送至你的服務(wù)器。這個(gè)過(guò)程如下所示:
在服務(wù)器上的處理操作取決于你是自己處理支付還是使用其它支付平臺(tái)。不過(guò),在兩種情況下服務(wù)器都得處理訂單再將處理結(jié)果返回給設(shè)備。在設(shè)備上,委托再將處理結(jié)果傳入完成處理方法中,詳細(xì)過(guò)程請(qǐng)參閱 處理支付
- (void) paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
didAuthorizePayment:(PKPayment *)payment
completion:(void (^)(PKPaymentAuthorizationStatus))completion
{
NSError *error;
ABMultiValueRef addressMultiValue = ABRecordCopyValue(payment.billingAddress, kABPersonAddressProperty);
NSDictionary *addressDictionary = (__bridge_transfer NSDictionary *) ABMultiValueCopyValueAtIndex(addressMultiValue, 0);
NSData *json = [NSJSONSerialization dataWithJSONObject:addressDictionary options:NSJSONWritingPrettyPrinted error: &error];
// ... Send payment token, shipping and billing address, and order information to your server ...
PKPaymentAuthorizationStatus status; // From your server
completion(status);
}
支付框架顯示完支付事務(wù)狀態(tài)后,授權(quán)視圖控制器會(huì)調(diào)用委托的 aymentAuthorizationViewControllerDidFinish: 方法。在此方法的實(shí)現(xiàn)中,你應(yīng)該釋放授權(quán)視圖控制器然后再顯示與應(yīng)用相關(guān)的支付信息界面。
- (void) paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller
{
[controller dismissViewControllerAnimated:YES completion:nil];
}