ApplePay高调入华,教你在app里上线ApplePay

ApplePay在中国上线后,就有许多线上app前后脚加入了对其的接入支持,个人比较喜欢的ENJOY也抢在首批接入了ApplePay应用内支付。本文将分享作者的接入经验。
ApplePay是苹果公司推出的一种线上/线下的便捷支付方式,根据TouchId来验证支付卡持卡人身份,ApplePay并不参与资金流动,最终还是让银行完成扣款处理,目前据Apple介绍只配备在iphone6以上和新款的ipad Air2和ipad mini3上,中国地区最低系统要求为IOS9.2,对于一种新支付体验,这门槛的确有点高了。苹果开发文档对ApplePay工作方式的介绍.

线下支付使用NFC POST机只需要与银联联系签约租用即可,我们来介绍线上支付的流程和app应用内接入的方法。
目前的接入方式有两种,一是使用第三方提供商的SDK接入,另一种是让PassKit Framework直接与银联的接口对接,当然网络上还有一些自己使用PassKit PaymentRequest自己生成订单组织信息,直接与Apple对接的Demo,因为我们不可能每家银行跑去签约,大陆的银行也不会给我们开放特许,因此这种方式仅仅能用于测试ApplePay的功能和API尝鲜,并不适用于生产中。
ApplePay官网上有列出中国目前支持并提供SDK的第三方提供商
使用第三方SDK接入的优点是开发成本比较低,并且各自都应该有高度定制的Payment Sheet(因订单信息完整度的不同),可供定制更详细的商品信息展示,缺点就是要钱。
若我们选择后者,相对开发成本会高,移动端不仅需要对支持性进行验证,协商银联接口数据对Payment Sheet的展示关闭进行控制,对各种异常进行捕抓和处理,同时后台需要自己实现对银联接口的认证交互,对交易数据的标准封装,订单状态的处理,支付信息的解密等。
我们选择使用银联SDK接入这种折中的方式,免费,工作量可以接受。
使用银联SDK接入的实现方式如图所示,主要工作是商户后台利用现成的API与银联的交互:

申请MerchantID并更新你的证书:
向苹果申请我们独有的商户ID,这里我借用Yasin朋友在简书上分享的详细步骤,真的很详细易懂。
获得MerchantId后,更新你的证书,并且于项目->targets->Capabilities中打开ApplePay权限,选择正确的MerchantID,让三个steps成为tick状态完全权限的配置。

ok开始与银联碰头,于银联商家技术服务中心找到ApplePay入口,然后在"技术文档"选项卡中可以找到相应的SDK和后台文档。

这里我使用PHP后台,在下载的SDK压缩包里找到了PHP Version SDK,忽略掉这个外壳,我们需要将子文件夹upacp_demo_app部署到我们的服务器中。

这里我将upacp_demo_app部署到我mac的PHP环境中,打开upacp_demo_app/demo/api_05_app可以看见各种对订单处理的接口。

订单的创建,取消,查询,退款等,现在我们测试下创建订单接口
订单参数
下图是创建订单的请求参数,目前银联创建ApplePay订单仅支持图中所示的参数字段,基本满足使用但可定制性比较低,最基本的订单参数merId商户号,orderId订单号,txnTime订单发送时间,txnAmt订单金额,目前测试阶段我们可以通过直接调用此接口post传参,也可以直接写死在php文件中
- 注意:这里的merId是银联商户号,而非苹果分配的MerchantID。
测试证书
了解到这里后还没有具备生成订单的条件,然后我们需要配置配置签名证书和验签证书的路径,这些证书在SDK下载包里面已经有附带,我们只需要在upacp_demo_app/sdk/SDKConfig.php文件中配置好他们的路径即可

这里需要配置主机的绝对路径,不能使用项目相对路径,完成SDK_SIGN_CERT_PATH,SDK_ENCRYPT_CERT_PATH,SDK_VERIFY_CERT_DIR路径的配置
成功获取tn
我们请求下Form_6_2_AppConsume.php接口,即可创建订单,并且返回对应的Trade Name
,在App端我们就是拿这个Trade Name来对相应的订单进行付款。

拿到订单tn后,我们已经可以使用银联SDK调起支付,在这之前还要做的就是对设备和平台的支持性检测,通过,present出Payment Sheet即可。
工程配置:
1.添加SDK包:
将下载SDK解压包中找到applePaySDK文件夹,加入到需要接入ApplePay的项目中。

