Apple Pay編程指導(dǎo)

1.About Apple Pay

Apple Pay是一種移動(dòng)支付技術(shù),讓使用者把它們對(duì)真實(shí)的物品和服務(wù)的支付信息以一種方便和安全的方式給你。

對(duì)于在app中給出的數(shù)字物品和服務(wù),可查看In-App Purchase Programming Guide

Working with Apple Pay

使用Apple Pay功能的Apps需要在Xcode 中開(kāi)啟Apple Pay capabilities。也需要注冊(cè)一個(gè)商家標(biāo)識(shí)并設(shè)置密鑰(用來(lái)加密發(fā)送支付數(shù)據(jù)給服務(wù)器)。

初始化支付時(shí),app創(chuàng)建一個(gè)支付請(qǐng)求。該請(qǐng)求包含幾乎全部的服務(wù)和商品購(gòu)買,也包含任何額外的費(fèi)用:稅金、運(yùn)費(fèi)或者折扣。傳送該請(qǐng)求給支付授權(quán)視圖控制器,控制器展示該請(qǐng)求給用戶并對(duì)任何需要的信息作出提示,例如運(yùn)送地址或者賬單地址。當(dāng)用戶與視圖控制器進(jìn)行交互時(shí),調(diào)用代理用以更新請(qǐng)求。

一旦用戶授權(quán)支付,Apple Pay加密支付信息用以保護(hù)未授權(quán)的第三方訪問(wèn)它。在設(shè)備上,Apple Pay發(fā)送支付請(qǐng)求給加密元件,該元件是一個(gè)用戶設(shè)備上的專用芯片。該加密元件添加支付信息為指定的卡和商家生成一個(gè)加密的支付密鑰。然后傳遞該密鑰給Apple 服務(wù)器,在服務(wù)器上使用商家標(biāo)識(shí)證書(shū)(Merchant Identifier certificate)解密。最后,服務(wù)器傳遞該密鑰返回到app中繼續(xù)處理。

支付密鑰從不訪問(wèn)或者存取在Apple服務(wù)器上。該服務(wù)器僅僅可使用證書(shū)解密密鑰。這種處理使得不用加密證書(shū)app安全的加密支付信息,且必須分配商家標(biāo)識(shí)證書(shū)作為app的一部分。

更多關(guān)于Apple Pay安全的信息,可查看iOS Security Guide

大多數(shù)情況下,app傳送加密密鑰給第三發(fā)支付平臺(tái)解密并處理支付。然而,如果自己的團(tuán)隊(duì)有已經(jīng)存在的支付基礎(chǔ)設(shè)施,可以在自己的服務(wù)器上解密并處理支付。

更多關(guān)于支持Apple Pay的支付平臺(tái)的信息,可查看develop.apple.com/apple-pay/

2.Configuring Your Environment

商戶ID用來(lái)判別用戶是否對(duì)Apple Pay能夠接受支付。與商戶ID有關(guān)的公共的鑰匙和證書(shū)被用來(lái)作為支付進(jìn)程的一部分,用來(lái)加密支付信息。在app可以使用Apple Pay之前,需要注冊(cè)一個(gè)merchant ID商戶ID 并配置它的證書(shū)。

