原創(chuàng)|行業(yè)資訊|編輯:黃竹雯|2016-02-18 14:12:38.000|閱讀 477 次
概述:Apple Pay,是蘋(píng)果公司在2014蘋(píng)果秋季新品發(fā)布會(huì)上發(fā)布的一種基于NFC的手機(jī)支付功能,于2014年10月20日在美國(guó)正式上線(xiàn)。2016年2月18日凌晨5:00, Apple Pay 業(yè)務(wù)在中國(guó)上線(xiàn)。Apple Pay再次進(jìn)入關(guān)心移動(dòng)支付的公眾視野,中國(guó)的移動(dòng)支付市場(chǎng)最新格局備受矚目。小編特別整理翻譯了蘋(píng)果官方文檔資料,為大家?guī)?lái)Apple Pay的編程指南。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
Apple Pay是一種移動(dòng)支付技術(shù),它能夠讓用戶(hù)以一種便捷安全的方式為現(xiàn)實(shí)世界中購(gòu)買(mǎi)的商品和服務(wù)付款。
關(guān)于相關(guān)App里的數(shù)字商品和服務(wù),請(qǐng)參考。
使用Apple Pay的APP需要一項(xiàng)特殊的權(quán)限,該權(quán)限可以在開(kāi)發(fā)者會(huì)員中心和Xcode中開(kāi)啟。你同樣需要注冊(cè)一個(gè)商業(yè)標(biāo)示,并設(shè)置密鑰;在給服務(wù)器發(fā)送支付信息時(shí),這些密匙可以確保數(shù)據(jù)的安全傳輸。
原文內(nèi)容:配置支付環(huán)境()
支付請(qǐng)求就是描述當(dāng)前進(jìn)行的購(gòu)買(mǎi)操作,包括支付金額。你把支付請(qǐng)求發(fā)送給一個(gè)授權(quán)支付的視圖控制器;該試圖控制器呈現(xiàn)相關(guān)請(qǐng)求內(nèi)容,并提示用戶(hù)需要輸入的信息,例如配送地址或者賬單地址。接著,當(dāng)用戶(hù)與視圖控制器交互,并提供新的支付信息時(shí),APP會(huì)調(diào)用支付請(qǐng)求的委托,繼續(xù)執(zhí)行支付流程。
原文內(nèi)容:創(chuàng)建支付請(qǐng)求(),授權(quán)支付()
Apple Pay會(huì)對(duì)支付信息進(jìn)行加密處理,以防止未獲授權(quán)的第三方獲取用戶(hù)的支付信息。你可以在自己的服務(wù)器上完成整個(gè)支付流程,也可以在自己的服務(wù)器上使用第三方支付平臺(tái)來(lái)解碼支付信息,并完成支付處理。
原文內(nèi)容:處理支付請(qǐng)求()
一個(gè)商用ID標(biāo)識(shí)可以幫助Apple Pay識(shí)別你,讓你能夠接受付款。在支付信息加密的過(guò)程中,把公匙和證書(shū)與ID標(biāo)示關(guān)聯(lián)起來(lái)進(jìn)行加密是必不可少的一步。在A(yíng)PP使用Apple Pay之前,你首先得注冊(cè)一個(gè)商用ID,并配置它的相關(guān)證書(shū)。
如果KeyChain Access中顯示了警示信息,表示未知授權(quán)簽發(fā)證書(shū)或者無(wú)效證書(shū)發(fā)行人,那么要確保你已經(jīng)在鑰匙鏈中安裝了WWDR中級(jí)證書(shū)-G2和Apple Root CA-G2。你可以在這個(gè)地方下載這些東西:。
為了在Xcode中啟用Apple Pay,打開(kāi)APP工程文件的Capabilities面板。在A(yíng)pple Pay這行將開(kāi)關(guān)按鈕設(shè)置為"ON",接著選擇APP需要使用的ID標(biāo)示。
注意:在A(yíng)PP排錯(cuò)時(shí),偶爾手動(dòng)啟用Apple Pay很管用。請(qǐng)按照以下步驟手動(dòng)啟用Apple Pay:
支付請(qǐng)求是類(lèi)的實(shí)例,它的組成部分包括一個(gè)用來(lái)表示將要購(gòu)買(mǎi)的項(xiàng)目的摘要,一個(gè)可用的配送方式列表,一個(gè)表示用戶(hù)需要提供的配送信息的描述,以及一些商家和支付平臺(tái)的信息。
在創(chuàng)建支付請(qǐng)求之前,要首先通過(guò)調(diào)用PKPaymentAuthorizationViewController 類(lèi)里的canMakePaymentsUsingNetworks:方法來(lái)判斷用戶(hù)是否能夠使用你提供的支付網(wǎng)絡(luò)進(jìn)行支付。如果要判斷用戶(hù)的硬件是否支持Apple Pay或者是否因?yàn)榧议L(zhǎng)控制而不能支付,請(qǐng)使用canMakePayments 方法。
如果用戶(hù)不能進(jìn)行支付,那就不要顯示支付按鈕,相應(yīng)的應(yīng)該退回到其它支付方式。
所有的匯總金額應(yīng)該使用同一種貨幣,貨幣的信息可使用PKPaymentRequest類(lèi)的currencyCode屬性進(jìn)行指定。像"USD"這樣,使用3個(gè)字符格式的ISO貨幣編碼。
一個(gè)支付請(qǐng)求里的國(guó)家代碼表示了這次購(gòu)買(mǎi)發(fā)生的國(guó)家或者將要在這個(gè)國(guó)家處理這次支付。像"US"這樣,使用2個(gè)字符格式的ISO國(guó)家編碼。
在支付請(qǐng)求里指定的商用ID必須匹配應(yīng)用中指定的商用ID列表之一。
request.currencyCode = @"USD"; request.countryCode = @"US"; request.merchantIdentifier = @"merchant.com.example";
支付摘要項(xiàng)目,屬于類(lèi),描述了支付請(qǐng)求的不同部分。在一個(gè)支付請(qǐng)求里不要使用太多的摘要項(xiàng)目---典型的項(xiàng)目像比如小計(jì)金額、折扣信息、配送信息、含稅信息以及總計(jì)金額等。如果你想要提供更詳細(xì)的支付項(xiàng)目列表,可以在你應(yīng)用的其它地方提供。
每一個(gè)摘要項(xiàng)目會(huì)有一個(gè)標(biāo)簽和數(shù)額,就像在代碼列表3-1中顯示的那樣。標(biāo)簽文本是一個(gè)用戶(hù)可閱讀的摘要項(xiàng)目描述信息,數(shù)額是相對(duì)應(yīng)的支付數(shù)額。在一個(gè)支付請(qǐng)求中所有的數(shù)額都要使用在這個(gè)請(qǐng)求中指定的貨幣。對(duì)于折扣或優(yōu)惠券,則需要把數(shù)額設(shè)成負(fù)數(shù)。
創(chuàng)建支付項(xiàng)目
// 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];
注意:這里使用類(lèi)來(lái)存儲(chǔ)摘要項(xiàng)目的數(shù)額,它是一個(gè)以10為底數(shù)的數(shù)值。可以使用指定尾數(shù)和指數(shù)的方式(像代碼中那樣)來(lái)創(chuàng)建這個(gè)類(lèi)的實(shí)例,也可以通過(guò)指定字符串和locale來(lái)實(shí)例化,字符串指定了相應(yīng)的數(shù)值。這里總是使用以10為底數(shù)的數(shù)值來(lái)做財(cái)務(wù)計(jì)算--例如當(dāng)需要計(jì)算5%折扣掉的金額時(shí)。
盡管有時(shí)使用其它的計(jì)數(shù)方法更方便,但是像float或者Double這樣的IEEE浮點(diǎn)數(shù)類(lèi)型是不適合作財(cái)務(wù)計(jì)算的,這些數(shù)據(jù)類(lèi)型使用的是以2為底數(shù)的數(shù)值表示方法,這就表示有一些十進(jìn)制數(shù)值不能準(zhǔn)確得被表示--例如0.42必須以0.41999這樣的循環(huán)小數(shù)來(lái)近似表示,而這種近似表示常常會(huì)造成財(cái)務(wù)計(jì)算的錯(cuò)誤結(jié)果。
在這個(gè)摘要項(xiàng)目列表中的最后一個(gè)是總計(jì)金額。這個(gè)金額是通過(guò)把所有其它金額相加而得到。總計(jì)的顯示方法和其它的摘要項(xiàng)目不同:應(yīng)該使用你公司的名稱(chēng)做為其標(biāo)簽,使用所有其它項(xiàng)目的金額總和做為金額。使用屬性將這些摘要項(xiàng)目加入支付請(qǐng)求。
// 10.75 grand total NSDecimalNumber *totalAmount = [NSDecimalNumber zero]; 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;
對(duì)于每一種可用的配送方式創(chuàng)建一個(gè)的實(shí)例。就像其它支付摘要項(xiàng)目一樣,配送方式包含用戶(hù)易于辨別的標(biāo)簽,比如"標(biāo)準(zhǔn)配送"或者"第二天配送",還有一個(gè)金額來(lái)表示配送費(fèi)用。與其它摘要項(xiàng)目不同的是,配送方式還有一個(gè)屬性--像"7月29日到達(dá)"或者"24小時(shí)之內(nèi)配送"等--可以用來(lái)解釋各個(gè)配送方式之間的區(qū)別。
使用屬性來(lái)在代理方法中區(qū)分不同的配送方式,這個(gè)屬性只會(huì)在你的應(yīng)用內(nèi)使用--框架看不到這個(gè)屬性,并且它也不會(huì)出現(xiàn)在UI中。在創(chuàng)建配送方式時(shí)為其分配一個(gè)獨(dú)一無(wú)二的標(biāo)識(shí)符。為了方便調(diào)試,可使用文本縮寫(xiě),比如"discount", "standard", 或者 "next-day".
有一些配送方式在某些地區(qū)可能不適用,或者有不同的價(jià)格,你可以在用戶(hù)選擇配送地址或配送方式的代理方法時(shí)更新這些信息,就像描述的一樣。
通過(guò)在屬性中填入字符串常量數(shù)組來(lái)指定你支持的支付網(wǎng)絡(luò)。通過(guò)指定屬性來(lái)指定你支持的支付處理標(biāo)準(zhǔn),3DS支付方式是必須支持的,EMV方式是可選的。
商家支持的支付處理標(biāo)準(zhǔn)使用標(biāo)識(shí)位來(lái)進(jìn)行組合,像下面這樣:
request.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa]; // Supports 3DS only request.merchantCapabilities = PKMerchantCapability3DS; // Supports both 3DS and EMV request.merchantCapabilities = PKMerchantCapability3DS | PKMerchantCapabilityEMV;
通過(guò)填充和屬性來(lái)指定所需賬單信息和配送地址信息。當(dāng)你顯示一個(gè)視圖控制器時(shí),它會(huì)提示用戶(hù)輸入所需內(nèi)容。這些字段常量可以像下面這樣進(jìn)行組合來(lái)設(shè)置這些屬性:
request.requiredBillingAddressFields = PKAddressFieldEmail; request.requiredBillingAddressFields = PKAddressFieldEmail | PKAddressFieldPostalAddress;
如果你已經(jīng)有了用戶(hù)的賬單和配送信息,可以直接在支付請(qǐng)求中使用它們。但是盡管Apple Pay默認(rèn)使用了這些信息,用戶(hù)仍然可以在授權(quán)支付的過(guò)程中修改這些信息。
ABRecordRef record = ABPersonCreate(); CFErrorRef error; BOOL success; success = ABRecordSetValue(record, kABPersonFirstNameProperty, @"John", &error); if (!success) { /* ... handle error ... */ } success = ABRecordSetValue(record, kABPersonLastNameProperty, @"Appleseed", &error); if (!success) { /* ... handle error ... */ } ABMultiValueRef shippingAddress = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType); NSDictionary *addressDictionary = @{ (NSString *) kABPersonAddressStreetKey: @"1234 Laurel Street", (NSString *) kABPersonAddressCityKey: @"Atlanta", (NSString *) kABPersonAddressStateKey: @"GA", (NSString *) kABPersonAddressZIPKey: @"30303" }; ABMultiValueAddValueAndLabel(shippingAddress, (__bridge CFDictionaryRef) addressDictionary, kABOtherLabel, nil); success = ABRecordSetValue(record, kABPersonAddressProperty, shippingAddress, &error); if (!success) { /* ... handle error ... */ } request.shippingAddress = record; CFRelease(shippingAddress); CFRelease(record);
使用屬性來(lái)存儲(chǔ)一些在你的應(yīng)用中關(guān)于這次支付請(qǐng)求的唯一標(biāo)識(shí)信息,比如一個(gè)購(gòu)物車(chē)的標(biāo)識(shí)符。在用戶(hù)授權(quán)支付之后,這個(gè)屬性的哈希值會(huì)出現(xiàn)在這次支付的token中。
支付授權(quán)過(guò)程是由支付授權(quán)view controller和它的代理協(xié)作完成的。支付授權(quán)view controller做了兩件事情:它讓用戶(hù)選擇支付請(qǐng)求所必需的賬單和配送信息,還有讓用戶(hù)最終授權(quán)同意這次支付。當(dāng)用戶(hù)和view controller交互時(shí),代理方法就會(huì)被調(diào)用,這樣你的應(yīng)用就可以不斷地更新顯示的信息--例如在配送地址更改后更新配送費(fèi)用。用戶(hù)最終授權(quán)支付請(qǐng)求之后代理方法同樣也會(huì)被調(diào)用。
注意:在實(shí)現(xiàn)這些方法時(shí)注意,這些方法可能會(huì)被多次調(diào)用,而它們被調(diào)用的順序取決于用戶(hù)的行為的順序。
在所有這個(gè)授權(quán)過(guò)程中被調(diào)用的代理方法中,都會(huì)有一個(gè)completion block被做為參數(shù)之一傳入,支付授權(quán)view controller會(huì)在一個(gè)代理方法執(zhí)行完畢(通過(guò)調(diào)用completion塊)后再調(diào)用另一個(gè)代理方法。唯一的例外是:方法:它不包含completion block,所以它可以在任何時(shí)候被調(diào)用。
這個(gè)completion block有一個(gè)傳入?yún)?shù),基于現(xiàn)有的可用信息,你可以通過(guò)這個(gè)參數(shù)并指定這次交易的狀態(tài)。如果這次交易沒(méi)有任何問(wèn)題,傳入PKPaymentAuthorizationStatusSuccess,否則,你要傳入一個(gè)識(shí)別問(wèn)題的值。
通過(guò)在類(lèi)的構(gòu)造方法中傳入一個(gè)支付請(qǐng)求來(lái)對(duì)它進(jìn)行實(shí)例化,然后給這個(gè)視圖控制器設(shè)置一個(gè)代理,就可以把它展示給用戶(hù)了。
PKPaymentAuthorizationViewController *viewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request]; if (!viewController) { /* ... Handle error ... */ } viewController.delegate = self; [self presentViewController:viewController animated:YES completion:nil];
當(dāng)用戶(hù)與這個(gè)視圖控制器進(jìn)行交互時(shí),它的代理方法會(huì)被調(diào)用。
當(dāng)用戶(hù)提供配送信息之后,授權(quán)view controller 會(huì)調(diào)用和 這兩個(gè)代理方法。在這兩個(gè)方法中根據(jù)最新信息來(lái)更新支付請(qǐng)求。
- (void) paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingAddress:(ABRecordRef)address completion:(void (^)(PKPaymentAuthorizationStatus, NSArray *, NSArray *))completion { self.selectedShippingAddress = address; [self updateShippingCost]; NSArray *shippingMethods = [self shippingMethodsForAddress:address]; 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); }
當(dāng)用戶(hù)最終授權(quán)了一個(gè)支付請(qǐng)求,框架會(huì)通過(guò)與蘋(píng)果服務(wù)器和嵌入在設(shè)備中的一個(gè)安全模塊進(jìn)行通信,生成一個(gè)支付token。然后你在方法中將這個(gè)token和其它一些你需要用來(lái)處理這次購(gòu)買(mǎi)的信息--例如配送地址和購(gòu)物車(chē)標(biāo)識(shí)--發(fā)送給你的服務(wù)器。這個(gè)過(guò)程是這樣的:
至于你的服務(wù)器采取的行為要取決于你是自己處理這次支付或者你是和其它支付平臺(tái)合作來(lái)進(jìn)行支付處理。不管怎樣,你的服務(wù)器處理這個(gè)訂單然后傳送一個(gè)狀態(tài)信息給設(shè)備,代理方法會(huì)把這個(gè)狀態(tài)信息傳送給completion塊,像在“”中討論過(guò)的。
- (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); }
在框架顯示交易狀態(tài)之后,授權(quán)View Controller會(huì)調(diào)用代理的方法。在這個(gè)方法的實(shí)現(xiàn)中,先釋放授權(quán)頁(yè)面控制器再顯示你自己的訂單確認(rèn)頁(yè)面。
- (void) paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller { [controller dismissViewControllerAnimated:YES completion:nil]; }
處理一個(gè)支付請(qǐng)求涉及以下幾個(gè)步驟:
處理支付請(qǐng)求時(shí),你有兩個(gè)選擇;你既可以利用支付平臺(tái)處理支付請(qǐng)求,也可以自己實(shí)現(xiàn)支付請(qǐng)求處理流程。一個(gè)常用的支付平臺(tái)可以完成上述大部分操作。
讀取,驗(yàn)證,以及處理支付信息需要有一定的相關(guān)密碼知識(shí),例如計(jì)算SHA-1哈希表,讀取和驗(yàn)證PKCS#7簽名,執(zhí)行Elliptic Curve Diffie-Hellman密匙交換。如果沒(méi)有一定的密碼學(xué)背景,你可以考慮使用第三方支付平臺(tái)來(lái)完成這些操作。
關(guān)于支持Apple Pay支付平臺(tái)的更多信息,請(qǐng)參考
處理支付請(qǐng)求所用的信息擁有一種嵌套式的數(shù)據(jù)結(jié)構(gòu),如下圖。支付令牌是PKPaymentToken類(lèi)的實(shí)例。其paymentData屬性值是一個(gè)JSON詞典,它的頭文件信息可以用來(lái)驗(yàn)證和加密支付數(shù)據(jù)。加密過(guò)的數(shù)據(jù)信息包括支付金額、持卡人姓名,以及一些其他指定的支付處理協(xié)議。
支付數(shù)據(jù)結(jié)構(gòu)
關(guān)于支付數(shù)據(jù)結(jié)構(gòu)格式的詳細(xì)信息,請(qǐng)參考:.
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都控件網(wǎng)