ApplePay



Apple Pay 苹果官方文档:Apple Pay Programming Guide

目录

第一节:关于Apple Pay
第二节:配置支付环境
第三节:创建支付请求代码
第四节:授权支付
第五节:支付处理
第六节:服务器接收到Token后的一般处理流程


第一节:关于Apple Pay

Apple Pay是一种移动支付技术,主要用在苹果的移动设备上,能够使用户更加便捷安全的方式在现实生活中购买商品和服务付款。

关于相关的App里的数字商品和服务,请参考:In-App Purchase Programming Guide


第二节:配置支付环境
1.使用xcode创建一个工程

2.注册并配置一个商业标识符

 >添加一个App ID

 >配置Merchant ID

 >为Merchant ID 配置证书,并下载证书安装到钥匙串

  >检测安装到钥匙串中的证书是否有效

 >绑定Merchant ID 到App ID


3.配置Xcode项目

>调整系统最低运行版本(iOS8.0)

>开启Apple Pay 功能


4.具体步骤实现
 4.1.配置支付环境
  > 使用Xcode创建一个工程,并设置好对应的BundleID



>注册并配置一个商业标识符

 1. 添加一个App ID,并且勾选Apple Pay功能






2.配置Merchant ID







3.给Merchant ID 配置证书。并且下载证书安装到钥匙串






4.检测安装到钥匙串的证书是否有效(苹果更新了一些证书,需要下载最新证书,删除过期证书)
 > 出现此证书颁发者无效,或者
 > 根证书/中级证书颁发机构过去
 >重新下载证书下载证书,并且安装,删除过期证书


( 点击登录-> 所有选项->搜索栏:apple w - >点击点击电脑上方的显示->点击显示已过期证书- > 会出现过期证书(左上角有一个红色的叉叉)->右击鼠标(触摸板双指单击)-> 删除即可)





5.绑定Merchant ID 到App ID
















> 配置Xcode项目
 1.调整系统运行最低版本(iOS8.0)





2.开启Apple Pay 功能







第三节:创建请求支付代码

1.判断当前设备是否支持支付

    //1.判断当前设备是否支持苹果支付
    if(![PKPaymentAuthorizationViewController canMakePayments]) {
        NSLog(@"当前设备不支持Apple Pay");
        //判断是否添加了银行卡(PKPaymentNetworkChinaUnionPay)银联卡,(9.2之后才支持)
    } 