**这里注意,项目内如果同时支持银联普通支付的话,因为两个库引用重复,最好的办法就是升级银联SDK至最新版本(3.3.3),当然可以使用添加Linker Flags的方式解决,或者可以自己剥离掉重复部分,我是懒人,我选择升级哈哈。
2.为工程引入必须的framework:
- CFNetwork.framework
- PassKit.framework
- SystemConfiguration/framework
- libUPAPayPlugin.a
- libz.1.2.5.tbd
3.银联SDK使用http请求,在ios9以后需在工程plist文件中添加NSAppTransportSecurity来支持Http继续使用。
---注意---
- 因为银联SDK内部分代码是由C/C++组织,这里必须添加libz.1.2.5.tbd,并且将引用到UPAPayPlugin.h的源文件的后缀改为.mm
- 同时检查Target->Build Settings->Search Paths->Library Search Paths中自定义库libUPAPayPlugin.a的路径是否正确
4.最后可以开始写代码了,在需要调起ApplePay支付控件的文件中引入头文件UPAPayPlugin.h(记得文件名后缀需要改成.mm),PassKit/PassKit.h
- (void)verifiesApplePayAbility {
if (![PKPaymentAuthorizationViewController class]) {
//检查系统版本支持性
PopMessage(@"当前系统版本不支持ApplePay,最低支持:iphone6, ios9.0以上");
return;
} else if (![PKPaymentAuthorizationViewController canMakePayments]) {
//检查设备支持性
PopMessage(@"当前设备不支持ApplePay,最低支持:iphone6, ios9.0以上");
return;
} else {
//检查卡片支持性
NSArray *supportedNetwork = @[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkChinaUnionPay, PKPaymentNetworkAmex, PKPaymentNetworkDiscover];
if (![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:supportedNetwork]) {
PopMessage(@"没有绑定支持的卡片");
return;
}
} //调起苹果支付控件
[self presentPaymentSheet];
} - (void)presentPaymentSheet {
WaitingMessage(@"正在呼出ApplePay支付控件");
[UPAPayPlugin startPay:yourPayTn mode:self.applePayMode viewController:self delegate:self andAPMechantID:kAppleMechantId]; //-startPay 第一个参数是后台向银联请求创建订单获得的商品tn
//mode是字符串,00为正式环境,01为测试环境
//此处的MechantID传的是从苹果那获取的mechantId
}
如果需要对借记卡/信用卡作限制,在检查卡片支持性的步骤可以这样写:
//检查卡片支持性
NSArray *supportedNetwork = @[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkChinaUnionPay, PKPaymentNetworkAmex, PKPaymentNetworkDiscover];
PKMerchantCapability capabilities = PKMerchantCapabilityEMV | PKMerchantCapability3DS | PKMerchantCapabilityDebit;
if (![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:supportedNetwork capabilities:capabilities]) {
PopMessage(@"没有绑定支持的卡片,本支付仅支持使用借记卡支付");
return;
}
最后是银联ApplePay的支付回调:
返回的UPPayResult对象中有各种支付状态,同时我们还应该检查他的otherInfo属性,里面包含银联的优惠活动信息,如果有则应该在支付成功页中告知客户。
//实现UPAPayPluginDelegate
- (void)UPAPayPluginResult:(UPPayResult *)payResult {
//do something
//检查是否有银联优惠信息,告知客户
}
otherInfo中包含优惠信息的格式为: otherInfo = "currency=元&order_amt=20.00&pay_amt=15.00" //currency 币种
//order_amt 订单金额
//pay_amt 实付金额
!!!目前不支持商户自定义优惠活动!!!
博主自己研究了php API很久后无果,咨询银联客服,然后彻底死心。。
展示
以下左图是通过银联SDK接入,因为可定制参数比较少,Payment Sheet比较简短,右图是使用苹果API直接生成的订单。

相信美团的ApplePay也是跟银联对接的,心血来潮买了个流量顺便作下对比

生产环境:
csr文件
若需要在生产环境中使用银联SDK接入ApplePay,首先需向银联申请开通ApplePay服务(联系下签约服务),并从银联商户服务平台生成ApplePay专用的CSR文件,重新去苹果开发者网站签署证书。

