zoukankan      html  css  js  c++  java
  • IOS Apple Pay

    运行环境##

    iphone 6 以及以上,iOS 9.2 以上。目前不支持企业证书添加。
    支持模拟器测试。

    环境配置##

    1、 Xcode 7.2.1 以及以上打开项目,在 Capabilities里将Apple Pay设置为on,如下图,

    2、 图一我们看到了有个 Merchant ID 选项,而且新建时候是没有配置的,那么需要到哪里去配置呢?
    1、访问苹果开发账号,证书中心。
    Identifiers -->Merchant IDs
    输入描述 和 ID,ID 必须以merchant. 开头 

    Continue 到下一步,前方高能警报,嘀嘀嘀~~~~ 坑一出现:报错!!!!!!!

    说明苹果对这个ID 格式是有要求的。多试几次。其实仔细看 图 -3 底下有一行小字,We recommend using a reverse-domain name style string (i.e.,merchant.com.example.merchantname).最好按照官方要求 merchant.com.example.merchantname这个格式来。

     一步一步往下走。
    这时候 会提示你 Identifier:merchant.com.Demo.applepaydemo已经生成。

     点击 Done 

     根据上面的提示,点击Edit,接下去应该是需要建证书了。
    首次添加时候 会询问你是否 在中国使用。选择 YES(截图是默认状态-NO),一直 continue 。

    3、新建证书
    创建 ** Creating a Certificate Signing Request (CSR) CSR 证书,**
    生成CSR证书,这个证书一般是接入第三方银联生成的CSR ,上传到这里就行了

    代码集成##

    这里要说的 重点不在下半部分,而是 Buy with XXPay这个按钮,我们知道苹果是一个有情(偏)怀(执)的处女座公司,对很多的设计或则交互都有自己的一套规则,ApplePay 的响应 按钮也不例外。不要以为随便 弄个 设计个按钮 就能上线了,这个时候 美工和老板说了都不算,要听苹果的ApplePay 设计规范。不然审核也过不了。


    导入头文件,(xcode 7.0 以上已经自动帮我们导入了库,所以我们只需要导入头文件即可)
    #import <PassKit/PassKit.h>

    2、
    PKPaymentAuthorizationViewController Apple pay的展示控件,也是核心类。直接看代码

    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*supportedNetworkCards =@[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa, PKPaymentNetworkChinaUnionPay];
    
    if(![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:supportedNetworks]) {
    
    NSLog(@"没有绑定支付卡");
    
    return;
    
    }
    
    NSLog(@"可以支付,开始建立支付请求");
    - (void)actionApplePay:(UIButton *)button {
    
      if ([PKPaymentAuthorizationViewController canMakePayments]) {
    
        NSLog(@"Woo! Can make payments!");
    
        if ([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[
              PKPaymentNetworkChinaUnionPay,
              PKPaymentNetworkMasterCard,
              PKPaymentNetworkVisa
            ]]) {
    
        } else {
          NSLog(@"用户未添加银行卡");
          return;
        }
    
        PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
    
        PKPaymentSummaryItem *widget1 = [PKPaymentSummaryItem
            summaryItemWithLabel:@"Widget 1"
                          amount:[NSDecimalNumber decimalNumberWithString:@"0.01"]];
    
        PKPaymentSummaryItem *widget2 = [PKPaymentSummaryItem
            summaryItemWithLabel:@"Widget 2"
                          amount:[NSDecimalNumber decimalNumberWithString:@"0.01"]];
    
        PKPaymentSummaryItem *total = [PKPaymentSummaryItem
            summaryItemWithLabel:@"Grand Total"
                          amount:[NSDecimalNumber decimalNumberWithString:@"0.02"]];
    
        request.paymentSummaryItems = @[ widget1, widget2, total ];
        request.countryCode = @"CN";
        request.currencyCode = @"CHW";
    
        //能支付的币种
        request.supportedNetworks = @[
          PKPaymentNetworkChinaUnionPay,
          PKPaymentNetworkMasterCard,
          PKPaymentNetworkVisa
        ];
          
        //Merchant ID
        request.merchantIdentifier = @"merchant.com.Carman.Paydemo";
    
        // 询问你的付款处理器 (PKMerchantCapabilityCredit
        // 信用卡,PKMerchantCapabilityDebit 借记卡)
    
        /*
         PKMerchantCapabilityCredit NS_ENUM_AVAILABLE_IOS(9_0)   = 1UL << 2,   //
         支持信用卡
         PKMerchantCapabilityDebit  NS_ENUM_AVAILABLE_IOS(9_0)   = 1UL << 3    //
         支持借记卡
         */
        request.merchantCapabilities = PKMerchantCapabilityCredit;
        // 添加联系人邮箱 及送货地址信息
        //request.requiredShippingAddressFields = PKAddressFieldAll;
    
        PKPaymentAuthorizationViewController *paymentPane =
            [[PKPaymentAuthorizationViewController alloc]
                initWithPaymentRequest:request];
        paymentPane.delegate = self;
        [self presentViewController:paymentPane animated:TRUE completion:nil];
    
      } else {
        NSLog(@"设备不支持支付");
      }
    }
    1、[PKPaymentAuthorizationViewController canMakePayments] 判断设备支持不支持 ApplePay。中国区 是 iphone 6 及以上,iOS9.2
    2、canMakePaymentsUsingNetworks: 判断 设备上用户有没有添加银行卡,如果没添加,不写这个判断,真机上会crash。
    PKPaymentNetworkChinaUnionPay//中国银联卡
    PKPaymentNetworkMasterCard//Master卡
    PKPaymentNetworkVisa//Visa卡
    3、支付的类目以及总额

    PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
    
        PKPaymentSummaryItem *widget1 = [PKPaymentSummaryItem
            summaryItemWithLabel:@"Widget 1"
                          amount:[NSDecimalNumber decimalNumberWithString:@"0.01"]];
    
        PKPaymentSummaryItem *widget2 = [PKPaymentSummaryItem
            summaryItemWithLabel:@"Widget 2"
                          amount:[NSDecimalNumber decimalNumberWithString:@"0.01"]];
    
        PKPaymentSummaryItem *total = [PKPaymentSummaryItem
            summaryItemWithLabel:@"Grand Total"
                          amount:[NSDecimalNumber decimalNumberWithString:@"0.02"]];
    
        request.paymentSummaryItems = @[ widget1, widget2, total ];
    4、countryCode国家 code ,中国的是 CN ,不太清楚定义的可以查看 countryCode查询网站
    5、currencyCode支付币种 ,人民币 CHW
    6、supportedNetworks能支持的卡种,同 2
    7、merchantIdentifier,终于出现这货了,申请半天的 Merchant ID ,请注意保持一致。
    8、
    merchantCapabilities
    询问你的付款处理器
    PKMerchantCapabilityCredit//支持信用卡
    PKMerchantCapabilityDebit//支持借记卡
    9、requiredShippingAddressFields添加联系人信息
    typedef NS_OPTIONS(NSUInteger, PKAddressField) {
        PKAddressFieldNone                              = 0UL,      // No address fields required.
        PKAddressFieldPostalAddress                     = 1UL << 0, // Full street address including name, street, city, state/province, postal code, country.
        PKAddressFieldPhone                             = 1UL << 1,
        PKAddressFieldEmail                             = 1UL << 2,
        PKAddressFieldName NS_ENUM_AVAILABLE_IOS(8_3)   = 1UL << 3,
        PKAddressFieldAll                               = (PKAddressFieldPostalAddress|PKAddressFieldPhone|PKAddressFieldEmail|PKAddressFieldName)
    } NS_ENUM_AVAILABLE(NA, 8_0);

    10、调起 ** PKPaymentAuthorizationViewController**

     PKPaymentAuthorizationViewController *paymentPane =
            [[PKPaymentAuthorizationViewController alloc]
                initWithPaymentRequest:request];
        paymentPane.delegate = self;
          
        [self presentViewController:paymentPane animated:TRUE completion:nil];

    当然,我们要实现<PKPaymentAuthorizationViewControllerDelegate> 代理

    #pragma mark-- PKPaymentAuthorizationViewControllerDelegate
    - (void)
        paymentAuthorizationViewController:
            (PKPaymentAuthorizationViewController *)controller
                       didAuthorizePayment:(PKPayment *)payment
                                completion:
                                    (void (^)(PKPaymentAuthorizationStatus status))
                                        completion {
      NSLog(@"Payment was authorized: %@", payment);
    
      // do an async call to the server to complete the payment.
      // See PKPayment class reference for object parameters that can be passed
      BOOL asyncSuccessful = FALSE;
    
      if (asyncSuccessful) {
        completion(PKPaymentAuthorizationStatusSuccess);
    
        NSLog(@"支付成功");
    
      } else {
        completion(PKPaymentAuthorizationStatusFailure);
        NSLog(@"支付失败");
      }
    }
    
    - (void)paymentAuthorizationViewControllerDidFinish:
            (PKPaymentAuthorizationViewController *)controller {
      // hide the payment window
      [controller dismissViewControllerAnimated:TRUE completion:nil];
    }
    1、paymentAuthorizationViewController:didAuthorizePayment:
    completion

    支付 状态回调在这里处理,支付成功和失败,订单的地址 以及和 服务器传输数据-token。
    2、paymentAuthorizationViewControllerDidFinish:支付结束,关闭 支付弹框。

    token支付成功之后的回执,需要上传给服务器。
    billingAddress用户账单地址
    billingContact用户账单信息
    shippingAddress送货地址
    shippingContact送货信息
    shippingMethod送货方式
    以上的 信息 可以根据自己的需求 上传到服务器

     
     
     
     
     

    银联Apple Pay控件开发包####

    下载 银联的Apple Pay 控件开发包,里面有非常详细的 介绍,如何接入ApplePay。

    银联支付控件 SDK 模式 Apple Pay 支付的实现方式###

     
    1-2、 商户生成订单,通过商户SERVER端将订单信息发送给银联支付网关;
    3-4、银联支付网关记录订单信息,返回用来标识订单的 TN 号,经由商户 SERVER 返回至给商户 APP;
    5、 商户 APP 调用银联 SDK,将 TN 号传递给银联 SDK
    6、 银联 SDK 向 Apple 公司的 PASSKIT FRAMEWORK 发起支付请求;
    7、 接口返回加密的支付 Token 信息;
    8-9、银联 SDK 将支付 Token 传递给银联支付网关,完成交易认证;
    10-12、银联将支付结果返回给商户 APP,商户 SERVER,商户 APP 负责提示用户交易结果。
     
     
     
    • 添加银联SDK 并加入依赖的库文件

    a、添加 Apple Pay 版本静态库文件
    包含文件:
    UPAPayPlugin.h
    UPAPayPluginDelegate.h
    libUPAPayPlugin.a

    b、添加 CFNetwork.framework 、 libUPAPayPlugin.a 、 PassKit.framework 、 SystemConfiguration.framework 到商户 App 工程中

    c、http 请求设置,设置NSAllowsArbitraryLoads 属性值为 YES

    注意:如果工程的 compile source as 选项的值不是 Objective–C++,则引用此头文件的文件类型都要 改为.mm

    • 接口调用

    a、商户 App 从商户服务器获取 tn,当 tn 不为空时,调用支付接口。

    //当获得的tn不为空时,调用支付接口
    if (tn != nil && tn.length > 0) {
    if([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[PKPaymentNetworkChinaUnionPay]] )
    {
    //调用银联支付控件
    [UPAPayPlugin startPay:tn mode:self.testMode viewController:self delegate:self andAPMechantID:kAppleMechantID]; }
    }

    处理支付结果

    银联手机支付控件结果回调函数有四个支付状态返回值,在 UPPayResult 类中有关于 UPPaymentResultStatus 的详细说明。

    商户 App 通过在工程中添加头文件 “UPAPayPluginDelegate.h”,然后在处理交易结果界面中根据该头文件中定义的回调函数:-(void)UPAPayPluginResult:(UPPayResult *)result 来实现回调方法,从而根据支付结果的不同进行相应的处理。

    -(void)UPAPayPluginResult:(UPPayResult *)result
    {
        if(result.paymentResultStatus == UPPaymentResultStatusSuccess) {
            NSString *otherInfo = result.otherInfo?result.otherInfo:@"";
            NSString *successInfo = [NSString stringWithFormat:@"支付成功\n%@",otherInfo];
            [self showAlertMessage:successInfo];
        }
        else if(result.paymentResultStatus == UPPaymentResultStatusCancel){
    
            [self showAlertMessage:@"支付取消"];
        }
        else if (result.paymentResultStatus == UPPaymentResultStatusFailure) {
            
            NSString *errorInfo = [NSString stringWithFormat:@"%@",result.errorDescription];
            [self showAlertMessage:errorInfo];
        }
        else if (result.paymentResultStatus == UPPaymentResultStatusUnknownCancel)  {
            
            //TODO UPPAymentResultStatusUnknowCancel表示发起支付以后用户取消,导致支付状态不确认,需要查询商户后台确认真实的支付结果
            NSString *errorInfo = [NSString stringWithFormat:@"支付过程中用户取消了,请查询后台确认订单"];
            [self showAlertMessage:errorInfo];
            
        }
    }
  • 相关阅读:
    Unable to satisfy the following requirements解决方式
    零基础学python》(第二版)
    mysql 更新数据表的记录
    mysql创建数据库和删除数据库
    正则表达式
    python lambda函数详细解析(面试经常遇到)
    Linux 命令 统计进程数目
    Python 时间戳与时间字符串互相转
    python 安装配置(windows)
    linux 系统 tar 的用法详解
  • 原文地址:https://www.cnblogs.com/fengfeng159/p/11122765.html
Copyright © 2011-2022 走看看