ApplePay 接入教程及开发过程需要注意的点

运行环境##

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

环境配置##

1、 Xcode 7.2.1 以及以上打开项目,在 Capabilities里将Apple Pay设置为on,如下图,请忽略 Merchant IDmerchant.com.Carman.Paydemo这一项,一会我会详细介绍。

ApplePay 接入教程及开发过程需要注意的点_第1张图片
图片-1

这时你会发现 项目 下 会自动 生成一个 类似证书的东西

图片-2

这一步做了什么?
1、自动导入了需要的库文件。
2、添加了一个权限文件(图片-2).

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

ApplePay 接入教程及开发过程需要注意的点_第2张图片
图-3

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

ApplePay 接入教程及开发过程需要注意的点_第3张图片
图-4

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

ApplePay 接入教程及开发过程需要注意的点_第4张图片
图 -5

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

ApplePay 接入教程及开发过程需要注意的点_第5张图片
图-6

点击 Done
ApplePay 接入教程及开发过程需要注意的点_第6张图片
图 -7

根据上面的提示,点击Edit,接下去应该是需要建证书了。
首次添加时候 会询问你是否 在中国使用。选择 YES(截图是默认状态-NO),一直 continue 。
ApplePay 接入教程及开发过程需要注意的点_第7张图片
图-8

3、新建证书
创建 ** Creating a Certificate Signing Request (CSR) CSR 证书,**
Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.
打开钥匙串访问 如下图操作

ApplePay 接入教程及开发过程需要注意的点_第8张图片
图-9

生成 CertificateSigningRequest.certSigningRequest(名称可以自定义)
ApplePay 接入教程及开发过程需要注意的点_第9张图片
图-10

上传 生成证书


ApplePay 接入教程及开发过程需要注意的点_第10张图片
图-11

满怀信心,觉得即将成功是么?

ApplePay 接入教程及开发过程需要注意的点_第11张图片
图-12

此证书是由未知颁发机构签名的!!!什么鬼呀,老子的账号明明是正规渠道申请的!
还好有解决方案--- 点我解决.
点击下载红线项,删除老的证书,重新导入 G2 证书
ApplePay 接入教程及开发过程需要注意的点_第12张图片
图-13

以上,ApplePay 所需的环境就算全部配置完成了。
总结一下就一条: 生成了 Merchant ID 证书
再看 项目 工程,已经自动生成了 Merchant ID 值,打钩就可以了,如果没有生成,再检查下 项目的 Bundle identifier是否和证书一致。
ApplePay 接入教程及开发过程需要注意的点_第13张图片
图-14

代码集成##

首先我们来看下模拟器上Demo 运行的结果:

ApplePay 接入教程及开发过程需要注意的点_第14张图片
图-15

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

1、
导入头文件,(xcode 7.0 以上已经自动帮我们导入了库,所以我们只需要导入头文件即可)

#import 

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

- (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];

当然,我们要实现 代理

@interface ViewController : UIViewController
@end

实现 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:支付结束,关闭 支付弹框。
3、可选的另外的代理 回调 请参考Apple Pay接入详细教程 一文

我们主要来看下** PKPayment** 对象

ApplePay 接入教程及开发过程需要注意的点_第15张图片
图-16

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

 - (void) paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller

didAuthorizePayment:(PKPayment *)payment

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

{

NSError *error;

ABMultiValueRef addressMultiValue = ABRecordCopyValue(payment.billingAddress, kABPersonAddressProperty);

NSDictionary *addressDictionary = (__bridge_transfer NSDictionary *) ABMultiValueCopyValueAtIndex(addressMultiValue, 0);

NSData *json = [NSJSONSerialization dataWithJSONObject:addressDictionary options:NSJSONWritingPrettyPrinted error: &error];

// ... Send payment token, shipping and billing address, and order information to your server ...

PKPaymentAuthorizationStatus status; // From your server

completion(status);

}

更深入了解可以参看官方文档

钱去哪了##

目前为止,我们完成了客户端的ApplePay 代码集成,假设回调的信息也成功上传 服务器,服务器也成功对订单进行了处理,那么用户支付的钱去哪了?
1、钱去了商家的 AppStore 账号?
苹果账号的申请一般都是用信用卡支付 ,业务的收入不太可能直接打到信用卡里。
2、商家 AppStore 账号绑定了商家的银行卡?
我们生成 Merchant ID 证书的时候 并没有这一步。

