iOS9 Day-by-Day:Day 8:Apple Pay

本文翻译自iOS9 Day-by-Day系列文章之一,原文地址

这是一个系列文章,查看更多请移步目录页

Apple Pay在 iOS8 时被引入,它是一种简单便捷、安全、私密的支付方式,用于在你的app中购买实体或服务性商品,使得用户只需要简单的通过指纹授权进行交易,完成购买。

Apple Pay只能应用在某一些设备中,当前在iPhone 6,iPhone 6+, iPad Air 2 以及 iPad mini 3(当前还包括iPhone 6s, iPhone 6s+,iPad pro等所有包含指纹识别的设备),这是因为Apple Pay必须要有一个叫做安全元件(Secure Element)的专门芯片提供支持,用于存储和加密机密的信息。

你不应该使用Apple Pay这种方式去解锁你的app的任何特性,而应该用于程序内购买。Apple Pay是用于购买实体商品和服务的,例如:会员、酒店预订、订票等

为什么要使用Apple Pay

Apple Pay能大大的简化开发者的工作,你不再需要去操作和管理卡号,也不需要用户去注册账号。同时你可以移除相应的业务逻辑,你的用户也不再需要一个账户。购买和账单信息将由 Apple Pay token自动的传递给你的支付进程。这意味着一个更简单的购买流程,带来更高的转化率。

WWDC session 702Apple Pay Within Apps , Nick Shearer 介绍了一些 Apple Pay 在美国的不同商业交易中超高转化率的统计数据。

Stubhub 发现使用 Apple Pay 的客户的转换率超过传统客户 20%。

OpenTable在集成 Apple Pay 后转换率增长了50%

Staples 发现使用 Apply Pay 后,转换率增长了109%

创建一个简单的商店应用(Store App)

我们将创建一个包含商店的简单应用,并且展示如何使用Apple Pay 去处理我们的交易,这个应用将只有一个商品,但是已经足以完整的展示如何创建和开始使用Apple Pay

这是我们将要去构建的效果,如图所见,当用户点击“购买”按钮是会显示一个Apple Pay的表单

授权Apple Pay (Enabling Apple Pay)

在我们编写任何代码之前,我们必须确让我们的应用有能力使用Apple Pay,一旦你创建完成一个新的工程,打开项目设置,找到capabilities 标签

enabling apple pay 1
enabling apple pay 1

你应该能够在 capabilities 里看到 Apple Pay (注:Apple Developer Program members 才能看到),把状态设置为开启。你将被要求选择一个开发团队的账号。然后希望Xcode能都为你完成所有设置,并且Apple Pay能够使用。

我们必须要添加一个 Merchant ID,以便 Apple 知道如何去为当前付款信息编码,点击在Merchant ID区域出现的添加按钮,填写你的唯一的Merchant ID。在这个例子中我们使用merchant.com.shinobistore.appleplay

enabling apple pay 2
enabling apple pay 2

使用 Apple Pay

现在我们已经配置完成并且拥有权限,我们要开始搭建 UI ,以便让用户可以购买产品和支付。打开 storyboard 添加一些UI,展示可支付的商品。

我们刚刚创建的UI界面仅仅包括了一个带有标题、价格和描述文本的图片。对我们的Demo来说这并不是重点,我们需要添加一个按钮,我们把它添到视图的下面。我们要添加的按钮是一个 PKPaymentButton, 这个在 iOS 8.3 时引入。这个按钮是本地化的,在能够使用Apple Pay的时候提供用户标准的视觉引导。因此,苹果强力推荐使用这个按钮来启动 Apple Pay 的支付页面

这个按钮有三个显示的样式:

WhiteWhiteOutlineBlack

它同样有两种不同的按钮类型

PlainBuy

有几种不同的方式可以设置按钮的样式。不幸的是,当前还不支持在Interface Builder中添加这个类型的按钮,因此打开ViewController.swift 并且重载(override)viewDidLoad方法

override func viewDidLoad() {
super.viewDidLoad()

    let paymentButton =     PKPaymentButton(type:.Buy, style:.Black)
    paymentButton.translatesAutoresizingMaskIntoConstraints = false
    paymentButton.addTarget(self, action: "buyNowButtonTapped", forControlEvents: .TouchUpInside)
    bottomToolbar.addSubview(paymentButton)

    bottomToolbar.addConstraint(NSLayoutConstraint(item: paymentButton, attribute: .CenterX, relatedBy: .Equal, toItem: bottomToolbar, attribute: .CenterX, multiplier: 1, constant: 0))
    bottomToolbar.addConstraint(NSLayoutConstraint(item: paymentButton, attribute: .CenterY, relatedBy: .Equal, toItem: bottomToolbar, attribute: .CenterY, multiplier: 1, constant: 0))
}

这就是我们全部需要做的。它可以自适应,本质上我们真正在意的就是这个按钮。 当我们点击了按钮后,在 buyNowButtonTapped 方法里,我们启动购买进程。

当界面搭建好后,我们必须首先对Apple Pay 的一些类的概念有好的理解

PKPaymentSummaryItem

这个 Object 是在Apple Pay交易表单上的一个简单条目,他可以使商品,也可以是税,或者运费。

PKPaymentRequest

一个 PKPaymentRequest 包含(combines)了一些你想要的关于用户支付的一些条目,包括例如你的merchant identifiercountry codecurrency code

PKPaymentAuthorisationViewController

PKPaymentAuthorisationViewController 提示用户授权 PKPaymentRequest,并且选择投递地址和有效的支付卡

PKPayment

