ApplePay 初探

1,102 阅读3分钟

在 iOS 系统下,苹果对虚拟物品的交易是要抽成的,这个也限制了虚拟物品交易的支付渠道必须是 ApplePay 了,作为开发者,能做的也就是把 ApplePay 集成进我们的 App 吧。

一、配置环境

  1. 登录 Apple 开发者页面,申请一个商业标识符 MerchantID,并跟工程的 BundleIdentifier 绑定,具体步骤可以在网上找下。

  2. 在 Xcode 上配置 ApplePay 支持。

    如果是 Xcode11 之下,在 Capabilities 中打开 ApplePay 选项开关即可;

    如果是 Xcode11,则需要在 Signing & Capabilities 的左上角,点击 + Capability 手动添加一个 ApplePay 选项。

  3. 在第2步的 AppleyPay 选项中,如果没有显示出 MerchantId,则需要手动在 <工程名>.entitlements 文件里的 Merchant IDs 下添加一个元素,填写在第1步中申请时填写的以 merchant. 开头的那个字符串。重启工程,就可以 ApplePay 选项中看到它了,显示为未找到的红色,不用管它。


二、开发

ApplePay 的 API 在 iOS10 系统前后有些区别,在 iOS10 之前是用 PKPaymentAuthorizationViewController 继承于 UIViewController,在 iOS10 之后用的是 PKPaymentAuthorizationController 继承于 NSObject。它们的 API 基本完全相同,本文就用 PKPaymentAuthorizationController 举例了,下面介绍一点主要的 API。


1、 权限判断

API 描述
open class func canMakePayments() -> Bool 判断设备是否支持 ApplePay
open class func canMakePayments(usingNetworks supportedNetworks: [PKPaymentNetwork]) -> Bool 判断设备是否支持传入的网络的 ApplePay,如果 ApplePay 里没有支持的卡,或者没有卡也会返回 false

2、 跳转钱包,设置银行卡,直接跳转到苹果的钱包应用,并唤起添加卡片页面

let wallet = PKPassLibrary()
wallet.openPaymentSetup()

3、设置商品信息,并唤起 ApplePay 支付页面

伪代码如下,注意要点都写在 注释

let request = PKPaymentRequest()

//国家
request.countryCode = "CN"
//币种
request.currencyCode = "CNY"
//支持的网络
var networks: [PKPaymentNetwork] = [.privateLabel]
if #available(iOS 11.2, *) {
    networks.insert(.chinaUnionPay, at: 0)
}
request.supportedNetworks = networks
//商业标识符
request.merchantIdentifier = "merchant.xxxx"
//capability3DS 必须添加,在大陆 capabilityEMV 也必须添加,否则 didAuthorizePayment 方法不会调用
request.merchantCapabilities = [.capability3DS, .capabilityEMV, .capabilityCredit, .capabilityDebit]

//快递
let ship1 = PKShippingMethod(label: "顺丰", amount: .init(value: 10))
ship1.detail = "24小时送达"
ship1.identifier = "shunfeng"

let ship2 = PKShippingMethod(label: "韵达", amount: .init(value: 15))
ship2.detail = "隔天送达"
ship2.identifier = "yunda"

//快递列表
request.shippingMethods = [ship1, ship2]

//送货方式
request.shippingType = .shipping


//商品列表
let firstGoods = PKPaymentSummaryItem(label: "火锅", amount: .init(value: 0.00))
let secondGoods = PKPaymentSummaryItem(label: "青菜", amount: .init(value: 0.00))

paymentList = [firstGoods, secondGoods]

let list = showSummaryItems(with: ship1)

//添加商品列表,最后一个是总计
request.paymentSummaryItems = list

//商品附加信息,会被传到生成的 PKPaymentToken 中,可用于平台的校验
request.applicationData = "goodsId=123456".data(using: .utf8)

let payment = PKPaymentAuthorizationController(paymentRequest: request)
payment.delegate = self
payment.present(completion: nil)

4、回调处理

4.1 完成回调(取消支付、支付完成、失败都会调用)
func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
	//隐藏支付页面
    controller.dismiss(completion: nil)
}
4.2 认证回调
func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
    
    //延时,模拟平台校验订单并且对接金融机构扣款
    DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
        [unowned self] in
        
        let ret = arc4random_uniform(4) % 2 == 0
        
        if ret {
            completion(.init(status: .success, errors: nil))
            self.lbl.text = "支付成功"
        } else {
            completion(.init(status: .failure, errors: nil))
            self.lbl.text = "支付失败"
        }
    }
}
4.3 切换送货方式回调
func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didSelectShippingMethod shippingMethod: PKShippingMethod, handler completion: @escaping (PKPaymentRequestShippingMethodUpdate) -> Void) {
    
    let update = PKPaymentRequestShippingMethodUpdate(paymentSummaryItems: showSummaryItems(with: shippingMethod))
    completion(update)
}



当然,上面的这些仅仅是 ApplePay 支付的一部分,整体的流程应该是这样的:


在认证回调里,拿到 PaymentToken 之后,需要服务端根据解析的订单信息从支付供应商那里扣款,并取得扣款结果,这个过程就是 demo 里的延时的过程。之后再根据扣款的结果处理下客户端的显示支付结果,就是那个 block 回调。

这个过程可以用不同的三方sdk来处理,可以在官网找到这些内容,根据他们的文档对接就好:


本文所有代码及工具方法在这里,欢迎 Star。

官方Demo在这里

本文原地址为:www.shenhongbang.cc/ApplePayFir…