【iOS】Apple Pay 开发指南(一)

By https://LeoDev.me

在发布近两年、历经各种周折之后,苹果公司的 Apple Pay 移动支付服务终于在2016年2月18日来到了中国大陆。
对中国用户来说,移动支付其实已经不是什么陌生事物,抢红包和支付宝早完成用户启蒙。但与这两者有区别的是,Apple Pay 只是苹果搭建的一个支付服务,它链接银行、店面及用户,但又不像支付宝那样把钱存在自己这,这是银联为何会疯狗一样帮推的原因之一。

作为开发者,这事还是值得高兴会的,高大上啊,不过代价是又要学习新知识了。。。
不过还好,看了看 Apple Pay 的文档,发现事情并没有那么可悲,这玩意还是比较容易搞的。
Swift 来一发好了。

开发步骤

  1. 新建项目,打开 Apple Pay 的开关:

    By https://LeoDev.me

  2. 这时你会发现 Merchant IDs 下面什么都没有,正常,点 + 号,按提示创建一个 Merchant ID:

    By https://LeoDev.me

    当然你也可以前往 开发者中心 创建:

    By https://LeoDev.me

  3. 创建好了就是这个样子的:

    By https://LeoDev.me

  4. 打开 ViewController.swift,开心地敲代码吧~
    完整代码如下,注释比较齐全:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    //
    // ViewController.swift
    // ApplePayDemo
    //
    // Created by Leo on 16/3/4.
    // Copyright © 2016年 Leo. All rights reserved.
    //

    import UIKit
    import PassKit

    class ViewController: UIViewController, PKPaymentAuthorizationViewControllerDelegate {

    override func viewDidLoad() {
    super.viewDidLoad()

    let iconImage = UIImage.init(named: "Apple_Pay_Payment_Mark")

    let payBtn = UIButton.init(frame: CGRectMake((UIScreen.mainScreen().bounds.size.width - 100.0) * 0.5, 200, 100.0, 64.0))
    payBtn.setBackgroundImage(iconImage, forState: UIControlState.Normal)
    payBtn.addTarget(self, action: "payBtnClicked", forControlEvents: UIControlEvents.TouchUpInside)
    view.addSubview(payBtn)
    }

    /**
    点击了支付按钮
    */
    func payBtnClicked() {

    // 检查用户是否支持 Apple Pay
    if !PKPaymentAuthorizationViewController.canMakePayments() {
    print("设备不支持 Apple Pay")
    let alertView = UIAlertView.init(
    title: "设备不支持 Apple Pay",
    message: nil,
    delegate: nil,
    cancelButtonTitle: "确定")
    alertView.show()
    return
    }

    // 检查是否支持用户卡片
    var paymentNetworks: [String]!
    if #available(iOS 9.2, *) {
    paymentNetworks = [
    PKPaymentNetworkVisa,
    PKPaymentNetworkMasterCard,
    PKPaymentNetworkChinaUnionPay] // 银联卡要求 iOS 9.2 +
    } else {
    paymentNetworks = [
    PKPaymentNetworkVisa,
    PKPaymentNetworkMasterCard]
    }
    if !PKPaymentAuthorizationViewController.canMakePaymentsUsingNetworks(paymentNetworks) {
    print("不支持的卡片类型。目前仅支持 Visa、MasterCard、中国银联卡。")
    let alertView = UIAlertView.init(
    title: "不支持的卡片类型",
    message: "目前仅支持 Visa、MasterCard、中国银联卡。",
    delegate: nil,
    cancelButtonTitle: "确定")
    alertView.show()
    return
    }

    // 创建付款请求
    let request = PKPaymentRequest()
    request.countryCode = "CN"
    request.currencyCode = "CNY"
    request.supportedNetworks = paymentNetworks
    request.merchantIdentifier = "merchant.me.leodev.ApplePayDemo"
    request.merchantCapabilities = PKMerchantCapability.Capability3DS

    // 添加付款项目
    let item1 = PKPaymentSummaryItem.init(label: "美酒", amount: NSDecimalNumber.init(double: 99.99))
    let item2 = PKPaymentSummaryItem.init(label: "咖啡", amount: NSDecimalNumber.init(double: 29.99))
    let item3 = PKPaymentSummaryItem.init(label: "小费", amount: NSDecimalNumber.init(double: 19.99))
    let item4 = PKPaymentSummaryItem.init(label: "超哥", amount: NSDecimalNumber.init(double: 149.97))
    request.paymentSummaryItems = [item1, item2, item3, item4]

    // 初始化 PKPaymentAuthorizationViewController 并显示
    let authViewController = PKPaymentAuthorizationViewController.init(paymentRequest: request)
    authViewController.delegate = self
    presentViewController(authViewController, animated: true, completion: nil)
    }

    // MARK: - PKPaymentAuthorizationViewControllerDelegate

    /**
    处理交易数据,并把状态返回给应用

    - parameter controller: 当前的 PKPaymentAuthorizationViewController
    - parameter payment: payment
    - parameter completion: 返回
    */
    func paymentAuthorizationViewController(controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, completion: (PKPaymentAuthorizationStatus) -> Void) {

    let paymentToken = payment.token
    print("\(paymentToken)")

    // 超哥交易成功了
    completion(.Success)

    // 交易成功应该 push 个交易成功的界面什么的
    // ...
    }

    /**
    支付完成,隐藏 PKPaymentAuthorizationViewController

    - parameter controller: 当前的 PKPaymentAuthorizationViewController
    */
    func paymentAuthorizationViewControllerDidFinish(controller: PKPaymentAuthorizationViewController) {
    self.dismissViewControllerAnimated(true, completion: nil)
    }
    }
  5. 收工。

