Authorizing Payments
支付授權(quán)處理是支付授權(quán)視圖控制器和它的代理之間的協(xié)力合作的結(jié)果。支付授權(quán)視圖控制器做兩件事:讓用戶選擇支付請(qǐng)求中所需要的賬單和運(yùn)送信息,讓用戶去授權(quán)支付。當(dāng)用戶和視圖控制器交互時(shí)調(diào)用代理的方法以便app可以更新展示的信息-例如:當(dāng)一個(gè)運(yùn)送地址被選擇時(shí)更新運(yùn)送價(jià)格。在用戶授權(quán)支付請(qǐng)求之后調(diào)用該代理。
注意:
當(dāng)實(shí)現(xiàn)代理方法時(shí),記得它們會(huì)被調(diào)用很多次并且它們被調(diào)用的規(guī)則取決于用戶的動(dòng)作順序。
所有在授權(quán)處理期間調(diào)用的代理方法均傳送一個(gè)完成的block
作為它們的參數(shù)之一。在它調(diào)用其他代理方法之前,支付授權(quán)視圖控制器等待代理完成響應(yīng)一個(gè)方法(通過調(diào)用完成block
)。paymentAuthorizationViewControllerDidFinish:
方法是唯一的例外。它沒有取到完成block
,但是它在任何時(shí)候均可被調(diào)用。
完成 block
取到一個(gè)論證,該論證可以指定基于可用信息的交易的當(dāng)前授權(quán)狀態(tài)。如果該交易沒有任何問題,傳送該值PKPaymentAuthorizationStatusSuccess
;否則,傳送一個(gè)值來標(biāo)識(shí)錯(cuò)誤。
為了創(chuàng)建一個(gè)PKPaymentAuthorizationViewController
類的實(shí)例,傳送支付請(qǐng)求給視圖控制器的初始化。設(shè)置該視圖控制器的代理,然后顯示它。
PKPaymentAuthorizationViewController *viewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
if (!viewController) { /* ... Handle error ... */ }
viewController.delegate = self;
[self presentViewController:viewController animated:YES completion:nil];
當(dāng)用戶與視圖控制器交互時(shí),視圖控制器調(diào)用它的代理方法。
注意:
在Xcode 7.0或者以后,可以在模擬器上測(cè)試支付授權(quán)視圖控制器。它提供了所有支持的支付系統(tǒng)的模擬卡片并以簡(jiǎn)單的文本形式返回虛擬的支付數(shù)據(jù)。在設(shè)備上,該數(shù)據(jù)使用商戶標(biāo)識(shí)加密并必須在自己的服務(wù)器上或者在支付處理時(shí)解密。
雖然模擬器提供一個(gè)快捷而且方便的方式測(cè)試自己的代碼,仍然需要在真實(shí)的物理設(shè)備上完全地測(cè)試Apple Pay。
如果使用 Xcode的早期版本,僅僅可以在設(shè)備上測(cè)試Apple Pay。
Your Delegate Updates Shipping Methods 代理更新運(yùn)送方式和費(fèi)用
當(dāng)用戶提供運(yùn)送信息時(shí),授權(quán)視圖控制器調(diào)用代理的paymentAuthorizationViewController:didSelectShippingContact:completion:
方法和paymentAuthorizationViewController:didSelectShippingMethod:completion:
方法。使用這些方法來更新基于這些新信息的支付請(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:
方法中提及的運(yùn)送信息是匿名的。返回的聯(lián)系方式包含足夠的信息用以計(jì)算運(yùn)費(fèi),不展現(xiàn)用戶的敏感信息。直到用戶批準(zhǔn)了該支付之后,才能獲取到用戶的全部運(yùn)送信息,否則不能獲取到。另外,聯(lián)系方式中的數(shù)據(jù)可以根據(jù)不同的國(guó)家而改變,并可以一次又一次地改變。保證以合適的方式測(cè)試app。
A Payment Token Is Created When a Payment Is Authorized 當(dāng)支付被授權(quán)時(shí)生成一個(gè)支付密鑰
當(dāng)用戶授權(quán)支付請(qǐng)求時(shí),框架通過Apple 服務(wù)器和安全元件聯(lián)合生成一個(gè)支付密鑰。可以通過paymentAuthorizationViewController:didAuthorizePayment:completion:
代理方法傳送該支付密鑰給自己的服務(wù)器,與其它需要的信息一起處理購(gòu)買。例如:運(yùn)送地址和購(gòu)物車標(biāo)識(shí)。過程如下:
- 1.框架發(fā)送支付請(qǐng)求給安全元件。只有安全元件可以使用tokenized標(biāo)記化的特定設(shè)備的支付卡號(hào)。
- 2.安全元件將含有特定卡和商戶的支付數(shù)據(jù) 放在一起,加密它使得只有Apple 可以讀取它,并發(fā)送它給框架。框架然后發(fā)送支付數(shù)據(jù)給Apple 服務(wù)器。
- 3.Apple 服務(wù)器使用Merchant Identifier certificate商戶標(biāo)識(shí)證書解密支付數(shù)據(jù)。該密鑰僅僅自己和那些已分享商戶標(biāo)識(shí)證書給他們的人可讀。然后服務(wù)器寫下該支付密鑰,并返回它給設(shè)備。
- 4.框架通過調(diào)用
paymentAuthorizationViewController:didAuthorizePayment:completion:方法傳送該密鑰給代理。代理傳送該密鑰給自己的服務(wù)器。
在自己服務(wù)器上的行為改變?nèi)Q于是否處理自己的支付或者對(duì)一個(gè)支付平臺(tái)有效。在兩種情況下,服務(wù)器處理訂單并傳送一個(gè)狀態(tài)返回給設(shè)備,代理可傳送給它的完成處理者,具體描述在Processing a Payment。
- (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);
}
Your Delegate Dismisses the Payment Authorization View Controller代理dismiss支付授權(quán)視圖控制器
當(dāng)框架顯示交易的狀態(tài)之后,授權(quán)視圖控制器調(diào)用代理的paymentAuthorizationViewControllerDidFinish:
方法。在實(shí)施階段,dismiss
授權(quán)視圖控制器并且顯示自己app特定的訂單確認(rèn)頁(yè)面。
- (void) paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller
{
[controller dismissViewControllerAnimated:YES completion:nil];
}