环境配置:
1 注册一个你的App ID
1.1 在创建App ID 右边点击+,如下图所示:
1.2 填写App Name、Bundle ID,如下图所示:
1.3 勾选Apple Pay
点击下一步完成注册,会看到Apple Pay 为待配置状态:
1.4 创建商家ID
点击Merchant IDs,再点击+:
填写Merchant ID Name和ID,直至点击完成:
1.4.1 点击App IDs中你创建的App ID,点击Edit:
点击Apple Pay的Edit:
勾选刚才创建的商家ID(注:可多选):
点击下一步,直至完成,此时你可以发现Apple Pay变为可用状态了呢:
2 配置商家ID证书
2.1 为Merchant ID 创建证书
点击你的Merchant ID,点击Edit:
点击创建证书:
点击下一步,会提示你是否在中国以外的地区开启Apple Pay,我这里选是:
点击下一步,会让你上传一个请求文件:
2.2 那么这个请求文件如何获取呢?
打开钥匙串,点击左上角钥匙串访问->证书助理->从证书颁发机构请求证书:
我们将证书存放到本地磁盘,会看到在桌面上生产了一个文件(CertificateSigningRequest.certSigningRequest):
2.3 选择上传这个文件:
点击下一步,这时我们的商家ID证书就创建成功了:
2.4 下载安装Merchant ID的证书
3 关于证书失效等问题:
3.1 WWDR已过期
以下是苹果证书的官方网址:
打开网址:
首先删掉本地已过期的WWDR证书,然后下载安装最新的证书(02/07/23):
3.2 安装受信任的根证书(CA - G2)
此时关于Apple Pay环境已经配置完成了,下面就来代码实现它吧!
代码实现:
1 开启Apple Pay功能:
在工程中点击项目的Target,选择Capabilities:
开启Apple Pay,并勾选你创建成功的Merchant ID:
2 模拟一个商品的购买
2.1 在根视图故事板中我们添加一个图片,表示这个商品的图片,并且在底部添加一个购买按钮放置的父视图payView,将payView关联至控制器中,如下所示:
2.2 创建Apple Pay按钮
2.2.1 引入PassKit
1
2
3
4
5
#import "ViewController.h"
//引入PassKit
@import PassKit;
2.2.2 创建按钮
首先判断当前设备是否支持applePay,如果不支持打印错误信息;如果支持但该用户未添加银行卡,我们创建设置按钮,点击可以跳转到添加银行卡信息的Wallet应用中;如果已添加银行卡,创建购买按钮,点击可购买。具体实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//1 判断当前设备是否支持applePay
if ([PKPaymentAuthorizationViewController canMakePayments]==NO) {
NSLog(@"当前设备不支持ApplePay");
}else if (![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[PKPaymentNetworkVisa,PKPaymentNetworkChinaUnionPay]]) {//2 判断是否添加了相应的银行卡 去设置按钮
//不支持 去设置
PKPaymentButton * jump = [PKPaymentButton buttonWithType:PKPaymentButtonTypeSetUp style:PKPaymentButtonStyleWhiteOutline];
[jump addTarget:self action:@selector(jump:) forControlEvents:UIControlEventTouchUpInside];
jump.frame = self.payView.bounds;
[self.payView addSubview:jump];
}else{//3 添加了相应的银行卡 显示购买按钮
//支持 购买
PKPaymentButton * buy = [PKPaymentButton buttonWithType:PKPaymentButtonTypeBuy style:PKPaymentButtonStyleBlack];
[buy addTarget:self action:@selector(buy:) forControlEvents:UIControlEventTouchUpInside];
buy.frame = self.payView.bounds;
[self.payView addSubview:buy];
}
这里我们使用PKPaymentKit提供的专门的按钮:PKPaymentButton ,我们可以通过一下方法来实例化按钮:
1
2
3
4
//按钮外观 去设置字样 白色底黑边样式的
[PKPaymentButton buttonWithType:PKPaymentButtonTypeSetUp style:PKPaymentButtonStyleWhiteOutline];
//按钮外观 支付方式字样 黑底白边样式的
[PKPaymentButton buttonWithType:PKPaymentButtonTypeBuy style:PKPaymentButtonStyleBlack];
运行效果如下:
2.3 跳转到Wallet添加银行卡信息:
1
2
3
4
5
6
7
8
#pragma mark - 跳转
- (void)jump:(id)sender{
PKPassLibrary * pk = [[PKPassLibrary alloc]init];
[pk openPaymentSetup];
}
2.4 购买请求:
2.4.1 需要注意的:
首先要对购买请求做一些配置,如商家ID、国家代码、货币代码等;
其次要创建一个商品(PKPaymentSummaryItem)的数组。注意:数组最后一个Item代表之前所有Item的合计;
还可以配置一些快递信息等;
最后调起验证用户授权的控制器,并设置代理;
具体实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#pragma mark - 购买请求
- (void)buy:(id)sender{
//开始购买
//1 创建一个支付请求
PKPaymentRequest * request = [[PKPaymentRequest alloc]init];
// 配置支付请求
// 配置商家id
request.merchantIdentifier = @"merchant.com.occode.ApplePayTest";
//国家代码
request.countryCode = @"CN";
//货币代码
request.currencyCode = @"CNY";
//支持的支付网络
request.supportedNetworks = @[PKPaymentNetworkVisa,PKPaymentNetworkChinaUnionPay];
//支付的处理方式
request.merchantCapabilities = PKMerchantCapability3DS;
//商品列表
NSDecimalNumber * number = [NSDecimalNumber decimalNumberWithString:@"6000.0"];
PKPaymentSummaryItem * item = [PKPaymentSummaryItem summaryItemWithLabel:@"苹果6S" amount:number];
NSDecimalNumber * number11 = [NSDecimalNumber decimalNumberWithString:@"6800.0"];
PKPaymentSummaryItem * item11 = [PKPaymentSummaryItem summaryItemWithLabel:@"苹果6S+" amount:number11];
NSDecimalNumber * number1 = [NSDecimalNumber decimalNumberWithString:@"12800.0"];
PKPaymentSummaryItem * item1 = [PKPaymentSummaryItem summaryItemWithLabel:@"魔笛" amount:number1];
request.paymentSummaryItems = @[item,item11,item1];
//附加项
//是否显示发票收货地址 显示哪些选项
request.requiredBillingAddressFields = PKAddressFieldAll;
//是否显示快递地址
request.requiredShippingAddressFields = PKAddressFieldAll;
//配置快递方式
NSDecimalNumber * number2 = [NSDecimalNumber decimalNumberWithString:@"12.0"];
PKShippingMethod * m1 = [PKShippingMethod summaryItemWithLabel:@"顺丰快递" amount:number2];
m1.identifier = @"Shunfeng";
m1.detail = @"24小时送货上门";
NSDecimalNumber * number3 = [NSDecimalNumber decimalNumberWithString:@"10.0"];
PKShippingMethod * m2 = [PKShippingMethod summaryItemWithLabel:@"韵达快递" amount:number3];
m2.identifier = @"Yunda";
m2.detail = @"送货上门";
request.shippingMethods = @[m1,m2];
//配置快递类型
request.shippingType = PKShippingTypeStorePickup;
//附加信息
request.applicationData = [@"buyId=12345" dataUsingEncoding:NSUTF8StringEncoding];
//2 验证用户的支付授权
PKPaymentAuthorizationViewController * avc = [[PKPaymentAuthorizationViewController alloc]initWithPaymentRequest:request];
avc.delegate = self;
[self presentViewController:avc animated:true completion:nil];
}
2.5 实现代理:
我们的订单信息通常都是由我们自己的服务器处理并返回是否支付成功的反馈结果,这里由于我们没有做服务器,所以这里我们假设服务器返回成功,于是客户端完成成功的回调,当用户授权成功获取取消授权,都会触发代理方法DidFinish,具体实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#pragma mark - PKPaymentAuthorizationViewControllerDelegate
/**
* 用户授权成功 就会调用这个方法
*
* @param controller 授权控制器
* @param payment 支付对象
* @param completion 系统给定的回调代码块 需要执行它 来告诉 系统当前的支付状态是否支付成功
*/
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didAuthorizePayment:(PKPayment *)payment completion:(void (^)(PKPaymentAuthorizationStatus))completion{
NSLog(@"TOKEN transactionIdentifier: %@",payment.token.transactionIdentifier);
NSLog(@"TOKEN PayData :%@",payment.token.paymentData);
//拿到支付信息 给服务器处理 服务器会返回一个状态 告诉客户端 是否支付成功 有客户端进行处理
BOOL isSuccess = YES;
if (isSuccess) {
completion(PKPaymentAuthorizationStatusSuccess);
}else{
completion(PKPaymentAuthorizationStatusFailure);
}
}
//当用户授权成功 或者 取消授权
- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller{
NSLog(@"授权结束");
[controller dismissViewControllerAnimated:true completion:nil];
}
2.6 运行效果如下:
点击购买按钮
点击输入手机密码以支付:
此时支付完成了!
Demo地址:
github:
https://github.com/ly918/Demos