2.判断设备的"Wallet"有没有添加支付网络的储蓄卡/信用卡(没有就创建一个按钮,跳转到添加支付网络储蓄卡/银行卡界面)
//判断是否添加了银行卡(PKPaymentNetworkChinaUnionPay)银联卡,(9.2之后才支持)
 if(![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[PKPaymentNetworkChinaUnionPay,PKPaymentNetworkVisa]])    {
        // 创建一个跳转按钮,当用户点击按钮时,跳转到添加银行卡界面
        PKPaymentButton *button = [PKPaymentButton buttonWithType:PKPaymentButtonTypeSetUp style:PKPaymentButtonStyleBlack];
        [button addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
        button.center = self.view.center;
        [self.view addSubview:button];
    } 

3.创建一个支付请求,并且配置相关信息

 //1.创建一个支付请求
    PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
    
    //1.1 配置支付请求
    //1.1.1 配置商家ID
    request.merchantIdentifier = @"merchant.com.applePayBookBuy.demo"; //申请的merchantID
    
    //1.1.2 配置货币代码,以及国家代码
    request.currencyCode = @"CNY";  //RMB的币种代码
    request.countryCode = @"CN";  //国家代码
    
    //1.1.3 配置支持的支付网络
    request.supportedNetworks = @[PKPaymentNetworkVisa,PKPaymentNetworkChinaUnionPay];
    
    //1.1.4 配置商户的处理方式
    request.merchantCapabilities = PKMerchantCapability3DS;设置支持的交易处理协议,3DS必须支持,EMV为可选,目前国内的话还是使用两者吧
    
    //1.1.5 配置购买的商品列表
    NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"6000"];
    PKPaymentSummaryItem *itme1 = [PKPaymentSummaryItem summaryItemWithLabel:@" Swift" amount:number];
    
    // 注意:支付列表最后一个,代表汇总
    NSDecimalNumber *totalAmount = [NSDecimalNumber zero];
    totalAmount = [totalAmount decimalNumberByAdding:number];
    //最后这个是支付给谁。哈哈,快支付给我
    PKPaymentSummaryItem *total = [PKPaymentSummaryItem summaryItemWithLabel:@"YXZ" amount:totalAmount];
    //summaryItems为账单列表,类型是 NSMutableArray,这里设置成成员变量,在后续的代理回调中可以进行支付金额的调整。
    summaryItems = [NSMutableArray arrayWithArray:@[itme1,total]];
    request.paymentSummaryItems = summaryItems;
    
    //1.2 配置请求的附加项
    //1.2.1 是否显示发票地址,显示那些选项
    //如果需要邮寄账单可以选择进行设置,默认PKAddressFieldNone(不邮寄账单)
    //楼主感觉账单邮寄地址可以事先让用户选择是否需要,否则会增加客户的输入麻烦度,体验不好,
    request.requiredBillingAddressFields = PKAddressFieldAll;
    
    //1.2.2 是否显示快递地址,显示那些选项
    //送货地址信息,这里设置显示所有,如果需要进行设置,默认PKAddressFieldNone(没有送货地址)
    request.requiredShippingAddressFields = PKAddressFieldAll;
    
    //1.2.3 配置快递方式
    NSDecimalNumber *shippingNumber = [NSDecimalNumber decimalNumberWithString:@"10.0"];
    PKShippingMethod *method = [PKShippingMethod summaryItemWithLabel:@"顺丰" amount:shippingNumber];
    method.identifier = @"顺丰";
    method.detail = @"24小时内送到";
    //shippingMethods为配送方式列表,类型是 NSMutableArray,这里设置成成员变量,在后续的代理回调中可以进行配送方式的调整。
    shippingMethods = [NSMutableArray arrayWithArray:@[method]];
    request.shippingMethods = shippingMethods;
    
    //1.2.3.2 配置快递类型
    request.shippingType = PKShippingTypeStorePickup;
    
    //1.3 添加一些附加数据
    request.applicationData = [@"buyID=1234" dataUsingEncoding:NSUTF8StringEncoding];
    
 


第四节:授权支付(弹出授权控制器,让用户给支付经行授权)
//用户验证支付授权
    PKPaymentAuthorizationViewController * avc = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
    [self presentViewController:avc animated:YES completion:nil];
    avc.delegate = self; //成为代理,判断用户是否授权


第五节:支付处理(代理方法)


#pragma mark
#pragma mark - PKPaymentAuthorizationViewControllerDelegate
#pragma mark - PKPaymentAuthorizationViewControllerDelegate @required
/**
 *  如果用户授权成功,就会调用这个方法
 *
 *  @param controller 授权窗口对象
 *  @param payment    支付对象
 *  @param 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; //送货信息
    PKShippingMethod *shippingMethod = payment.shippingMethod;  //送货方式
    
    NSLog(@"payToken = %@,billingContact = %@,shippingContact = %@,shippingMethod = %@",payToken,billingContact,shippingContact,shippingMethod);
    //等待服务器返回结果后再进行系统block调用
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //模拟服务器通信
        completion(PKPaymentAuthorizationStatusSuccess);
    });
    
}


/**
 *  当用户授权成功,或者取消授权
 *
 *  @param controller 授权控制器对象
 */
- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
    NSLog(@"授权结束");
    [controller dismissViewControllerAnimated:YES completion:nil];
}


