Apple Pay 应用内支付流程分析
2016-02-23 09:39
323 查看
接入方式
Apple Pay接入方式的选择上有两种。一种是使用 CUP SDK(CUP 就是 China Union Pay)等第三方的 SDK。另外一种就是使用 iOS 的 PassKit Framework 和银联的接口来接入。本质上来说,第三方 SDK 就是对 PassKit Framework 和传输信息的加密解密过程做了一层封装,让开发者可以轻松完成 Apple Pay 的接入。两种接入方式对比:第一种使用第三方 SDK 接入的方式开发成本较低,但缺点在于对 Payment Sheet 定制化程度不够。而第二种形式的缺点就是开发成本较高。不仅 iOS 端要处理好 Payment Sheet 的显示和隐藏的逻辑,还要对各种异常情况做好相应的 UI 处理。同时在后台也需要处理好以下情况:支付信息的解密,银联接口的交互,以及订单状态的处理。
支付流程分析
要理解 Apple Pay 的支付流程,其中最关键一点就是:Apple 不处理跟扣款相关的逻辑,它只负责支付信息的传递。Apple 通过 Touch ID 来验证银行卡卡持有者身份。实际的扣款行为则是发生在银联端,接入了 Apple Pay 的商户组织好 Apple 返回的支付信息,向银联发出扣款请求之后,该笔交易才会真正发生扣款。所以,商户还是要跟银联进行结算的,Apple Pay 只是提供了一种支付渠道。
Apple Pay 应用内支付流程如下
1.App 根据使用场景显示 Payment Sheet。
2.用户选择需要进行支付的卡以及支付需要的个人信息后,进行指纹验证,之后根据情况,有些银行卡还需要输入卡对应的密码(PIN 码)
3.iOS 将支付相关信息发送到 Apple 的服务器,进行加密。然后通过回调函数将加密后的支付信息返回给对应 App。
4.App 在收到回调之后,将对应信息发送到自己的服务器。
5.服务器在收到 App 发送来的支付信息后,对数据进行解密操作,提取其中需要的信息,组织银联接口报文,调用银联的接口,完成扣款
下面对过程中的关键地方做一些说明。
App 收到的 Payment sheet 回调信息中,包含了一个 PKPayment 的对象,该对象包含了所有跟 Apple Pay 支付相关所有信息。比如用户的手机号或者收货地址等等,其中最重要的就是 payment token,它的 paymentData 字段数据就是需要发送给服务器的内容。用户信息部分是明文的,而支付信息也就是 paymentData 部分则是被加密过的。
paymentData 的内容是 Json 格式的二进制流,服务器在收到这个数据之后进行解析,其中的
以上的服务器端对 paymentData 的解密流程,我们后台的同学近期会整理并开源出来,方便大家使用。有一点需要特别注意:paymentData 里的有一个交易金额字段,但该字段返回的数据并不是实际支付的金额。在组织银联报文的时候一定要注意不要直接使用该字段的内容作为扣款金额的值。
调用银联接口时也有一些需要注意的事项。拿调用银联扣款接口举例,在组织好报文并调用银联接口发送给银联之后,银联的接口返回结果同时有同步和异步两种形式。注意:如果同步结果返回成功,说明银联成功收到并开始处理扣款请求,并不是代表扣款成功。扣款是否成功,是通过异步形式来通知的。扣款不成功的原因可能有很多,比如卡被冻结,PIN 码错误,余额不足等等。为了保证交易状态的准确,推荐的做法是这样:在调用扣款接口后,如果 3 秒内没有收到本次调用的异步结果回调,则使用银联的流水号,开始轮询银联的交易状态接口来确保拿到确切的交易结果。
总结
Apple Pay 是很重视数据安全的。从上面的流程可以看到,为了保证整个交易的安全,Apple Pay 对每个关键流程都有加密处理。同时对每个绑定了 Apple Pay 的银行卡生成一个虚拟卡号,这个卡号的部分信息可以在 wallet 里绑定的卡片详情里看到。在实际支付中是用的这个卡号来做交易,这样可以在一定程度上保证我们银行卡的信息安全。
最后,如何将 Apple Pay 接入到 App 中,要结合自身的产品做出选择。如果只是将 Apple Pay 作为现有支付手段的一种补充,那么使用第三方 SDK 是一种省时省力的选择。如果需要跟 Apple Pay 做深度集成以及 Payment Sheet 的高度定制化,那么就需要使用 PassKit Framework 和银联接口方式来接入。
Apple Pay接入方式的选择上有两种。一种是使用 CUP SDK(CUP 就是 China Union Pay)等第三方的 SDK。另外一种就是使用 iOS 的 PassKit Framework 和银联的接口来接入。本质上来说,第三方 SDK 就是对 PassKit Framework 和传输信息的加密解密过程做了一层封装,让开发者可以轻松完成 Apple Pay 的接入。两种接入方式对比:第一种使用第三方 SDK 接入的方式开发成本较低,但缺点在于对 Payment Sheet 定制化程度不够。而第二种形式的缺点就是开发成本较高。不仅 iOS 端要处理好 Payment Sheet 的显示和隐藏的逻辑,还要对各种异常情况做好相应的 UI 处理。同时在后台也需要处理好以下情况:支付信息的解密,银联接口的交互,以及订单状态的处理。
支付流程分析
要理解 Apple Pay 的支付流程,其中最关键一点就是:Apple 不处理跟扣款相关的逻辑,它只负责支付信息的传递。Apple 通过 Touch ID 来验证银行卡卡持有者身份。实际的扣款行为则是发生在银联端,接入了 Apple Pay 的商户组织好 Apple 返回的支付信息,向银联发出扣款请求之后,该笔交易才会真正发生扣款。所以,商户还是要跟银联进行结算的,Apple Pay 只是提供了一种支付渠道。
Apple Pay 应用内支付流程如下
1.App 根据使用场景显示 Payment Sheet。
2.用户选择需要进行支付的卡以及支付需要的个人信息后,进行指纹验证,之后根据情况,有些银行卡还需要输入卡对应的密码(PIN 码)
3.iOS 将支付相关信息发送到 Apple 的服务器,进行加密。然后通过回调函数将加密后的支付信息返回给对应 App。
4.App 在收到回调之后,将对应信息发送到自己的服务器。
5.服务器在收到 App 发送来的支付信息后,对数据进行解密操作,提取其中需要的信息,组织银联接口报文,调用银联的接口,完成扣款
下面对过程中的关键地方做一些说明。
App 收到的 Payment sheet 回调信息中,包含了一个 PKPayment 的对象,该对象包含了所有跟 Apple Pay 支付相关所有信息。比如用户的手机号或者收货地址等等,其中最重要的就是 payment token,它的 paymentData 字段数据就是需要发送给服务器的内容。用户信息部分是明文的,而支付信息也就是 paymentData 部分则是被加密过的。
paymentData 的内容是 Json 格式的二进制流,服务器在收到这个数据之后进行解析,其中的
header.wrappedKey是使用非对称加密算法加密过的对称秘钥。使用在苹果开发者后台配置 merchant 时的私钥进行解密,会得到这个对称秘钥。然后用这个对称秘钥对
data字段所包含的加密数据进行解密,可以得到 Apple 返回的与支付相关的信息。此支付信息是加密过的,包含了用户支付的卡号和 PIN 码等信息,理论上只有银联才能解析出来真正的内容,我们作为商户是看不到具体信息的。服务器端需要将这些解密过的信息组织成银联所需的报文内容,然后调用银联的扣款接口,完成扣款。
以上的服务器端对 paymentData 的解密流程,我们后台的同学近期会整理并开源出来,方便大家使用。有一点需要特别注意:paymentData 里的有一个交易金额字段,但该字段返回的数据并不是实际支付的金额。在组织银联报文的时候一定要注意不要直接使用该字段的内容作为扣款金额的值。
调用银联接口时也有一些需要注意的事项。拿调用银联扣款接口举例,在组织好报文并调用银联接口发送给银联之后,银联的接口返回结果同时有同步和异步两种形式。注意:如果同步结果返回成功,说明银联成功收到并开始处理扣款请求,并不是代表扣款成功。扣款是否成功,是通过异步形式来通知的。扣款不成功的原因可能有很多,比如卡被冻结,PIN 码错误,余额不足等等。为了保证交易状态的准确,推荐的做法是这样:在调用扣款接口后,如果 3 秒内没有收到本次调用的异步结果回调,则使用银联的流水号,开始轮询银联的交易状态接口来确保拿到确切的交易结果。
总结
Apple Pay 是很重视数据安全的。从上面的流程可以看到,为了保证整个交易的安全,Apple Pay 对每个关键流程都有加密处理。同时对每个绑定了 Apple Pay 的银行卡生成一个虚拟卡号,这个卡号的部分信息可以在 wallet 里绑定的卡片详情里看到。在实际支付中是用的这个卡号来做交易,这样可以在一定程度上保证我们银行卡的信息安全。
最后,如何将 Apple Pay 接入到 App 中,要结合自身的产品做出选择。如果只是将 Apple Pay 作为现有支付手段的一种补充,那么使用第三方 SDK 是一种省时省力的选择。如果需要跟 Apple Pay 做深度集成以及 Payment Sheet 的高度定制化,那么就需要使用 PassKit Framework 和银联接口方式来接入。
相关文章推荐
- iOS9下有关CoreLocation学习二
- android真机测试No minsdk(API 16)>device sdk(api 1)
- (Android)代码覆盖率统计
- Android静态代码检查
- 在AndroidManifest.xml中uses-sdk内属性意思
- Unity 关于冻结Rotation 和 Position的选项
- iOS 设计模式之原型模式 (Prototype)
- 解决5.0以上通知栏图标变白
- Android 实现闪屏页和右上角的倒计时跳转
- JavaScript的Function与Object浅析
- Android万能适配器 简化繁琐的开发
- Android Data Binding代码实战,mvvm
- 【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
- android:layout_gravity和android:gravity的区别
- iOS开发之与后台服务器的交互
- iOS simulator Code = 4
- Android开发笔记(六十八)工程库打包
- IOS 开发 证书显示 此证书签发者无效 解决办法
- Android.mk 文件语法详解
- 关于16年2月14日以后上传AppStore出现:Missing iOS Distribution signing identity for...的问题