Apple pay刚推出的时候可以说“绑定的过程很崩溃,用的时候很心碎”,为什么要这样说呢?因为刚一推出,就有大量的人同时绑定,银行和银联又处理不过来,就会出现以下界面,用的时候很心碎是指太TMD方便了,几百块说没就没呀,你说心碎不!哭:
一:适用于以下设备
注:操作系统必须iOS9.2以上版本watch OS 2.1以上版本,可以在模拟器上面运行,xcode7.2.1以上 + iPhone6S 以上 + 9.2系统以上,系统会绑定几种虚拟的银行卡,和几个联系人,方便调试,支付也不会发生真实的付款。
二:金融交易分为:在线远程支付和近场支付
1.在线远程支付:是指在应用内完成物品的购买,一般在电商应用内比较常见(Apple Pay 远程支付商户入网采取大商户、大行业优先、直联接入优先的原则。同时, 优先发展零售业、住宿/餐饮和休闲娱乐业、居民服务和商业服务、教育/卫生行业。暂时限制接 入互联网金融(基金、理财、直销银行、P2P、信贷还款、融资租赁等)、信用卡还款、货款回 缴、烟草、房地产、彩票以及其他苹果公司限制接入 Apple Pay 的行业及应用场景
)。
环境配置:在接入Apple Pay之前,首先要申请MerchantID。
第一步:首先明确,你要为哪一个应用做或者增加Apple Pay功能:
第二步:使该应用具备Apple Pay的能力:
第三步:配置Merchant IDs
这时回到你的应用,选择上面配置好的Merchant IDs
当你完成上面操作时,再回到apple ID时,这时查看你的应用你会发现如下界面:
到这里环境配置已经完毕。
二:代码体现
1.首先导入头文件:
#import //包含用户绑定的银行卡信息
#import //Apple pay的展示控制器
#import //用户联系的相关信息
2.代码展示
//点击支付按钮要执行的事件
- (IBAction)ApplePayBtnClicked:(id)sender {
if (![PKPaymentAuthorizationViewController class]) {
//PKPaymentAuthorizationViewController需iOS8.0以上支持
NSLog(@"操作系统不支持ApplePay,请升级至9.0以上版本,且iPhone6以上设备才支持");
return;
}
//检查当前设备是否可以支付
if (![PKPaymentAuthorizationViewController canMakePayments]) {
//支付需iOS9.0以上支持
NSLog(@"设备不支持ApplePay,请升级至9.0以上版本,且iPhone6以上设备才支持");
return;
}
//创建支付请求
//设置币种、国家码及merchant标识符等基本信息
PKPaymentRequest *payRequest = [[PKPaymentRequest alloc]init];
payRequest.countryCode = @"CN"; //国家代码
payRequest.currencyCode = @"CNY"; //RMB的币种代码
payRequest.merchantIdentifier = @"申请的merchantID"; //申请的merchantID
//配置请求的支付网络
//检查用户是否可进行某种卡的交易,是否支持Amex、MasterCard、Visa与银联四种卡,根据项目需要进行校验
NSArray *supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard,PKPaymentNetworkVisa,PKPaymentNetworkChinaUnionPay];
if (![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:supportedNetworks]) {
NSLog(@"你需要绑定支付卡");
return;
}
payRequest.supportedNetworks = supportedNetworks; //用户可进行支付的银行卡
payRequest.merchantCapabilities = PKMerchantCapability3DS|PKMerchantCapabilityEMV; //设置支持的交易处理协议,3DS必须支持,EMV为可选,目前国内的话还是使用两者吧
// payRequest.requiredBillingAddressFields = PKAddressFieldEmail;
//如果需要邮寄账单可以选择进行设置,默认PKAddressFieldNone(不邮寄账单)
payRequest.requiredShippingAddressFields = PKAddressFieldPostalAddress|PKAddressFieldPhone|PKAddressFieldName;
//送货地址信息,这里设置需要地址和联系方式和姓名,如果需要进行设置,默认PKAddressFieldNone(没有送货地址)
//
//设置配送方式可以设置多种供用户选择
PKShippingMethod *free = [PKShippingMethod summaryItemWithLabel:@"顺丰包邮" amount:[NSDecimalNumber zero]];
free.identifier = @"free";
free.detail = @"一天内送达";
PKShippingMethod *quick = [PKShippingMethod summaryItemWithLabel:@"极速送达" amount:[NSDecimalNumber decimalNumberWithString:@"15.00"]];
quick.identifier = @"quick";
quick.detail = @"1 小时内 送达";
// self.shippingMethod = [NSMutableArray arrayWithCapacity:@[free,quick]];
//shippingMethods为配送方式列表,类型是 NSMutableArray,这里设置成成员变量,在后续的代理回调中可以进行配送方式的调整。
payRequest.shippingMethods = @[free,quick];
NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:8888 exponent:-2 isNegative:NO]; //88.88
PKPaymentSummaryItem *subtotal = [PKPaymentSummaryItem summaryItemWithLabel:@"商品价格" amount:subtotalAmount];
NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"-66.66"]; //-66.66
PKPaymentSummaryItem *discount = [PKPaymentSummaryItem summaryItemWithLabel:@"优惠折扣" amount:discountAmount];
NSDecimalNumber *methodsAmount = [NSDecimalNumber zero];
PKPaymentSummaryItem *methods = [PKPaymentSummaryItem summaryItemWithLabel:@"顺丰包邮" amount:methodsAmount];
NSDecimalNumber *totalAmount = [NSDecimalNumber zero];
totalAmount = [totalAmount decimalNumberByAdding:subtotalAmount];
totalAmount = [totalAmount decimalNumberByAdding:discountAmount];
totalAmount = [totalAmount decimalNumberByAdding:methodsAmount];
PKPaymentSummaryItem *total = [PKPaymentSummaryItem summaryItemWithLabel:@"Obama" amount:totalAmount]; //要支付给谁
summaryItems = [NSMutableArray arrayWithArray:@[subtotal, discount, methods, total]];
//summaryItems为账单列表,类型是 NSMutableArray,这里设置成成员变量,在后续的代理回调中可以进行支付金额的调整。
payRequest.paymentSummaryItems = summaryItems;
//ApplePay控件
PKPaymentAuthorizationViewController *view = [[PKPaymentAuthorizationViewController alloc]initWithPaymentRequest:payRequest];
//view可能创建不成功,因为payRequest可能创建失败或无效
if (!view) {
return;
}
view.delegate = self;
[self presentViewController:view animated:YES completion:nil];
}
#pragma mark - 授权的代理方法
//controller:授权控制器
//payment:支付对象 token,address地址
//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; //送货信息
PKContact *shippingMethod = payment.shippingMethod; //送货方式
//在这里将token,送货信息,送货方式发送到自己的服务器,自己的服务器和银行与商家对接支付,并将结果防回到这里,根据结果生成对应的状态对象,根据状态对象显示不同的支付结果
//等待服务器返回结果后再进行系统block调用
//状态对象
BOOL isSuccessed = YES;
if (isSuccessed) {
completion(PKPaymentAuthorizationStatusSuccess);
}else{
completion(PKPaymentAuthorizationStatusFailure);
}
}
//当授权结束或取消支付,就会调用该方法
- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller{
NSLog(@"授权结束");
//让展示界面消失
[controller dismissViewControllerAnimated:YES completion:nil];
}
//该方法可以选择实现
//- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
// didSelectShippingContact:(PKContact *)contact
// completion:(void (^)(PKPaymentAuthorizationStatus, NSArray * _Nonnull, NSArray * _Nonnull))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及以上才有
//
// //送货信息选择回调,如果需要根据送货地址调整送货方式,比如普通地区包邮+极速配送,偏远地区只有付费普通配送,进行支付金额重新计算,可以实现该代理,返回给系统:shippingMethods配送方式,summaryItems账单列表,如果不支持该送货信息返回想要的PKPaymentAuthorizationStatus
// completion(PKPaymentAuthorizationStatusSuccess, self.shippingMethod, summaryItems);
//}
//该方法根据实际情况,选择实现
//- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
// didSelectShippingMethod:(PKShippingMethod *)shippingMethod
// completion:(void (^)(PKPaymentAuthorizationStatus, NSArray * _Nonnull))completion{
// //配送方式回调,如果需要根据不同的送货方式进行支付金额的调整,比如包邮和付费加速配送,可以实现该代理
// PKShippingMethod *oldShippingMethod = [summaryItems objectAtIndex:2];
// PKPaymentSummaryItem *total = [summaryItems lastObject];
// total.amount = [total.amount decimalNumberBySubtracting:oldShippingMethod.amount];
// total.amount = [total.amount decimalNumberByAdding:shippingMethod.amount];
//
// [summaryItems replaceObjectAtIndex:2 withObject:shippingMethod];
// [summaryItems replaceObjectAtIndex:3 withObject:total];
//
// completion(PKPaymentAuthorizationStatusSuccess, summaryItems);
//}
//根据需求,选择实现。支付银行卡回调,如果需要根据不同的银行调整付费金额,可以实现该代理
//-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectPaymentMethod:(PKPaymentMethod *)paymentMethod completion:(void (^)(NSArray * _Nonnull))completion{
//
// completion(summaryItems);
//}
二:金融交易之近场支付(目前银行类客户端比较常见)
在银行类客户端中基本都是跳到wallet应用( [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@“shoebox://“]];),以后的操作都有用户自己管理。当然银行自己的App也可以对卡进行一些:挂失,解挂,注销等操作,因每个银行需求不一样,至于在银行客户端中怎样进行挂失,解挂等,行内人员(主要tsm系统)提供接口,页面设计有行内决定,有开发人员自行开发。