想想支付宝和微信支付, Pay 真 TM 简单啊。。。

源码GitHub

示例

By https://LeoDev.me

By https://LeoDev.me

By https://LeoDev.me

附一 currencyCode

ADP,
AED,
AFA,
AFN,
ALK,
ALL,
AMD,
ANG,
AOA,
AOK,
AON,
AOR,
ARA,
ARL,
ARM,
ARP,
ARS,
ATS,
AUD,
AWG,
AZM,
AZN,
BAD,
BAM,
BAN,
BBD,
BDT,
BEC,
BEF,
BEL,
BGL,
BGM,
BGN,
BGO,
BHD,
BIF,
BMD,
BND,
BOB,
BOL,
BOP,
BOV,
BRB,
BRC,
BRE,
BRL,
BRN,
BRR,
BRZ,
BSD,
BTN,
BUK,
BWP,
BYB,
BYR,
BZD,
CAD,
CDF,
CHE,
CHF,
CHW,
CLE,
CLF,
CLP,
CNX,
CNY,
COP,
COU,
CRC,
CSD,
CSK,
CUC,
CUP,
CVE,
CYP,
CZK,
DDM,
DEM,
DJF,
DKK,
DOP,
DZD,
ECS,
ECV,
EEK,
EGP,
EQE,
ERN,
ESA,
ESB,
ESP,
ETB,
EUR,
FIM,
FJD,
FKP,
FRF,
GBP,
GEK,
GEL,
GHC,
GHS,
GIP,
GMD,
GNF,
GNS,
GQE,
GRD,
GTQ,
GWE,
GWP,
GYD,
HKD,
HNL,
HRD,
HRK,
HTG,
HUF,
IDR,
IEP,
ILP,
ILR,
ILS,
INR,
IQD,
IRR,
ISJ,
ISK,
ITL,
JMD,
JOD,
JPY,
KES,
KGS,
KHR,
KMF,
KPW,
KRH,
KRO,
KRW,
KWD,
KYD,
KZT,
LAK,
LBP,
LKR,
LRD,
LSL,
LSM,
LTL,
LTT,
LUC,
LUF,
LUL,
LVL,
LVR,
LYD,
MAD,
MAF,
MCF,
MDC,
MDL,
MGA,
MGF,
MKD,
MKN,
MLF,
MMK,
MNT,
MOP,
MRO,
MTL,
MTP,
MUR,
MVP,
MVR,
MWK,
MXN,
MXP,
MXV,
MYR,
MZE,
MZM,
MZN,
NAD,
NGN,
NIC,
NIO,
NLG,
NOK,
NPR,
NZD,
OMR,
PAB,
PEI,
PEN,
PES,
PGK,
PHP,
PKR,
PLN,
PLZ,
PTE,
PYG,
QAR,
RHD,
ROL,
RON,
RSD,
RUB,
RUR,
RWF,
SAR,
SBD,
SCR,
SDD,
SDG,
SDP,
SEK,
SGD,
SHP,
SIT,
SKK,
SLL,
SOS,
SRD,
SRG,
SSP,
STD,
SUR,
SVC,
SYP,
SZL,
THB,
TJR,
TJS,
TMM,
TMT,
TND,
TOP,
TPE,
TRL,
TRY,
TTD,
TWD,
TZS,
UAH,
UAK,
UGS,
UGX,
USD,
USN,
USS,
UYI,
UYP,
UYU,
UZS,
VEB,
VEF,
VND,
VNN,
VUV,
WST,
XAF,
XAG,
XAU,
XBA,
XBB,
XBC,
XBD,
XCD,
XDR,
XEU,
XFO,
XFU,
XOF,
XPD,
XPF,
XPT,
XRE,
XSU,
XTS,
XUA,
XXX,
YDD,
YER,
YUD,
YUM,
YUN,
YUR,
ZAL,
ZAR,
ZMK,
ZMW,
ZRN,
ZRZ,
ZWL,
ZWR,
ZWD