PKPayment包括需要处理的交易的信息,并且包含需要显示的确认信息。

所有的这些类都包含在 PassKit (因此以PK作为前缀)之下,所以我们需要去引入这个框架,在你需要用到 Apple Pay 的地方

设置 Payment

设置payment的第一步:创建一个 PKPaymentRequest 步骤如下:

func buyNowButtonTapped(sender: UIButton) {

// Networks that we want to accept.
let paymentNetworks = [PKPaymentNetworkAmex,
    PKPaymentNetworkMasterCard,
    PKPaymentNetworkVisa,
    PKPaymentNetworkDiscover]

我们需要做的第一件事是创建一个数组用于存储可接受的多种支付网络,它确定了哪些类型的卡,是我们想要允许使用的。

if PKPaymentAuthorizationViewController.canMakePaymentsUsingNetworks(paymentNetworks) {

然后我们要检测,当前设备是否可以处理这些类型的交易。canMakePaymentsUsingNetworks 是PKPaymentAuthorizationViewController 中标准的检测设备是否有交易处理能力的方法

let request = PKPaymentRequest()

    // This merchantIdentifier should have been created for you in Xcode when you set up the ApplePay capabilities.
    request.merchantIdentifier = "shinobistore.com.day-by-day."
    request.countryCode = "US" // Standard ISO country code. The country in which you make the charge.
    request.currencyCode = "USD" // Standard ISO currency code. Any currency you like.
    request.supportedNetworks = paymentNetworks
    request.merchantCapabilities = .Capability3DS // 3DS or EMV. Check with your payment platform or processor.

如果我们能够在当前设备上处理交易,那么我们将通过上面的代码创建一个支付请求,每一行后面的注释解释了每一行的作用.

// Set the items that you are charging for. The last item is the total amount you want to charge.
    let shinobiToySummaryItem = PKPaymentSummaryItem(label: "Shinobi Cuddly Toy", amount: NSDecimalNumber(double: 22.99), type: .Final)
    let shinobiPostageSummaryItem = PKPaymentSummaryItem(label: "Postage", amount: NSDecimalNumber(double: 3.99), type: .Final)
    let shinobiTaxSummaryItem = PKPaymentSummaryItem(label: "Tax", amount: NSDecimalNumber(double: 2.29), type: .Final)
    let total = PKPaymentSummaryItem(label: "Total", amount: NSDecimalNumber(double: 29.27), type: .Final)

然后,正如上面代码显示那样,你现在必须设置你想在Apple Pay表单中的显示的产品,他们会用在下面的这一行paymentSummaryItems

request.paymentSummaryItems = [shinobiToySummaryItem, shinobiPostageSummaryItem, shinobiTaxSummaryItem, total]

这个 API 有趣的一点是,在数组最后一个,是用户实际需要支付的金额。它在表单的最后,会特别表示出来。在这里是总价。如果,你希望现实更多的条目,你需要手动计算并且在列表最后,添加一个PKPaymentSummaryItem

// Create a PKPaymentAuthorizationViewController from the request
    let authorizationViewController = PKPaymentAuthorizationViewController(paymentRequest: request)

    // Set its delegate so we know the result of the payment authorization
    authorizationViewController.delegate = self

    // Show the authorizationViewController to the user
    presentViewController(authorizationViewController, animated: true, completion: nil)

最后,为请求创建一个PKPaymentAuthorizationViewController,设置代理并且将它显示给用户

现在我们需要确定我们是否实现了PKPaymentAuthorizationViewController 的代理方法,我们需要去实现这些方法,来让我们知道交易是否生成,并在得到授权或完成后,响应相关事件。

paymentAuthorizationViewController:didAuthorizePayment 方法中我们需要用 provider 去处理支付数据,然后返回状态给我们的应用,返回的 PKPayment 拥有一个 PKPaymentToken 的属性,我们需要发送给支付的 provider.用于编码和私钥加密的

func paymentAuthorizationViewController(controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, completion: (PKPaymentAuthorizationStatus) -> Void) {

paymentToken = payment.token

// You would typically use a payment provider such as Stripe here using payment.token
completion(.Success)

// Once the payment is successful, show the user that the purchase has been successful.
self.performSegueWithIdentifier("purchaseConfirmed", sender: self)
}

paymentAuthorizationViewControllerDidFinish 方法中,我们简单的dismiss我们的ViewController。

func paymentAuthorizationViewControllerDidFinish(controller: PKPaymentAuthorizationViewController) {
self.dismissViewControllerAnimated(true, completion: nil)
}

这就是全部。显然,在现实世界中,你可能还需要把支付的 token 发送给支付服务提供者,例如 Stripe,但这个超出本教程的范围。我们还添加了一个 controller 来显示收据。在这个例子中,仅显示支付 token 的 transactionIdentifier。这是一个被格式化好的的全球唯一的一个字符串,可以用来做收据的验证。

延伸阅读

关于 Apple Pay 的更多信息,我推荐观看 WWDC session 702,Apple Pay Within Apps,视频相当长,但如果你对将Apple Pay集成到你的应用中很感兴趣,那它一定是值得观看。这个 session 中间有一段,讲了 Apple Pay 是如何改进交易处理的用户体验的。

另外,在苹果开发者网站上,还有一个文档 guide to Apple Pay。如果你想要在应用中集成 Apple Pay 的话,它是非常值得一读的。

最后,别忘了,如果你想观看我们在 Demo 中创建的项目的话,可以在 Github 上找到他。

这是一个系列文章,查看更多请移步目录页

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容