注冊(cè)商戶ID(a merchant ID)

  • 1.在會(huì)員中心(Member Center),選擇Certificates,Identifiers & Profiles(http://developer.apple.com/account)選項(xiàng)。
  • 2.在Identifiers選項(xiàng)下面,選擇Merchant IDs選項(xiàng)。
  • 3.點(diǎn)擊右上角的添加按鈕(+)。
  • 4.輸入一段描述和標(biāo)識(shí),點(diǎn)擊Continue繼續(xù)按鈕。
  • 5.檢查設(shè)置內(nèi)容,然后點(diǎn)擊Register注冊(cè)按鈕。
  • 6.點(diǎn)擊Done 按鈕,完成。

配置商戶ID相應(yīng)的證書(shū)

  • 1.在會(huì)員中心(Member Center)(https://developer.apple.com),選擇Certificates,Identifiers & Profiles選項(xiàng)。
  • 2.在Identifiers選項(xiàng)下面,選擇Merchant IDs選項(xiàng)。
  • 3.從列表中選擇商戶ID(merchant ID),點(diǎn)擊Edit編輯按鈕。
  • 4.點(diǎn)擊Create Certificate按鈕生成證書(shū),跟隨獲得的說(shuō)明或是生成一個(gè)CSR(certificate signing request),點(diǎn)擊Continue按鈕。
  • 5.點(diǎn)擊選擇文件,選中CSR文件,點(diǎn)擊Generate按鈕。
  • 6.點(diǎn)擊Download按鈕下載該證書(shū),并點(diǎn)擊Done按鈕,完成。

如果在鑰匙串使用中看見(jiàn)一個(gè)警告warning ,說(shuō)明證書(shū)被未知的認(rèn)證授權(quán)簽名或者它是一個(gè)無(wú)效的發(fā)行者,確認(rèn)有the WWDR intermediate certificate - G2證書(shū)并在鑰匙串中安裝了the Apple Root CA - G2。這些可以在apple.com/certificateauthority 下載得到。


注意:
當(dāng)出現(xiàn)故障時(shí),有時(shí)候這對(duì)手動(dòng)開(kāi)啟Apple Pay功能有所幫助。跟隨下面的步驟手動(dòng)開(kāi)啟Apple Pay功能。

  • 1.在會(huì)員中心(Member Center),選擇Certificates ,Identifiers & Profiles選項(xiàng)。
  • 2.在Identifiers選項(xiàng)下,選擇App IDs選項(xiàng)。
  • 3.從列表中選中app ID,點(diǎn)擊Edit按鈕。
  • 4.選擇Apple Pay選項(xiàng),點(diǎn)擊Edit按鈕。
  • 5.選擇準(zhǔn)備使用的商戶IDs(merchant IDs),點(diǎn)擊Continue按鈕。
  • 6.檢查設(shè)置內(nèi)容,然后點(diǎn)擊Assign指派按鈕。
  • 7.點(diǎn)擊Done按鈕,完成。

3.Creating Payment Requests

Payment Requests支付請(qǐng)求是PKPaymentRequest類的實(shí)例。支付請(qǐng)求包含一系列描述用戶的支付對(duì)象(為哪些東西付款)的概要項(xiàng):可用的運(yùn)送方式的列表,用戶需要提供的運(yùn)送信息的描述,關(guān)于商家和支付處理的信息。

Decide Whether the User Can Make Payments 判決用戶是否有能力支付

在生成一個(gè)支付請(qǐng)求之前,通過(guò)調(diào)用PKPaymentAuthorizationViewController類中的canMakePaymentsUsingNetworks:方法判斷用戶是否能夠使用支持的系統(tǒng)完成支付。使用canMakePayments方法,檢查設(shè)備的硬件和父類控制是否支持Apple Pay。

如果canMakePayments返回NO,表示設(shè)備不支持Apple Pay。因此也不顯示Apple Pay按鈕,轉(zhuǎn)到其他的支付方式。

如果canMakePayments返回YES,但是canMakePaymentsUsingNetworks:返回NO,表示設(shè)備支持Apple Pay,但是用戶沒(méi)有添加任何符合要求的支付系統(tǒng)的卡片。可選擇性地去顯示一個(gè)支付設(shè)置按鈕,提示用戶設(shè)置卡片。一旦用戶點(diǎn)擊了該按鈕,初始化設(shè)置一個(gè)新卡的進(jìn)程(例如:調(diào)用openPaymentSetup方法)。

另外,一旦用戶按下Apple Pay按鈕,必須開(kāi)始支付授權(quán)進(jìn)程。在展示支付請(qǐng)求之前不能要求用戶執(zhí)行其他任何任務(wù)。例如,如果用戶需要輸入折扣碼,必須在按下Apple Pay按鈕之前請(qǐng)求該代碼。

Bridging from Web-Based Interfaces 基于網(wǎng)絡(luò)接口進(jìn)行橋接

如果app使用網(wǎng)絡(luò)接口購(gòu)買物品和服務(wù),必須在處理Apple Pay交易之前從網(wǎng)絡(luò)接口移動(dòng)該請(qǐng)求到本地iOS代碼。列表3-1展示了需要處理web view的請(qǐng)求的步驟。

Listing 3-1Buying items from a web view
    // Called when the web view tries to load "myShoppingApp:buyItem"
    -(void)webView:(nonnull WKWebView *)webView
    decidePolicyForNavigationAction:(nonnull WKNavigationAction *)navigationAction
    decisionHandler:(nonnull void (^)(WKNavigationActionPolicy))decisionHandler {
        
        // Get the URL for the selected link.
        NSURL *URL = navigationAction.request.URL;
        
        // If the scheme and resource specifier match those defined by your app,
        // handle the payment in native iOS code.
        if ([URL.scheme isEqualToString:@"myShoppingApp"] &&
            [URL.resourceSpecifier isEqualToString:@"buyItem"]) {
            
            // Create and present the payment request here.
            
            // The web view ignores the link.
            decisionHandler(WKNavigationActionPolicyCancel);
        }
        
        // Otherwise the web view loads the link.
        decisionHandler(WKNavigationActionPolicyAllow);
    }

Payment Requests Include Currency and Region Information 包括貨幣和地區(qū)信息的支付請(qǐng)求

在支付請(qǐng)求中所有的概要數(shù)值均使用相同的貨幣(指定使用PKPaymentRequest類中的currencyCode屬性),均使用三個(gè)字母的ISO貨幣代碼,例如USD。

支付請(qǐng)求的國(guó)家碼表明在該國(guó)家發(fā)生購(gòu)買操作或者在該國(guó)家購(gòu)買將要被處理。使用兩個(gè)字母的ISO國(guó)家碼,例如US。

在支付請(qǐng)求中設(shè)置的商戶ID(merchant ID)必須與app中的entitlement中的merchant IDs相匹配.

    request.currencyCode = @"USD";
    request.countryCode = @"US";
    request.merchantIdentifier = @"merchant.com.example";

Payment Requests Have a List of Payment Summary Items支付請(qǐng)求有一個(gè)支付概要項(xiàng)的列表

展示在PKPaymentSummaryItem類中的支付概要項(xiàng),描述給用戶的支付請(qǐng)求的不同部分。使用一個(gè)小部分的概要項(xiàng)- 典型地包含總和、任何折扣、運(yùn)費(fèi)、稅金和最終的總和。如果沒(méi)有任何其他額外的費(fèi)用(例如:運(yùn)費(fèi)或稅金),僅僅包含購(gòu)物的總和。在app中提供逐項(xiàng)的消費(fèi)細(xì)節(jié)。

每個(gè)概要項(xiàng)有一個(gè)標(biāo)記和數(shù)值,展示在Listing 3-2。標(biāo)記是用戶可讀的概要項(xiàng)總結(jié)的描述。該數(shù)值與支付數(shù)值是一致的。在支付請(qǐng)求中的所有數(shù)值均使用在支付請(qǐng)求中指定的貨幣。折扣或者優(yōu)惠劵的數(shù)值,則設(shè)置為負(fù)數(shù)。

當(dāng)支付被授權(quán)的時(shí)候,如果不知道某個(gè)實(shí)際的費(fèi)用(例如:打車費(fèi)),生成一個(gè)使用PKPaymentSummaryItemTypePending類型的總和概要項(xiàng)并且值為0.0。該系統(tǒng)然后標(biāo)記該費(fèi)用為未決定的。

Listing 3-2Creating a payment summary item
    // 12.75 subtotal
    NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO];
    self.subtotal = [PKPaymentSummaryItem summaryItemWithLabel:@"Subtotal" amount:subtotalAmount];
    
    // 2.00 discount
    NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithMantissa:200 exponent:-2 isNegative:YES];
    self.discount = [PKPaymentSummaryItem summaryItemWithLabel:@"Discount" amount:discountAmount];

