Apple Pay 已经正式上线,ENJOY 作为国内首批接入 Apple Pay 应用内支付的 App,并且是为数不多的直接使用 PassKit Framework 和银联接口的形式接入的应用,我们在产品上与 Apple Pay 做了深度集成。接下来把我们在接入过程中的一些经验分享一下。本文并不涉及具体代码,也不是讲解 Apple Pay 如何接入的教程,只是结合我们的开发过程,介绍下在接入过程中需要注意的地方。
Apple Pay 是 Apple 推出的支付服务,支持线上支付和线下支付,对我们开发者而言,线下支付跟我们没有太多关系。而线上支付的接入也并不复杂,关键在于要理解 Apple Pay 的整个工作流程。
因为 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 应用内支付流程如下
下面对过程中的关键地方做一些说明。
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 和银联接口方式来接入。