在App中接入Apple Pay有兩種方式疼阔,一種是使用CUP SDK等第三方SDK,另一種就是使用iOS的PassKit Framework和銀聯的接口接入况毅。前一種方法导犹,開發(fā)成本低,接入簡單絮吵,但對于Payment Sheet定制化程度不夠弧烤。而第二種開發(fā)成本較高。需要對Payment Sheet的邏輯和異常情況做好相應的UI處理蹬敲。同時在后臺也需要做好支付信息解密暇昂、銀聯接口的交互以及訂單狀態(tài)處理。
這里主要介紹第二種方式伴嗡,第一種方式可以到相關網站查看SDK集成指南急波。
Demo 地址 https://github.com/alanwangke213/ApplePayDemo.git
Apple Pay 授權流程圖
Apple Pay 的集成需要做好版本和機型的適配。Apple Pay 只能運作于iPhone 9.2以上版本的iPhone6/6p及以上型號或版本在2.1以上的Apple Watch的設備上瘪校。
一澄暮、為App設置Apple Pay功能
1.在開發(fā)中賬號中注冊一個merchant ID;
2.創(chuàng)建CSR(CertificateSigningRequest)證書并提交到開發(fā)中賬號中阱扬;
3.在Xcode的Capabilities里使能Apple Pay泣懊,并添加merchant ID
二、Progress flow
1.加載內購商品的支付方式時麻惶,如果當前設備不支持Apple Pay需要隱藏Apple Pay支付按鈕
applePayButton.hidden = ![PKPaymentAuthorizationViewController canMakePayments];
2.如果當前設備未設置/當前設備設置的支付銀行卡無法在商戶提供的支付平臺支付馍刮,則隱藏Apple Pay支付按鈕,可以顯示Set Apple Pay按鈕(可選)窃蹋,提醒用戶進行設置Apple Pay卡啰。
applePayButton.hidden= ![PKPaymentAuthorizationViewControllercanMakePaymentsUsingNetworks:self.supportedPaymentNetworks];
applePaySetBtn.hidden = !applePaySetBtn.hidden;
注:顯示的Apple Pay按鈕和Set Apple Pay按鈕圖片需要按照官方文檔 要求設置
3.導入PassKit框架
Apple Pay 所需的類都包含在PassKit框架中,需要導入該框架
#import <PassKit/PassKit.>
4.創(chuàng)建一個PKPaymentRequest,該request需要包括所有商品和服務費用的警没,例如郵寄費匈辱,稅或者折扣等
// 1. 創(chuàng)建 payment rquest
PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
request.merchantIdentifier = ApplePaySwagMerchantID;
request.supportedNetworks = self.supportedPaymentNetworks;
request.merchantCapabilities = PKMerchantCapabilityCredit|PKMerchantCapabilityDebit|PKMerchantCapability3DS|PKMerchantCapabilityEMV;
request.countryCode = @"CN";
request.currencyCode = @"CNY";
需要根據不同的商品類型來設置requiredShippingAddressFields,如果使電子/虛擬商品(一般為提取/下載鏈接)杀迹,則顯示聯系人郵箱亡脸。如果為實物,則顯示聯系人地址树酪、手機號以及郵箱
// 判斷requiredShippingAddressFields
switch (_swag.swagType) {
case Delivered:
request.requiredShippingAddressFields = PKAddressFieldAll;
break;
case Electronic:
request.requiredShippingAddressFields = PKAddressFieldEmail;
break;
}
根據不同的商品類型浅碾,也判斷是否顯示郵寄方式:
// request 的 shippingMethods數組
NSMutableArray <PKShippingMethod *>*shippingMethods = [NSMutableArray array];
switch (_swag.swagType) {
case Delivered:
for (ShippingMethod *shippingMethod in self.shipMethods) {
PKShippingMethod *method = [[PKShippingMethod alloc] init];
method.label = shippingMethod.title;
method.amount = shippingMethod.price;
method.identifier = shippingMethod.title;
method.detail = shippingMethod.methodDescription;
[shippingMethods addObject:method];
}
_shippingMethods = shippingMethods;
request.shippingMethods = shippingMethods;
break;
case Electronic:
break;
}
圖2A為實體商品,顯示了送貨地址嗅回,郵寄方式以及收貨人聯系方式及穗,圖2B為虛擬物品,只顯示了用戶的郵箱
// 設置paymentSummaryItem數組
_paymentSummaryItems = [self calculateSummaryItemsFromSwag:_swag withShippingMethod:self.shippingMethods.firstObject];
request.paymentSummaryItems = _paymentSummaryItems;
用于顯示商品列表绵载,其中paymentSummaryItem的lastObject為商家Item埂陆,amount為所有商品、tax娃豹、shipping以及discounts的總和焚虱。
Demo中的calculateSummaryItemsFromSwag: withShippingMethod:
方法提供了計算summaryItems數組的邏輯。
5.展示支付授權界面PKAuthorizationViewController懂版,該界面需要將request和需要的提示信息展示給用戶鹃栽,例如shipping或者billing address。
// 授權控制權
PKPaymentAuthorizationViewController *paymentVC = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
paymentVC.delegate = self;
[self presentViewController:paymentVC animated:YES completion:nil];
6.選擇付款卡會push出選擇付款卡控制器躯畴,顯示所有已綁定的銀行卡民鼓。當選擇卡片會調用代理方法
paymentAuthorizationViewController:didSelectPaymentMethod:completion:
該方法薇芝,需要實現completion完成回調,否則會卡在payment processing界面
7.點擊送貨cell會push出送貨地址列表界面丰嘉,選擇送貨地址后會調用paymentAuthorizationViewController:didSelectShippingMethod:completion:
代理方法
該方法夯到,也需要實現completion完成回調,否則會卡在payment processing界面
8.點擊 郵寄方式cell會Push出Shipping method列表
當選擇其它郵寄方式會調用
paymentAuthorizationViewController :didSelectShippingMethod : completion:
代理方法饮亏,在方法中需要做好相關的request.paymentSummaryItems數組耍贾,重新計算列表信息和總價。Demo中的```calculateSummaryItemsFromSwag: withShippingMethod:
9.當用戶輸入TouchID荐开,且授權通過后,Apple Pay 將使用Secure Element安全元件芯片處理銀行卡信息简肴,再有secure enclave產生獨特的授權標志符
10.將授權標志符發(fā)送給蘋果的服務器晃听,再使用MerChante identifier certificate進行二次加密后將token反回給app做其它處理。
11.在```paymentAuthorizationViewController:didAuthorizePayment: completion:```代理方法中可以獲取payment信息着帽,其中包涵了payment token杂伟。
12.獲取到payment token后可以將其發(fā)送給后臺進行其他處理



在授權成功之后將支付相關信息發(fā)送到Apple服務器進行加密,再通過代理方法```paymentAuthorizationViewController:didAuthorizePayment:completion:```獲得到PKPayment中的PKPaymentToken仍翰。
這個是Apple Pay的授權流程的介紹赫粥,后續(xù)的還需要將paymentToken中的paymentData字段數據(加密過的)發(fā)送到自己的服務器。服務器進行解密操作之后提取出需要的信息予借,組織好銀聯接口報文越平,完成交易。
上述的paymentData的內容是Json格式的二進制流灵迫,服務器在收到數據后進行解析秦叛。其中的header.wrappedKey是使用非對稱加密算法加密過的對稱密鑰。使用在蘋果開發(fā)者后臺配置merchantID時的私鑰進行解密瀑粥,會得到對稱密鑰挣跋。使用對稱密鑰對data字段包含的加密數據進行解密,可以得到Apple返回的與支付相關的信息狞换。此信息時加密的避咆,包含了用戶支付的卡號和PIN碼等信息,理論上只有銀聯能解密出真正的內容修噪。商戶看不到具體的信息查库。服務器端將這些信息組織成銀聯需要的報文內容,然后調用銀聯的扣款接口黄琼,完成扣款樊销。
注意:paymentData里面有一個交易金額字段,該字段返回的數據并不是實際支付的金額。在組織銀聯報文的時候一定要注意不能直接使用該字段作為扣款金額的值围苫。
在調用銀聯扣款接口的時候需要注意裤园,在組織好報文并調用銀聯接口發(fā)送給銀聯之后,銀聯的接口返回結果同時有同步和異步兩種方式够吩。如果同步返回成功比然,則表示銀聯成功收到并開始處理該扣款請求丈氓,并不代表扣款成功周循。扣款成功實在異步里返回的万俗。比如湾笛,銀行卡被凍結,PIN錯誤闰歪,余額不足等原因可能造成扣款失敗嚎研。可以在調用銀聯扣款接口后库倘,如果幾秒內未收到異步回調临扮,使用銀聯的交易流水號去輪詢調用銀聯的交易狀態(tài)接口來確保此次交易結果。