Apple Pay接入詳細教程(轉)

Apple Pay運行環境:iPhone6以上設備,操作系統最低iOS9.0以上,部分信息設置需要iOS9.2以上。目前還不支持企業證書添加。

環境搭建好后可以在模擬器上面運行,xcode7.2.1+iPhone6SP9.2系統下,系統會綁定幾種虛擬的銀行卡,和幾個聯系人,方便調試,支付也不會發生真實的付款,真的很方便。

準備工作

在接入Apple Pay之前,首先要申請MerchantID及對應證書。(請移步我寫的申請MerchantID及對應證書詳細圖文教程

工程設置

bundleID設置?

Capability中啟用Apple Pay權限,并選擇merchantID。

之后項目會多一個Applepay的配置文件ApplePayYasin.entitlements

需要引用的庫

Xcode7.0以上不需要再手動添加需要引用的庫了,只需要導入頭文件就可以了

設備Applepay權限檢測

if (![PKPaymentAuthorizationViewController class]) {

//PKPaymentAuthorizationViewController需iOS8.0以上支持

NSLog(@"操作系統不支持ApplePay,請升級至9.0以上版本,且iPhone6以上設備才支持");

return;

}

//檢查當前設備是否可以支付

if?(![PKPaymentAuthorizationViewController?canMakePayments])?{

//支付需iOS9.0以上支持

NSLog(@"設備不支持ApplePay,請升級至9.0以上版本,且iPhone6以上設備才支持");

return;

}

//檢查用戶是否可進行某種卡的支付,是否支持Amex、MasterCard、Visa與銀聯四種卡,根據自己項目的需要進行檢測

NSArray?*supportedNetworks?=?@[PKPaymentNetworkAmex,?PKPaymentNetworkMasterCard,PKPaymentNetworkVisa,PKPaymentNetworkChinaUnionPay];

if?(![PKPaymentAuthorizationViewController?canMakePaymentsUsingNetworks:supportedNetworks])?{

NSLog(@"沒有綁定支付卡");

return;

}

創建支付請求PKPaymentRequest

初始化PKPaymentRequest

這里需要注意RMB的幣種代碼是CNY

//設置幣種、國家碼及merchant標識符等基本信息

PKPaymentRequest?*payRequest?=?[[PKPaymentRequest?alloc]init];

payRequest.countryCode?=?@"CN";//國家代碼

payRequest.currencyCode?=?@"CNY";//RMB的幣種代碼

payRequest.merchantIdentifier?=?@"merchant.ApplePayDemoYasin";//申請的merchantID

payRequest.supportedNetworks?=?supportedNetworks;//用戶可進行支付的銀行卡

payRequest.merchantCapabilities?=?PKMerchantCapability3DS|PKMerchantCapabilityEMV;

設置發票配送信息和貨物配送地址信息,用戶設置后可以通過代理回調代理獲取信息的更新

//?payRequest.requiredBillingAddressFields?=?PKAddressFieldEmail;

//如果需要郵寄賬單可以選擇進行設置,默認PKAddressFieldNone(不郵寄賬單)

//樓主感覺賬單郵寄地址可以事先讓用戶選擇是否需要,否則會增加客戶的輸入麻煩度,體驗不好,

payRequest.requiredShippingAddressFields?=?PKAddressFieldPostalAddress|PKAddressFieldPhone|PKAddressFieldName;

//送貨地址信息,這里設置需要地址和聯系方式和姓名,如果需要進行設置,默認PKAddressFieldNone(沒有送貨地址)


設置貨物的配送方式,不需要不配置

//設置兩種配送方式

PKShippingMethod?*freeShipping?=?[PKShippingMethod?summaryItemWithLabel:@"包郵"amount:[NSDecimalNumber?zero]];

freeShipping.identifier?=?@"freeshipping";

freeShipping.detail?=?@"6-8?天?送達";

PKShippingMethod?*expressShipping?=?[PKShippingMethod?summaryItemWithLabel:@"極速送達"amount:[NSDecimalNumber?decimalNumberWithString:@"10.00"]];

expressShipping.identifier?=?@"expressshipping";

expressShipping.detail?=?@"2-3?小時?送達";

payRequest.shippingMethods?=?@[freeShipping,?expressShipping];



賬單信息的設置

每條賬單的設置

賬單列表使用PKPaymentSummaryItem添加描述和價格,價格使用NSDecimalNumber。

PKPaymentSummaryItem初始化:

label為商品名字或者是描述,amount為商品價格,折扣為負數,type為該條賬單為最終價格還是估算價格(比如出租車價格預估)

+ (instancetype)summaryItemWithLabel:(NSString *)label amount:(NSDecimalNumber *)amount;

+?(instancetype)summaryItemWithLabel:(NSString?*)label?amount:(NSDecimalNumber?*)amount?type:(PKPaymentSummaryItemType)type?NS_AVAILABLE(NA,?9_0);

NSDecimalNumber初始化:

NSDecimalNumber可以使用數字初始化,也可以使用字符串。

使用方法請移步我寫的NSDecimalNumber--十進制數

添加賬單列表:

NSDecimalNumber?*subtotalAmount?=?[NSDecimalNumber?decimalNumberWithMantissa:1275?exponent:-2?isNegative:NO];//12.75

PKPaymentSummaryItem?*subtotal?=?[PKPaymentSummaryItem?summaryItemWithLabel:@"商品價格"amount:subtotalAmount];

NSDecimalNumber?*discountAmount?=?[NSDecimalNumber?decimalNumberWithString:@"-12.74"];//-12.74

PKPaymentSummaryItem?*discount?=?[PKPaymentSummaryItem?summaryItemWithLabel:@"優惠折扣"amount:discountAmount];

NSDecimalNumber?*methodsAmount?=?[NSDecimalNumber?zero];

PKPaymentSummaryItem?*methods?=?[PKPaymentSummaryItem?summaryItemWithLabel:@"包郵"amount:methodsAmount];

NSDecimalNumber?*totalAmount?=?[NSDecimalNumber?zero];

totalAmount?=?[totalAmount?decimalNumberByAdding:subtotalAmount];

totalAmount?=?[totalAmount?decimalNumberByAdding:discountAmount];

totalAmount?=?[totalAmount?decimalNumberByAdding:methodsAmount];

PKPaymentSummaryItem?*total?=?[PKPaymentSummaryItem?summaryItemWithLabel:@"Yasin"amount:totalAmount];//最后這個是支付給誰。哈哈,快支付給我

summaryItems?=?[NSMutableArray?arrayWithArray:@[subtotal,?discount,?methods,?total]];

//summaryItems為賬單列表,類型是?NSMutableArray,這里設置成成員變量,在后續的代理回調中可以進行支付金額的調整。

payRequest.paymentSummaryItems?=?summaryItems;

顯示購物信息并進行支付

//ApplePay控件

PKPaymentAuthorizationViewController?*view?=?[[PKPaymentAuthorizationViewController?alloc]initWithPaymentRequest:payRequest];

view.delegate?=?self;

[self?presentViewController:view?animated:YES?completion:nil];

PKPaymentAuthorizationViewControllerDelegate代理

這里還有兩個類要介紹

PKPayment 支付成功信息

PKPaymentToken *payToken = payment.token;

//支付憑據,發給服務端進行驗證支付是否真實有效

PKContact?*billingContact?=?payment.billingContact;?????//賬單信息

PKContact?*shippingContact?=?payment.shippingContact;???//送貨信息

PKContact?*shippingMethod?=?payment.shippingMethod;?????//送貨方式

PKContact 聯系人信息

NSPersonNameComponents?*name?=?contact.name;//聯系人姓名

CNPostalAddress?*postalAddress?=?contact.postalAddress;//聯系人地址

NSString?*emailAddress?=?contact.emailAddress;//聯系人郵箱

CNPhoneNumber?*phoneNumber?=?contact.phoneNumber;//聯系人手機

NSString?*supplementarySubLocality?=?contact.supplementarySubLocality;//補充信息,地址詳細描述,其他備注等等,iOS9.2及以上才有

代理說明

送貨地址回調

-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController?*)controller

