iOS 集成apple Pay 接入詳細教程

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

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

準備工作

在接入Apple Pay之前,首先要申請MerchantID及對應證書。

工程設置

bundleID設置

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

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


17if(![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


7//設置幣種、國家碼及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;//設置支持的交易處理協議,3DS必須支持,EMV為可選,目前國內的話還是使用兩者吧

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


//?payRequest.requiredBillingAddressFields?=?PKAddressFieldEmail;

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

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

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

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

送貨信息頁面展示

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


10//設置兩種配送方式

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為該條賬單為最終價格還是估算價格(比如出租車價格預估)

1

2+?(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--十進制數

添加賬單列表:


18NSDecimalNumber?*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;

顯示購物信息并進行支付

1

2

3

4//ApplePay控件

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

view.delegate?=?self;

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

PKPaymentAuthorizationViewControllerDelegate代理

這里還有兩個類要介紹

PKPayment 支付成功信息

1

2

3

4

5PKPaymentToken?*payToken?=?payment.token;

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

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

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

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

PKContact 聯系人信息


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

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

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

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

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

代理說明

送貨地址回調

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

didSelectShippingContact:(PKContact?*)contact

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

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

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

completion(PKPaymentAuthorizationStatusSuccess,?shippingMethods,?summaryItems);

}

送貨方式回調


13-(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);

}

支付卡選擇回調


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

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

completion(summaryItems);

}

送貨地址回調,已棄用

1

2

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

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

}

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


14-(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);

});

}

支付完成回調


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

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

}




#import "ViewController.h"#import@interface ViewController ()@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//1、判斷當前設備是否支持蘋果支付

// 2、判斷是否添加銀行卡

if (![PKPaymentAuthorizationViewController class]) {

//PKPaymentAuthorizationViewController需iOS8.0以上支持

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

return;

}

else if (![PKPaymentAuthorizationViewController canMakePayments]) {

NSLog(@"當前設備不支持applepay");

}

//PKPaymentNetworkChinaUnionPay? 銀聯卡 。PKPaymentNetworkVisa vsa 卡

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

else if (![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[PKPaymentNetworkChinaUnionPay,PKPaymentNetworkVisa]])

{

// 如果沒有添加銀行卡,創建一個跳轉按鈕,跳轉到添加銀行卡的界面

PKPaymentButton *button=[PKPaymentButton buttonWithType:PKPaymentButtonTypeSetUp style:PKPaymentButtonStyleWhiteOutline];

button.center=self.view.center;

[self.view addSubview:button];

[button addTarget:self action:@selector(jumpAddBank) forControlEvents:UIControlEventTouchUpInside];

}

else

{

// 創建一個夠買按鈕,當用戶點擊按鈕時,購買一個商品

PKPaymentButton *button=[PKPaymentButton buttonWithType:PKPaymentButtonTypeBuy style:PKPaymentButtonStyleBlack];

button.center=self.view.center;

[self.view addSubview:button];

[button addTarget:self action:@selector(clickBuy) forControlEvents:UIControlEventTouchUpInside];

}

}

#pragma mark - 點擊去購買

-(void)clickBuy

{

// 1、創建一個支付請求

PKPaymentRequest *request=[[PKPaymentRequest alloc]init];

// 配置支付請求

//1.1 配置商家ID

request.merchantIdentifier=@"merchant.com.cym.weiliaopay";

//1.2 配置國家代碼,以及貨幣代碼

request.countryCode=@"CN";

request.currencyCode=@"CNY";

// 1.3 支付的銀行卡

request.supportedNetworks=@[PKPaymentNetworkChinaUnionPay,PKPaymentNetworkVisa];

// 1.4配置商戶的處理方式//設置支持的交易處理協議,3DS必須支持,EMV為可選,目前國內的話還是使用兩者吧

request.merchantCapabilities=PKMerchantCapability3DS|PKMerchantCapabilityEMV;

// 1.5 配置購買的商品列表

NSDecimalNumber *price=[NSDecimalNumber decimalNumberWithString:@"0.01"];

PKPaymentSummaryItem *item=[PKPaymentSummaryItem summaryItemWithLabel:@"汽車保養" amount:price];

request.paymentSummaryItems=@[item];

//配置請求的附加項

//1、是否顯示發票收貨地址 。顯示哪些選項

//? ? request.requiredBillingAddressFields=PKAddressFieldAll;

//? ? // 2、是否顯示快遞地址,顯示哪些選項

//? ? request.requiredShippingAddressFields=PKAddressFieldAll;

//2、 驗證用戶的支付授權

PKPaymentAuthorizationViewController *PayVC=[[PKPaymentAuthorizationViewController alloc]initWithPaymentRequest:request];

PayVC.delegate=self;

[self presentViewController:PayVC animated:YES completion:nil];

}

#pragma mark? -代理方法

//如果當用戶授權成功,就會調用這個方法

/*

參數一:授權控制器

參數二:支付對象

參數三:系統給定的一個回調代碼塊,我們需要執行這個代碼塊,來告訴系統當前的的支付狀態是否成功

*/

- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller

didAuthorizePayment:(PKPayment *)payment

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

{

NSLog(@"token=%@",payment.token);

// 一般在此外,拿到支付信息,發送給服務器處理,處理完畢之后,服務器返回一個狀態,告訴客戶端,是否支付成功,然后由客戶端進行處理

BOOL isSuccess=YES;

if (isSuccess)

{

completion(PKPaymentAuthorizationStatusSuccess);

}

else

{

completion(PKPaymentAuthorizationStatusFailure);

}

}

#pragma mari 當用戶授權成功,或者取消授權時調用

- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller

{

[self dismissViewControllerAnimated:YES completion:nil];

}

#pragma mark - 添加銀行卡界面

-(void)jumpAddBank

{

// 跳轉到添加銀行卡界面

PKPassLibrary *pl=[[PKPassLibrary alloc]init];

[pl openPaymentSetup];

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

@end

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

推薦閱讀更多精彩內容