#pragma mark - PKPaymentAuthorizationViewControllerDelegate @optional
/**
 *  配送方式回调
 *
 *  @param controller     授权控制器对象
 *  @param shippingMethod 配送方式对象
 *  @param completion     系统给定的一个回调代码块,我们需要执行这个代码块,来告诉系统当前配送方式
 */
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                   didSelectShippingMethod:(PKShippingMethod *)shippingMethod
                                completion:(void (^)(PKPaymentAuthorizationStatus status, NSArray<PKPaymentSummaryItem *> *summaryItems))completion {
    //配送方式回调,如果需要根据不同的送货方式进行支付金额的调整,比如包邮和付费加速配送,可以实现该代理
    NSString *identifier = shippingMethod.identifier;
    NSString *detail = shippingMethod.detail;
    NSString *label = shippingMethod.label;
    NSDecimalNumber *amount = shippingMethod.amount;
    /*
     PKPaymentSummaryItemTypeFinal,  //支付金额是确定的
     PKPaymentSummaryItemTypePending //支付金额不确定,列如出租车的车费
     */
    PKPaymentSummaryItemType type = shippingMethod.type;
    NSLog(@"identifier = %@,detail = %@,label = %@,amount = %@,type = %ld",identifier,detail,label,amount,type);
    
    PKShippingMethod *oldShippingMethod = [summaryItems objectAtIndex:0];
    PKPaymentSummaryItem *total = [summaryItems lastObject];
    total.amount = [total.amount decimalNumberBySubtracting:oldShippingMethod.amount]; //减去
    total.amount = [total.amount decimalNumberByAdding:shippingMethod.amount];  //加上
    
    [summaryItems replaceObjectAtIndex:0 withObject:shippingMethod];
    [summaryItems replaceObjectAtIndex:1 withObject:total];
    
    completion(PKPaymentAuthorizationStatusSuccess, summaryItems);
}

/**
 *  送货信息回调
 *
 *  @param controller 授权控制器对象
 *  @param contact    送货地址信息对象
 *  @param completion 系统给定的一个回调代码块,我们需要执行这个代码块,来告诉系统当前送货地址信息
 */
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                  didSelectShippingContact:(PKContact *)contact
                                completion:(void (^)(PKPaymentAuthorizationStatus status, NSArray<PKShippingMethod *> *shippingMethods,
                                                     NSArray<PKPaymentSummaryItem *> *summaryItems))completion  {
    //contact送货地址信息,PKContact类型
    NSPersonNameComponents *name = contact.name; //联系人姓名
    CNPostalAddress *postalAddress = contact.postalAddress; //联系人地址
    NSString        *emailAddress = contact.emailAddress; //联系热邮箱
    CNPhoneNumber   *phoneNumber = contact.phoneNumber;  //联系人电话
    NSString        *supplementarySubLocality  = contact.supplementarySubLocality; //补充信息,iOS9.2及以上才有
    NSLog(@"name = %@,postalAddress = %@,emailAddress = %@,phoneNumber = %@,supplementarySubLocality = %@",name,postalAddress,emailAddress,phoneNumber,supplementarySubLocality);
    //送货信息选择回调,如果需要根据送货地址调整送货方式,比如普通地区包邮+极速配送,偏远地区只有付费普通配送,进行支付金额重新计算,可以实现该代理,返回给系统:shippingMethods配送方式,summaryItems账单列表,如果不支持该送货信息返回想要的PKPaymentAuthorizationStatus
    completion(PKPaymentAuthorizationStatusSuccess, shippingMethods, summaryItems);
}


- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                  didSelectShippingAddress:(ABRecordRef)address
                                completion:(void (^)(PKPaymentAuthorizationStatus status, NSArray<PKShippingMethod *> *shippingMethods,
                                                     NSArray<PKPaymentSummaryItem *> *summaryItems))completion {
    //送货地址回调,已弃用
    NSLog(@"苹果已经启用改方法");
    
}



/**
 *  支付银行卡回调
 *
 *  @param controller    授权控制器对象
 *  @param paymentMethod 支付方式对象
 *  @param completion    系统给定的一个回调代码块,我们需要执行这个代码块,来告诉系统当前的银行卡信息
 */
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                    didSelectPaymentMethod:(PKPaymentMethod *)paymentMethod
                                completion:(void (^)(NSArray<PKPaymentSummaryItem *> *summaryItems))completion {
    
    //支付银行卡回调,如果需要根据不同的银行调整付费金额,可以实现该代理
    NSString *displayName = paymentMethod.displayName;
    NSString *network = paymentMethod.network;
    PKPaymentMethodType type = paymentMethod.type;
    NSLog(@"displayName = %@,network = %@,type = %ld",displayName,network,type);
    completion(summaryItems);
    
}



第六节:服务器处理支付结果的一般流程

>验证支付数据的哈希表和签名
>对加密过的支付数据经行解码
>想支付处理系统提交支付数据
>向订单追踪系统提交订单

处理支付请求时。可以利用支付平台处理支付请求,也可以自己实现支付请求处理流程

关于更多Apple Pay 支付平台的信息,请参考:develop.apple.com/apple-pay/



资料附件
Demo源码地址:https://github.com/LiFuxiong/ApplePayDemo.git









  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值