附二 countryCode

AD,
AE,
AF,
AG,
AI,
AL,
AM,
AO,
AQ,
AR,
AS,
AT,
AU,
AW,
AX,
AZ,
BA,
BB,
BD,
BE,
BF,
BG,
BH,
BI,
BJ,
BL,
BM,
BN,
BO,
BQ,
BR,
BS,
BT,
BV,
BW,
BY,
BZ,
CA,
CC,
CD,
CF,
CG,
CH,
CI,
CK,
CL,
CM,
CN,
CO,
CR,
CU,
CV,
CW,
CX,
CY,
CZ,
DE,
DJ,
DK,
DM,
DO,
DZ,
EC,
EE,
EG,
EH,
ER,
ES,
ET,
FI,
FJ,
FK,
FM,
FO,
FR,
GA,
GB,
GD,
GE,
GF,
GG,
GH,
GI,
GL,
GM,
GN,
GP,
GQ,
GR,
GS,
GT,
GU,
GW,
GY,
HK,
HM,
HN,
HR,
HT,
HU,
ID,
IE,
IL,
IM,
IN,
IO,
IQ,
IR,
IS,
IT,
JE,
JM,
JO,
JP,
KE,
KG,
KH,
KI,
KM,
KN,
KP,
KR,
KW,
KY,
KZ,
LA,
LB,
LC,
LI,
LK,
LR,
LS,
LT,
LU,
LV,
LY,
MA,
MC,
MD,
ME,
MF,
MG,
MH,
MK,
ML,
MM,
MN,
MO,
MP,
MQ,
MR,
MS,
MT,
MU,
MV,
MW,
MX,
MY,
MZ,
NA,
NC,
NE,
NF,
NG,
NI,
NL,
NO,
NP,
NR,
NU,
NZ,
OM,
PA,
PE,
PF,
PG,
PH,
PK,
PL,
PM,
PN,
PR,
PS,
PT,
PW,
PY,
QA,
RE,
RO,
RS,
RU,
RW,
SA,
SB,
SC,
SD,
SE,
SG,
SH,
SI,
SJ,
SK,
SL,
SM,
SN,
SO,
SR,
SS,
ST,
SV,
SX,
SY,
SZ,
TC,
TD,
TF,
TG,
TH,
TJ,
TK,
TL,
TM,
TN,
TO,
TR,
TT,
TV,
TW,
TZ,
UA,
UG,
UM,
US,
UY,
UZ,
VA,
VC,
VE,
VG,
VI,
VN,
VU,
WF,
WS,
YE,
YT,
ZA,
ZM,
ZW

联系与捐赠

  • Mail: echo bGVvZGF4aWFAZ21haWwuY29tCg== | base64 -D
  • GitHub: iTofu
  • 如果你想对我的开发或是开源项目进行支持捐助,请扫描下方二维码,谢谢!👇

    LEO

🍭 支持一根棒棒糖!