博客原文鏈接: http://zyden.vicp.cc/applepay/

ApplePay在中國上線后,就有許多線上app前后腳加入了對其的接入支持,個人比較喜歡的ENJOY也搶在首批接入了ApplePay應(yīng)用內(nèi)支付。本文將分享作者的接入經(jīng)驗(yàn)。
ApplePay是蘋果公司推出的一種線上/線下的便捷支付方式,根據(jù)TouchId來驗(yàn)證支付卡持卡人身份,ApplePay并不參與資金流動,最終還是讓銀行完成扣款處理,目前據(jù)Apple介紹只配備在iphone6以上和新款的ipad Air2和ipad mini3上,中國地區(qū)最低系統(tǒng)要求為IOS9.2,對于一種新支付體驗(yàn),這門檻的確有點(diǎn)高了。蘋果開發(fā)文檔對ApplePay工作方式的介紹.
線下支付使用NFC POST機(jī)只需要與銀聯(lián)聯(lián)系簽約租用即可,我們來介紹線上支付的流程和app應(yīng)用內(nèi)接入的方法。
目前的接入方式有兩種,一是使用第三方提供商的SDK接入,另一種是讓PassKit Framework直接與銀聯(lián)的接口對接,當(dāng)然網(wǎng)絡(luò)上還有一些自己使用PassKit PaymentRequest自己生成訂單組織信息,直接與Apple對接的Demo,因?yàn)槲覀儾豢赡苊考毅y行跑去簽約,大陸的銀行也不會給我們開放特許,因此這種方式僅僅能用于測試ApplePay的功能和API嘗鮮,并不適用于生產(chǎn)中。
ApplePay官網(wǎng)上有列出中國目前支持并提供SDK的第三方提供商
使用第三方SDK接入的優(yōu)點(diǎn)是開發(fā)成本比較低,并且各自都應(yīng)該有高度定制的Payment Sheet(因訂單信息完整度的不同),可供定制更詳細(xì)的商品信息展示,缺點(diǎn)就是要錢。
若我們選擇后者,相對開發(fā)成本會高,移動端不僅需要對支持性進(jìn)行驗(yàn)證,協(xié)商銀聯(lián)接口數(shù)據(jù)對Payment Sheet的展示關(guān)閉進(jìn)行控制,對各種異常進(jìn)行捕抓和處理,同時后臺需要自己實(shí)現(xiàn)對銀聯(lián)接口的認(rèn)證交互,對交易數(shù)據(jù)的標(biāo)準(zhǔn)封裝,訂單狀態(tài)的處理,支付信息的解密等。
我們選擇使用銀聯(lián)SDK接入這種折中的方式,免費(fèi),工作量可以接受。
使用銀聯(lián)SDK接入的實(shí)現(xiàn)方式如圖所示,主要工作是商戶后臺利用現(xiàn)成的API與銀聯(lián)的交互:
申請MerchantID并更新你的證書:
向蘋果申請我們獨(dú)有的商戶ID,這里我借用Yasin朋友在簡書上分享的詳細(xì)步驟,真的很詳細(xì)易懂。
獲得MerchantId后,更新你的證書,并且于項(xiàng)目->targets->Capabilities中打開ApplePay權(quán)限,選擇正確的MerchantID,讓三個steps成為tick狀態(tài)完全權(quán)限的配置。
ok開始與銀聯(lián)碰頭,于銀聯(lián)商家技術(shù)服務(wù)中心找到ApplePay入口,然后在"技術(shù)文檔"選項(xiàng)卡中可以找到相應(yīng)的SDK和后臺文檔。
這里我使用PHP后臺,在下載的SDK壓縮包里找到了PHP Version SDK,忽略掉這個外殼,我們需要將子文件夾upacp_demo_app部署到我們的服務(wù)器中。
這里我將upacp_demo_app部署到我mac的PHP環(huán)境中,打開upacp_demo_app/demo/api_05_app可以看見各種對訂單處理的接口。
訂單的創(chuàng)建,取消,查詢,退款等,現(xiàn)在我們測試下創(chuàng)建訂單接口
訂單參數(shù)
下圖是創(chuàng)建訂單的請求參數(shù),目前銀聯(lián)創(chuàng)建ApplePay訂單僅支持圖中所示的參數(shù)字段,基本滿足使用但可定制性比較低,最基本的訂單參數(shù)merId商戶號,orderId訂單號,txnTime訂單發(fā)送時間,txnAmt訂單金額,目前測試階段我們可以通過直接調(diào)用此接口post傳參,也可以直接寫死在php文件中
- 注意:這里的merId是銀聯(lián)商戶號,而非蘋果分配的MerchantID。
測試證書
了解到這里后還沒有具備生成訂單的條件,然后我們需要配置配置簽名證書和驗(yàn)簽證書的路徑,這些證書在SDK下載包里面已經(jīng)有附帶,我們只需要在upacp_demo_app/sdk/SDKConfig.php文件中配置好他們的路徑即可
這里需要配置主機(jī)的絕對路徑,不能使用項(xiàng)目相對路徑,完成SDK_SIGN_CERT_PATH,SDK_ENCRYPT_CERT_PATH,SDK_VERIFY_CERT_DIR路徑的配置
成功獲取tn
我們請求下Form_6_2_AppConsume.php接口,即可創(chuàng)建訂單,并且返回對應(yīng)的Trade Name,在App端我們就是拿這個Trade Name來對相應(yīng)的訂單進(jìn)行付款。
拿到訂單tn后,我們已經(jīng)可以使用銀聯(lián)SDK調(diào)起支付,在這之前還要做的就是對設(shè)備和平臺的支持性檢測,通過,present出Payment Sheet即可。
工程配置:
1.添加SDK包:
將下載SDK解壓包中找到applePaySDK文件夾,加入到需要接入ApplePay的項(xiàng)目中。
**這里注意,項(xiàng)目內(nèi)如果同時支持銀聯(lián)普通支付的話,因?yàn)閮蓚€庫引用重復(fù),最好的辦法就是升級銀聯(lián)SDK至最新版本(3.3.3),當(dāng)然可以使用添加Linker Flags的方式解決,或者可以自己剝離掉重復(fù)部分,我是懶人,我選擇升級哈哈。
2.為工程引入必須的framework:
- CFNetwork.framework
- PassKit.framework
- SystemConfiguration/framework
- libUPAPayPlugin.a
- libz.1.2.5.tbd
3.銀聯(lián)SDK使用http請求,在ios9以后需在工程plist文件中添加NSAppTransportSecurity來支持Http繼續(xù)使用。
---注意---
- 因?yàn)殂y聯(lián)SDK內(nèi)部分代碼是由C/C++組織,這里必須添加libz.1.2.5.tbd,并且將引用到UPAPayPlugin.h的源文件的后綴改為.mm
- 同時檢查Target->Build Settings->Search Paths->Library Search Paths中自定義庫libUPAPayPlugin.a的路徑是否正確
4.最后可以開始寫代碼了,在需要調(diào)起ApplePay支付控件的文件中引入頭文件UPAPayPlugin.h(記得文件名后綴需要改成.mm),PassKit/PassKit.h
- (void)verifiesApplePayAbility {
if (![PKPaymentAuthorizationViewController class]) {
//檢查系統(tǒng)版本支持性
PopMessage(@"當(dāng)前系統(tǒng)版本不支持ApplePay,最低支持:iphone6, ios9.0以上");
return;
} else if (![PKPaymentAuthorizationViewController canMakePayments]) {
//檢查設(shè)備支持性
PopMessage(@"當(dāng)前設(shè)備不支持ApplePay,最低支持:iphone6, ios9.0以上");
return;
} else {
//檢查卡片支持性
NSArray *supportedNetwork = @[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkChinaUnionPay, PKPaymentNetworkAmex, PKPaymentNetworkDiscover];
if (![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:supportedNetwork]) {
PopMessage(@"沒有綁定支持的卡片");
return;
}
}
//調(diào)起蘋果支付控件
[self presentPaymentSheet];
}
- (void)presentPaymentSheet {
WaitingMessage(@"正在呼出ApplePay支付控件");
[UPAPayPlugin startPay:yourPayTn mode:self.applePayMode viewController:self delegate:self andAPMechantID:kAppleMechantId];
//-startPay 第一個參數(shù)是后臺向銀聯(lián)請求創(chuàng)建訂單獲得的商品tn
//mode是字符串,00為正式環(huán)境,01為測試環(huán)境
//此處的MechantID傳的是從蘋果那獲取的mechantId
}
如果需要對借記卡/信用卡作限制,在檢查卡片支持性的步驟可以這樣寫:
//檢查卡片支持性
NSArray *supportedNetwork = @[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkChinaUnionPay, PKPaymentNetworkAmex, PKPaymentNetworkDiscover];
PKMerchantCapability capabilities = PKMerchantCapabilityEMV | PKMerchantCapability3DS | PKMerchantCapabilityDebit;
if (![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:supportedNetwork capabilities:capabilities]) {
PopMessage(@"沒有綁定支持的卡片,本支付僅支持使用借記卡支付");
return;
}
最后是銀聯(lián)ApplePay的支付回調(diào):
返回的UPPayResult對象中有各種支付狀態(tài),同時我們還應(yīng)該檢查他的otherInfo屬性,里面包含銀聯(lián)的優(yōu)惠活動信息,如果有則應(yīng)該在支付成功頁中告知客戶。
//實(shí)現(xiàn)UPAPayPluginDelegate
- (void)UPAPayPluginResult:(UPPayResult *)payResult {
//do something
//檢查是否有銀聯(lián)優(yōu)惠信息,告知客戶
}
otherInfo中包含優(yōu)惠信息的格式為:
otherInfo = "currency=元&order_amt=20.00&pay_amt=15.00"
//currency 幣種
//order_amt 訂單金額
//pay_amt 實(shí)付金額
?。?!目前不支持商戶自定義優(yōu)惠活動?。。?br> 博主自己研究了php API很久后無果,咨詢銀聯(lián)客服,然后徹底死心。。
展示
以下左圖是通過銀聯(lián)SDK接入,因?yàn)榭啥ㄖ茀?shù)比較少,Payment Sheet比較簡短,右圖是使用蘋果API直接生成的訂單。
相信美團(tuán)的ApplePay也是跟銀聯(lián)對接的,心血來潮買了個流量順便作下對比
生產(chǎn)環(huán)境:
csr文件
若需要在生產(chǎn)環(huán)境中使用銀聯(lián)SDK接入ApplePay,首先需向銀聯(lián)申請開通ApplePay服務(wù)(聯(lián)系下簽約服務(wù)),并從銀聯(lián)商戶服務(wù)平臺生成ApplePay專用的CSR文件,重新去蘋果開發(fā)者網(wǎng)站簽署證書。
公鑰,私鑰
公鑰在SDK下載包里面有,私鑰在cfca入網(wǎng)通知郵件里面附帶也可以自行下載,一個商戶號唯一一份私鑰和授權(quán)碼,跟銀聯(lián)普通支付私鑰是同一份。
配置
修改生產(chǎn)環(huán)境配置文件中的簽名證書,密碼,后臺url地址
更換正式環(huán)境商戶號(也可以是同一個)
app前端startPay方法的mode參數(shù)改為"00"