注意:
支付概要項(xiàng)使用NSDecimalNumber類存儲(chǔ)數(shù)量為以10為基的數(shù)。該類的實(shí)例可以通過(guò)明確地指定尾數(shù)和指數(shù)(展示在代碼列表中)或者提供一個(gè)string類型的數(shù)量并指定一個(gè)區(qū)域來(lái)創(chuàng)建。總是使用以10為基的數(shù)來(lái)進(jìn)行金融計(jì)算,例如,確定5%折扣的數(shù)量。

即使IEEE的浮點(diǎn)類型數(shù)據(jù)例如floatDouble顯示起來(lái)非常方便,但不適合于金融計(jì)算。這些數(shù)據(jù)類型使用以2為基的數(shù)字表示出來(lái),這意味著一些小數(shù)數(shù)值不能被精確地表示出來(lái)。例如:0.42很可能接近于0.419999無(wú)限循環(huán)。這類近似值會(huì)造成金融計(jì)算得到錯(cuò)誤的結(jié)果。

在列表中最后的一個(gè)支付概要項(xiàng)是最終的總和。通過(guò)添加所有其他的概要項(xiàng)數(shù)值來(lái)計(jì)算總和數(shù)值。最終總和的顯示不同于其他的概要項(xiàng):使用公司的名稱作為它的label內(nèi)容,使用所有其他的概要項(xiàng)的數(shù)值之和作為它的數(shù)值。使用paymentSummaryItems屬性添加支付概要項(xiàng)到支付請(qǐng)求。

    // 10.75 grand total
    NSDecimalNumber *totalAmount = [NSDecimalNumber zero];
    //  計(jì)算總和
    totalAmount = [totalAmount decimalNumberByAdding:subtotalAmount];
    totalAmount = [totalAmount decimalNumberByAdding:discountAmount];

    self.total = [PKPaymentSummaryItem summaryItemWithLabel:@"My Company Name" amount:totalAmount];
    
    self.summaryItems = @[self.subtotal, self.discount, self.total];
    request.paymentSummaryItems = self.summaryItems;

