Apple Pay

1,167 阅读4分钟

1.介绍:

  • Apple Pay并不是独立的第三方支付服务,相比较支付宝和微信支付,他没有自己的账户,也不参与资金的流动, Apple Pay只是将原有的实体银行卡变成手机上“虚拟的银行卡”。Apple Pay依赖iPhone系统底层的整合,在便捷程度上,非第三方支付能比。和第三方的支付对比:一个是系统级的,一个是应用级的。

  • iOS 8 中第一次被介绍,支持到iOS9以上的系统

2配置证书:

  • 需要有一个具有ApplePay服务的APPid.以及真机测试的证书和描述文件

  • 创建或者编辑appID的支持Apple pay

    ApplePay1

    ApplePay2

  • 编辑Merchant ID

    ApplePay3
    ApplePay4

    ApplePay5

  • 从钥匙串中请求证书

  • 在Xcode 中设置允许Apple pay

3. 在界面中设置pay button

  • PKPaymentButton --我们需要添加一个按钮,进行支付代码的实现
  • 切图可以拉伸,但是不可以变窄!
  • 这个按钮有三个样式:White; WhiteOutLine; Black
  • 同样具有三个不同类型:Plain; Buy;SetUp

4.上代码

  • 创建button

    #import <PassKit/PassKit.h>
    //    Type : 类型
    //    PKPaymentButtonTypePlain
    //    PKPaymentButtonTypeBuy
    //    PKPaymentButtonTypeSetUp
        
    //    style : 样式
    //    PKPaymentButtonStyleWhite
    //    PKPaymentButtonStyleWhiteOutline
    //    PKPaymentButtonStyleBlack
        //以上的样式和类型,大家可以更换下,运行后可以直接查看到效果。在这里就不在解释。
        PKPaymentButton * payButton = [PKPaymentButton buttonWithType:PKPaymentButtonTypePlain style:PKPaymentButtonStyleWhiteOutline];
        payButton.center = self.view.center;
        [payButton addTarget:self action:@selector(payAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:payButton];
    
  • 开始支付

  • 系统提供了API来判断当前设备是否支持Apple Pay支付的功能。

    if([PKPaymentAuthorizationViewController canMakePayments]){
        //设备支持支付
        //PKPayment类来创建支付请求
        PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
        //国家 //HK 香港   CN :  中国大陆
        request.countryCode = @"CN";
        //人民币 // HKD  港币  CNY : 人民币    USD : 美元
        request.currencyCode = @"CNY";// 其他国家以及币种的缩写自行百度
        ///由商家支持的支付网络 所支持的卡类型
        //此属性限制支付卡,可以支付。
        //        PKPaymentNetworkAmex : 美国运通
        //        PKPaymentNetworkChinaUnionPay : 中国银联
        //        PKPaymentNetworkVisa  : Visa卡
        //        PKPaymentNetworkMasterCard : 万事达信用卡
        //        PKPaymentNetworkDiscover
        //        PKPaymentNetworkInterac
        //        PKPaymentNetworkPrivateLabel
        //        PKEncryptionSchemeECC_V2
        request.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkChinaUnionPay, PKPaymentNetworkDiscover, PKPaymentNetworkInterac, PKPaymentNetworkMasterCard, PKPaymentNetworkPrivateLabel, PKPaymentNetworkVisa, PKEncryptionSchemeECC_V2];
        
        //        PKMerchantCapability3DS // 美国的一个卡 必须支持
        //        PKMerchantCapabilityEMV // 欧洲的卡
        //        PKMerchantCapabilityCredit //信用卡
        //        PKMerchantCapabilityDebit //借记卡
        
        //商家的支付处理能力
        //PKMerchantCapabilityEMV : 他的旗下有三大银行 : 中国银联 Visa卡 万事达信用卡
        //也就是说merchantCapabilities指的支付的银行卡的范围。
        request.merchantCapabilities =   PKMerchantCapabilityDebit | PKMerchantCapabilityCredit | PKMerchantCapabilityEMV;
        
        //merchantIdentifier 要和你在开发者中心生成的id保持一致
        request.merchantIdentifier = @"merchant.com.lanou3g.hanshanhuApplePayTest";
        
        //需要的配送信息和账单信息
        request.requiredBillingAddressFields = PKAddressFieldAll;
        request.requiredShippingAddressFields = PKAddressFieldAll;
        //运输方式
        NSDecimalNumber * shippingPrice = [NSDecimalNumber decimalNumberWithString:@"11.0"];
        PKShippingMethod *method = [PKShippingMethod summaryItemWithLabel:@"快递公司" amount:shippingPrice];
        method.detail = @"24小时送到!";
        method.identifier = @"kuaidi";
        request.shippingMethods = @[method];
        request.shippingType = PKShippingTypeServicePickup;
        
        
        // 2.9 存储额外信息
        // 使用applicationData属性来存储一些在你的应用中关于这次支付请求的唯一标识信息,比如一个购物车的标识符。在用户授权支付之后,这个属性的哈希值会出现在这次支付的token中。
        request.applicationData = [@"商品ID:123456" dataUsingEncoding:NSUTF8StringEncoding];
        
        
        //添加物品到支付页
        //创建物品并显示,这个对象描述了一个物品和它的价格,数组最后的对象必须是总价格。
        //使用PKPaymentSummaryItem来创建商品信息
        
        PKPaymentSummaryItem *widget1 = [PKPaymentSummaryItem summaryItemWithLabel:@"商品1" amount:[NSDecimalNumber decimalNumberWithString:@"20.0"]];
        
        PKPaymentSummaryItem *widget2 = [PKPaymentSummaryItem summaryItemWithLabel:@"商品2" amount:[NSDecimalNumber decimalNumberWithString:@"10.0"]];
        
        PKPaymentSummaryItem *total = [PKPaymentSummaryItem summaryItemWithLabel:@"商品3" amount:[NSDecimalNumber decimalNumberWithString:@"25.0"]];
        
        request.paymentSummaryItems = @[widget1, widget2, total];
        //        request.paymentSummaryItems = @[widget1];
        //显示认证视图
        PKPaymentAuthorizationViewController * paymentPane = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
        paymentPane.delegate = self;
        
        [self presentViewController:paymentPane animated:TRUE completion:nil];
    }else{
        //设备不支持支付
        NSLog(@"设备不支持支付");
    }
    
  • 支付过程中会进行调用 PKPaymentAuthorizationViewControllerDelegate

    //这个代理方法指的是支付过程中会进行调用
    - (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                        didAuthorizePayment:(PKPayment *)payment
                                completion:(void (^)(PKPaymentAuthorizationStatus status))completion
    {
        //payment:代表的是一个支付对象, 支付相关的所有信息都在他的身上:1.token.   2.address
            
        //completion : 是一个回调的block  ,block回调的参数,直接影响到界面结果的展示。
    
        /*PKPaymentAuthorizationStatus 交易状态
        PKPaymentAuthorizationStatusSuccess, // 成功交易
        PKPaymentAuthorizationStatusFailure // 没有授权交易
        PKPaymentAuthorizationStatusInvalidBillingPostalAddress  // 拒绝账单地址
        PKPaymentAuthorizationStatusInvalidShippingPostalAddress, // 拒绝收货地址
        PKPaymentAuthorizationStatusInvalidShippingContact //提供的信息不够
        PKPaymentAuthorizationStatusPINRequired  // 交易需要指纹输入
        PKPaymentAuthorizationStatusPINIncorrect // 输入不正确,重新输入.
        PKPaymentAuthorizationStatusPINLockout// 输入次数超出
        */
        PKPaymentToken * token = payment.token;
        NSLog(@"获取token---%@", token);
        //获取订单地址
        NSString * address = payment.billingContact.postalAddress.city;
        NSLog(@"获取到地址: %@", address);
        NSLog(@"验证通过后, 需要开发者继续完成交易");
        // 在这个位置, 我们开发人员需要把token值和商品的其他信息如:地址 id  这些 , 上传到自己公司的服务器。然后公司的服务器和银行的商家接口进行接口的调用,并将接口调用返回的支付结果信息返回到这里。
        //根据不同的支付结果状态,让block调用不同的交易状态;
        //比如说:服务器调用支付结果是成功的, 就让        completion(PKPaymentAuthorizationStatusSuccess);          如果失败 调用        completion(PKPaymentAuthorizationStatusFailure);
        //如:
        BOOL isSuccess = YES;
        if (isSuccess) {
            completion(PKPaymentAuthorizationStatusSuccess);
        }else {
            completion(PKPaymentAuthorizationStatusFailure);
        }
    }
    
  • 授权成功之后或者取消授权之后会调用这个代理方法

    - (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
    NSLog(@"取消或者交易完成");
    [self dismissViewControllerAnimated:YES completion:nil];
    }