didSelectShippingContact:(PKContact?*)contact

completion:(void?(^)(PKPaymentAuthorizationStatus,?NSArray?*?_Nonnull,?NSArray?*?_Nonnull))completion{

//contact送貨地址信息,PKContact類型

//送貨信息選擇回調,如果需要根據送貨地址調整送貨方式,比如普通地區包郵+極速配送,偏遠地區只有付費普通配送,進行支付金額重新計算,可以實現該代理,返回給系統:shippingMethods配送方式,summaryItems賬單列表,如果不支持該送貨信息返回想要的PKPaymentAuthorizationStatus

completion(PKPaymentAuthorizationStatusSuccess,?shippingMethods,?summaryItems);

}

送貨方式回調

-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController?*)controller

didSelectShippingMethod:(PKShippingMethod?*)shippingMethod

completion:(void?(^)(PKPaymentAuthorizationStatus,?NSArray?*?_Nonnull))completion{

//配送方式回調,如果需要根據不同的送貨方式進行支付金額的調整,比如包郵和付費加速配送,可以實現該代理

PKShippingMethod?*oldShippingMethod?=?[summaryItems?objectAtIndex:2];

PKPaymentSummaryItem?*total?=?[summaryItems?lastObject];

total.amount?=?[total.amount?decimalNumberBySubtracting:oldShippingMethod.amount];

total.amount?=?[total.amount?decimalNumberByAdding:shippingMethod.amount];

[summaryItems?replaceObjectAtIndex:2?withObject:shippingMethod];

[summaryItems?replaceObjectAtIndex:3?withObject:total];

completion(PKPaymentAuthorizationStatusSuccess,?summaryItems);

}

支付卡選擇回調

-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController?*)controller?didSelectPaymentMethod:(PKPaymentMethod?*)paymentMethod?completion:(void?(^)(NSArray?*?_Nonnull))completion{

//支付銀行卡回調,如果需要根據不同的銀行調整付費金額,可以實現該代理

completion(summaryItems);

}

送貨地址回調,已棄用

-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController?*)controller?didSelectShippingAddress:(ABRecordRef)address?completion:(void?(^)(PKPaymentAuthorizationStatus,?NSArray?*?_Nonnull,?NSArray?*?_Nonnull))completion{

//送貨地址回調,已棄用

}

付款成功蘋果服務器返回信息回調,做服務器驗證

-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController?*)controller

didAuthorizePayment:(PKPayment?*)payment

completion:(void?(^)(PKPaymentAuthorizationStatus?status))completion?{

PKPaymentToken?*payToken?=?payment.token;

//支付憑據,發給服務端進行驗證支付是否真實有效

PKContact?*billingContact?=?payment.billingContact;//賬單信息

PKContact?*shippingContact?=?payment.shippingContact;//送貨信息

PKContact?*shippingMethod?=?payment.shippingMethod;//送貨方式

//等待服務器返回結果后再進行系統block調用

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,?(int64_t)(3?*?NSEC_PER_SEC)),?dispatch_get_main_queue(),?^{

//模擬服務器通信

completion(PKPaymentAuthorizationStatusSuccess);

});

}

支付完成回調

1

2

3-(void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController?*)controller{

[controller?dismissViewControllerAnimated:YES?completion:nil];

}

demo的話因為證書問題可能會報錯,不過大家可以看看代碼。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容