A Shipping Method Is a Special Payment Summary Item 運(yùn)送方式是一種特殊的支付概要項(xiàng)

為每個(gè)適用的運(yùn)送方式創(chuàng)建一個(gè)PKShippingMethod的實(shí)例。正如其他的支付概要項(xiàng)一樣,運(yùn)送方式有一個(gè)用戶可讀label內(nèi)容(例如“標(biāo)準(zhǔn)的運(yùn)送”或者“次日運(yùn)送”)和一個(gè)運(yùn)費(fèi)的數(shù)值。不像其他的概要項(xiàng),運(yùn)送方式也有detail屬性-例如:“Arrives by July 29”或者“Ships in 24 hours”- 這說(shuō)明了運(yùn)送方式之間的不同。

為了在代理方法中區(qū)分運(yùn)送方式,可使用identifier屬性。該屬性僅僅被用于在自己的app中-框架處理它作為一個(gè)不透明的值,也不顯示在UI界面中。當(dāng)創(chuàng)建每個(gè)運(yùn)送方式時(shí),為它指定一個(gè)獨(dú)一無(wú)二的標(biāo)識(shí)。為了使調(diào)試容易些,使用摘要或者簡(jiǎn)短的string值,例如“discount”,“standard”或者“next-day”。

一些運(yùn)送方式不適用于所有的區(qū)域或者對(duì)不同的地址有不同的運(yùn)費(fèi)。當(dāng)用戶選擇一個(gè)運(yùn)送地址或者方式時(shí)可以更新這些信息,正如Your Delegate Updates Shipping Methods and Costs中描述的。

Indicating Your Support Payment Processing Mechanisms 指定支持的支付處理機(jī)制

通過(guò)用string常量的數(shù)組填充supportNetworks屬性來(lái)指定支持何種支付系統(tǒng)。通過(guò)給merchantCapabilities屬性設(shè)定一個(gè)值來(lái)指定支持何種支付處理協(xié)議。必須支持3DS,支持EMV是可選的。

商家支付能力是位掩碼,聯(lián)合展示如下:

    request.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkDiscover, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa];
    
    // Supports 3DS only
    request.merchantCapabilities = PKMerchantCapability3DS;
    
    // Supports both 3DS and EMV
    request.merchantCapabilities = PKMerchantCapability3DS | PKMerchantCapabilityEMV;

Indicating What Shipping and billing Information Is Needed 指定哪些運(yùn)送和賬單信息是必需的

填充支付授權(quán)視圖控制器的requiredBillingAddressFields和requiredShippingAddressFields屬性來(lái)指定哪些賬單和運(yùn)送信息是必需的。當(dāng)展示該視圖控制器時(shí),它提示用戶提供要求的賬單和運(yùn)送信息。這些區(qū)域的常量按照下面的方式聯(lián)合設(shè)定這些屬性的值:

    request.requiredBillingAddressFields = PKAddressFieldEmail;
    request.requiredBillingAddressFields = PKAddressFieldEmail | PKAddressFieldPostalAddress;

注意:
僅僅請(qǐng)求需要用來(lái)處理支付的賬單和運(yùn)送信息和傳送商品或者服務(wù)。請(qǐng)求不必要的信息會(huì)增加不需要的復(fù)雜性。每個(gè)額外的步驟會(huì)增加用戶簡(jiǎn)單地取消了該交易的可能性。

如果你有最新的賬單和運(yùn)送聯(lián)系方式信息,可以在支付請(qǐng)求時(shí)設(shè)置這些內(nèi)容。Apple Pay會(huì)默認(rèn)使用這些信息;然而,用戶仍然可以選擇其他的聯(lián)系方式信息作為支付授權(quán)處理的一部分。

    PKContact *contact = [[PKContact alloc] init];
    
    //  聯(lián)系人姓名
    NSPersonNameComponents *name = [[NSPersonNameComponents alloc] init];
    name.givenName = @"John";
    name.familyName = @"Appleseed";
    
    contact.name = name;
    
    // 聯(lián)系人地址
    CNMutablePostalAddress *address = [[CNMutablePostalAddress alloc] init];
    address.street = @"1234 Laurel Street";
    address.city = @"Atlanta";
    address.state = @"GA";
    address.postalCode = @"30303";
    
    contact.postalAddress = address;
    
    request.shippingContact = contact;