公钥,私钥
公钥在SDK下载包里面有,私钥在cfca入网通知邮件里面附带也可以自行下载,一个商户号唯一一份私钥和授权码,跟银联普通支付私钥是同一份。
配置
修改生产环境配置文件中的签名证书,密码,后台url地址
更换正式环境商户号(也可以是同一个)
app前端startPay方法的mode参数改为"00"
注意事项:
Apple Pay - Apple Developer
Apple Pay准备工作-申请MerchantID及对应证书详细图文教程 - 简书
商家技术服务
iOS Human Interface Guidelines: Apple Pay
个人博客原文
ApplePay高调入华,教你在app里上线ApplePay的更多相关文章
- 教你玩App怎么赚钱(一)
在看这篇文章之前,你一定要接受一下谋哥的观点:金钱就是价值流通的手段,不要高看了钱. 玩App怎么赚钱?貌似谋哥写的文章超级多,把这个最重要的忘记了.说实在的,我为啥要写“玩App"呢?其实 ...
- Vuejs 高仿饿了么外卖APP 百度云视频教程下载
Vuejs 高仿饿了么外卖APP 百度云视频教程下载 链接:https://pan.baidu.com/s/1KPbKog0qJqXI-2ztQ19o7w 提取码: 关注公众号[GitHubCN]回复 ...
- 牛客网 牛客小白月赛12 B.华华教月月做数学-A^B mod P-快速幂+快速乘
链接:https://ac.nowcoder.com/acm/contest/392/B来源:牛客网 华华教月月做数学 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其 ...
- 牛客练习赛46 A 华华教奕奕写几何 (简单数学)
链接:https://ac.nowcoder.com/acm/contest/894/A 来源:牛客网 华华教奕奕写几何 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K ...
- NC23046 华华教月月做数学
NC23046 华华教月月做数学 题目 题目描述 找到了心仪的小姐姐月月后,华华很高兴的和她聊着天.然而月月的作业很多,不能继续陪华华聊天了.华华为了尽快和月月继续聊天,就提出帮她做一部分作业. 月月 ...
- IT连创业系列:App产品上线后,运营怎么搞?(中)
等运营篇写完,计划是想写一个IOS系列,把IT连App里用到和遇到的坑都完整的和大伙分享. 不过写IOS系列前,还是要认真把这个运营篇写完,接下来好好码字!!! 上篇说到,我们计划去一次富士康门口,拉 ...
- Andoird Crash的跟踪方法,使用腾讯Bugly来捕捉一些疑难杂症,让我们APP稳定上线
Andoird Crash的跟踪方法,使用腾讯Bugly来捕捉一些疑难杂症,让我们APP稳定上线 我们在开发中常常会注意到一些Crash,这正是很头疼的,而且Crash会带来很多意想不到的状态,很恶心 ...
- Console app 里的依赖注入及其实例生命周期
依赖注入是 ASP.NET Core 里的核心概念之一,我们平常总是愉快地在Startup类的ConfigureServices方法里往IServiceCollection里注册各种类型,以致有一些同 ...
- iOS 9 failed for URL: "XXX://@" - error: "This app is not allowed to query for scheme XXX" iOS 从APP里启动另一APP
iOS 从C APP里启动 D APP 首先在D APP里设置 URL Schemes 在info.plist 文件里添加URL Schemes URL Types -->item0 --> ...
随机推荐
- 【转】SQL常用的语句和函数
原文链接:http://www.cnblogs.com/mailingfeng/archive/2013/01/07/2850116.html order by 的数值型灵活使用 select * f ...
- Netbeans Platform 工程,免安装JDK
使用Netbeans 6.8 创建了一个Netbeans Platform 工程,以Zip形式发布后, 按照以下操作,可 以在客户端免安装JDK: 1. 从已安装JDK的计算机中,提取JDK:eg. ...
- [iOS微博项目 - 2.3] - 用户取消对app的授权
github: https://github.com/hellovoidworld/HVWWeibo A.用户取消对app的授权 用户可以在微博网站上取消对某个应用(app)的授权 1.打开& ...
- ACM之数学题
数学题,始终记得,第一次被带飞师大校赛以及省赛,毫无例外的在数学题上卡死....因此,现在开始,有意识的保留遇见的数学题...(下列知识点按遇见先后顺序排列: 1欧拉公式 欧拉公式的用处是,找出小于N ...
- My集合框架第五弹 最小堆
二叉堆(以最小堆为例),其具有结构性质和堆序性质结构性质: 堆是一棵完全的二叉树,一颗高为h的完全二叉树有2^h到2^h-1个节点,高度为log N 而且该结构可以很容易的使用数 ...
- InitializingBean和init-method
[spring的InitializingBean的 afterPropertiesSet 方法 和 init-method配置的 区别联系] InitializingBean Spring的Initi ...
- EF小节
EF学习笔记——生成自定义实体类 http://blog.csdn.net/leftfist/article/details/24889819 --工具: 1.entity developer 2.D ...
- thinkphp 3+ 观后详解 (5)
static public function dispatch() { $varPath = C('VAR_PATHINFO'); $varAddon = C('VAR_ADDON'); $varMo ...
- Ext的Panel总结(好文章)
我刚才禁不住诱惑去看了一下Ext.Window的API文档,发现只是比Panel多了点什么最大化.最小化.关闭.置前.置后.动画引发目标设置.可调整大小这些功能.像什么标题栏.工具栏之类的东西在Ext ...
- 理解Web标准(网站标准)
我觉得一名Web前端应该好好理解Web标准到底是什么,为什么要在我们的实际实践中遵循Web标准. 什么是Web标准.百度百科的解释是: WEB标准不是某一个标准,而是一系列标准的集合.网页主要由三部分 ...