支付供应商##

苹果官方文档 Apple Pay 入门 明确指出:

ApplePay 接入教程及开发过程需要注意的点_第16张图片
图-17

就是说,苹果官方强烈建议开发者接入他合作的支付供应商SDK 来支持ApplePay,这样就能理解了,开发者到支付供应商网站注册相关信息,绑定商户ID ,银行卡等,这样用户的钱就到了商户在支付供应商注册的账号里面。我们可以把支付供应商 理解成付款处理结构。 坑爹呀,上面的集成都白写了!!!

苹果官方在中国合作的指定付款处理结构有 (参考ApplePay 介绍):

中国银联
连连支付
首信易支付
易宝支付
银联商务

这里选择中国银联的sdk 进行介绍,有兴趣的同学可以自行去研究另外几个供应商的支付SDK。

中国银联##

选择中国银联 接入 有个很大的好处 -- 文档非常的详细。
1、中国银联商户入网新手指南
https://merchant.unionpay.com/join/help/director
2、银联商家服务
https://open.unionpay.com/ajweb/product/detail?id=80
3、银联Apple Pay控件开发包
https://open.unionpay.com/ajweb/help/file/techFile?productId=80

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

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


ApplePay 接入教程及开发过程需要注意的点_第17张图片
图-18

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

ApplePay 接入教程及开发过程需要注意的点_第18张图片
图-19

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 负责提示用户交易结果。

集成的测试代码介绍##

1-2步、商户生成订单,通过商户SERVER端将订单信息发送给银联支付网关; 代码如下:

- (void) pmPayAction:(id)sender {
    //使用PM环境
    self.tnMode = @"01";
    NSURL* url = [NSURL URLWithString:@"http://101.231.204.84:8091/sim/getacptn"];
    
    NSMutableURLRequest * urlRequest=[NSMutableURLRequest requestWithURL:url];
    NSURLConnection* urlConn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
    [urlConn start];
    [self showAlertWait];
}

1、 self.tnMode = @"01"; //接入模式,标识商户以何种方式调用支付控件,00生产环境,01测试环境
2、http://101.231.204.84:8091/sim/getacptn //银联提供测试的 URL

3-9 步:代码如下:

#pragma mark - connection

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response
{
    NSHTTPURLResponse* rsp = (NSHTTPURLResponse*)response;
    NSInteger code = [rsp statusCode];
    if (code != 200)
    {
        
        [self showAlertMessage:kErrorNet];
        [connection cancel];
    }
    else
    {
        UPRelease(_responseData);
        _responseData = [[NSMutableData alloc] init];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [_responseData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self hideAlert];
    NSString* tn = [[NSMutableString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding];
    if (tn != nil && tn.length > 0)
    {
        if([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[PKPaymentNetworkChinaUnionPay]])
        {

            [UPAPayPlugin startPay:tn mode:self.tnMode viewController:self delegate:self andAPMechantID:kAppleMerchantID];
        }

    }
    [tn release];
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [self showAlertMessage:kErrorNet];
}

1、** [UPAPayPlugin startPay:tn mode:self.tnMode viewController:self delegate:self andAPMechantID:kAppleMerchantID];**
1、tn / /订单信息
2、self.tnMode //接入模式,标识商户以何种方式调用支付控件,00生产环境,01测试环境
3、kAppleMerchantID //苹果公司分配的商户号,表示调用Apple Pay所需要的MerchantID;(接入银联支付时候,该 MerchantID 需要商家向银联申请生成)

ApplePay 接入教程及开发过程需要注意的点_第19张图片
图 -20

10-12步,银联将支付结果返回给商户 APP,商户 SERVER,商户 APP 负责提示用户交易结果。 回调处理。

#pragma mark -
#pragma mark 响应控件返回的支付结果
#pragma mark -
- (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];
        
    }
}

运行效果###

ApplePay 接入教程及开发过程需要注意的点_第20张图片
图-21
ApplePay 接入教程及开发过程需要注意的点_第21张图片
图-22

你可能感兴趣的:(ApplePay 接入教程及开发过程需要注意的点)