注意:
地址信息可以來(lái)自在iOS中的廣泛的輸入源。在使用它之前總是驗(yàn)證這些信息。

Storing Additional Information 存儲(chǔ)額外的信息

為了存儲(chǔ)每個(gè)app特定的支付請(qǐng)求的信息,例如一個(gè)購(gòu)物車標(biāo)識(shí),使用applicationData屬性。該屬性被對(duì)待作為一個(gè)系統(tǒng)提供的不透明的值。當(dāng)用戶授權(quán)支付請(qǐng)求之后一大把應(yīng)用數(shù)據(jù)會(huì)顯示在支付密鑰中。

4.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è)方法(通過(guò)調(diào)用完成block)。paymentAuthorizationViewControllerDidFinish:方法是唯一的例外。它沒(méi)有取到完成block,但是它在任何時(shí)候均可被調(diào)用。

完成 block取到一個(gè)論證,該論證可以指定基于可用信息的交易的當(dāng)前授權(quán)狀態(tài)。如果該交易沒(méi)有任何問(wèn)題,傳送該值PKPaymentAuthorizationStatusSuccess;否則,傳送一個(gè)值來(lái)標(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:方法。使用這些方法來(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:方法中提及的運(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í),框架通過(guò)Apple 服務(wù)器和安全元件聯(lián)合生成一個(gè)支付密鑰。可以通過(guò)paymentAuthorizationViewController:didAuthorizePayment:completion:代理方法傳送該支付密鑰給自己的服務(wù)器,與其它需要的信息一起處理購(gòu)買。例如:運(yùn)送地址和購(gòu)物車標(biāo)識(shí)。過(guò)程如下:

  • 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ū)解密支付數(shù)據(jù)。該密鑰僅僅自己和那些已分享商戶標(biāo)識(shí)證書(shū)給他們的人可讀。然后服務(wù)器寫(xiě)下該支付密鑰,并返回它給設(shè)備。
  • 4.框架通過(guò)調(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];
    }

5.Processing Payments

處理支付包括這幾步:

  • 1.發(fā)送支付信息給服務(wù)器,與需要的其它信息一起處理訂單
  • 2.驗(yàn)證支付數(shù)據(jù)的哈希表和簽名
  • 3.解密加密的支付數(shù)據(jù)
  • 4.提交支付數(shù)據(jù)給支付處理網(wǎng)絡(luò)
  • 5.提交訂單給訂單追蹤系統(tǒng)

兩種選擇處理支付:有一個(gè)支付平臺(tái)的優(yōu)勢(shì)去處理支付,或者自己實(shí)施支付進(jìn)程。一個(gè)支付處理平臺(tái)一般處理大部分如上步驟。

讀取、驗(yàn)證和處理支付信息需要對(duì)密碼學(xué)的幾種領(lǐng)域有所理解,例如,計(jì)算一個(gè)SHA-1 哈希,讀取和驗(yàn)證一個(gè)PKCS #7類型的簽名,和執(zhí)行elliptic curve Diffie-Hellman key橢圓曲線密鑰交換。如果沒(méi)有密碼學(xué)的背景,考慮使用一個(gè)支付平臺(tái)來(lái)處理這些操作。更多支持Apple Pay的支付平臺(tái)的信息,可查看developer.apple.com/apple-pay/

用來(lái)處理支付的信息有一個(gè)嵌套的數(shù)據(jù)組織,正如展示在Figure 5-1中支付密鑰是PKPaymentToken類的實(shí)例。它的paymentData屬性的值是一個(gè)JSON字典,它有 個(gè)頭部header包含用于確認(rèn)和加密支付數(shù)據(jù)的信息。加密數(shù)據(jù)包含像數(shù)量、持卡人姓名和其它用于特定的支付處理協(xié)議的的信息。

Figure 5-1Payment data structure


關(guān)于支付數(shù)據(jù)結(jié)構(gòu)格式的詳情,可查看Payment Token Format Reference

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,382評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,038評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,853評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,616評(píng)論 6 408
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,112評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,355評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,869評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,727評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,928評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,165評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,570評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,813評(píng)論 1 282
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,585評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,892評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容