iOS アプリの決済周りを調べてみたのでメモ。
iOS アプリでお金を払うということ
iOS アプリからの支払いについては「Apple に3割もっていかれる」というぼんやりしたイメージしかなったのですが調べてみると、
In-App Purchaseを使用して販売可能なもの
-
コンテンツ
雑誌、写真、アートワークなどのデジタルコンテンツまたはデジタルアセット
-
アプリケーションの機能
既に配信済みのアプリケーションでロックされている動作の解除や機能の拡張を行います。
-
サービス
音声の転送などの1回限りのサービス、またはデータのコレクションへのアクセスなどの継続するサービスに対して、ユーザに支払いを求めます。
In-App Purchaseを使用して販売できないもの
- 実物の商品やサービス
アプリケーション内でユーザに実物の商品やサービスを購入してもらうには、
クレジットカードや支払いサービスなどの別の支払いメカニズムを使用してください。
参考:https://developer.apple.com/jp/documentation/StoreKitGuide.pdf
EC など実物を売る場合は In-App Purchase は使えない
物販するアプリなどを作る場合は自前で支払いする仕組みを用意しないといけないとのこと。
そこで調べたのが WebPay というサービスでREST API でクレジットカードによる決済が簡単に導入できるらしい。
iOS 向けにもライブラリも公開されています。
Webpay による決済の流れ
おおまかには下記のような感じ。
- ユーザにクレジットカード情報を入力してもらう
- Webpay にその情報を送り、token を生成してもらう
- token を使って決済(charge)を行う
流れはこんな感じなのですが、iOS 向けのサンプルコードが古くて動かなかったので自分で作ってみた。
Setup
Webpay にログインして公開鍵と非公開鍵を取得。公開鍵は Webpay ライブラリに渡します。非公開鍵は Webpay の REST API を呼び出す際に Basic 認証のユーザーにセットします。
WPYTokenizer.setPublicKey(WebpayClient.publicKey)
Token の取得
Webpay にクレジットカード情報を渡し、その後アプリ側では代わりに Token を使います。クレジットカード情報を保持しなくていいので楽ですね。
クレジットカードの入力フォームが Webpay ライブラリに含まれており、 WPYPaymentViewController を呼び出すと下記のようなフォームが簡単に使うことができます。
クレジットカードを入力し、「カードで支払う」ボタンをタップすると Token が生成され、結果が callback で渡されます。
let paymentViewController = WPYPaymentViewController(priceTag: "¥350", card: card) { [unowned self] (viewController, token, error) -> Void in
if let newError = error {
// エラー処理
} else {
// ここで Token を受け取る
// when transaction is complete
viewController.setPayButtonComplete()
viewController.dismissAfterDelay(2.0)
}
}
カード決済
Token を使ってカード決済を行います。(Token は一度しか使えません。このやり方だと決済の度にクレジットカードを入力してもらわないといけません。実際に運用を見据えた場合は Token を使ってユーザーを生成する方法を使います。)
キー | 意味 |
---|---|
currency | 通貨 |
card | 生成した Token |
amount | 金額 |
capture | 実決済するかどうか |
決済 API は Alamofire を使って呼び出します。パラメータの capture がポイントで、公式ドキュメントによると、
すぐに実売上にするか、仮売上として後で実売上化するかを指定します。falseの場合に与信のみが行われ、後で「仮売上の実売上化」をすることで実売上化できます。
とあります。
参考:https://webpay.jp/docs/api#charge_create
物販などで、
- 購入された時点で仮売上
- 商品を発送した時点で実売上(実際に決済を行う)
という使い方になるのではないかと思います。
いきなり実売上にすることもできるようなのでここでは capture = true で呼び出してみました。
非公開鍵を使って認証をしています。
class func charge(amount: Int, token: String, handler: ((Bool) -> Void)) {
let param: [String : AnyObject] = ["amount": amount,
"currency" : "jpy",
"capture" : true,
"card" : token]
Alamofire.request(.GET, "https://api.webpay.jp/v1/charges", parameters: param, encoding: .URL, headers: ["Authorization": "Bearer \(WebpayClient.secretKey)"])
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
handler(response.result.isSuccess)
}
}
CardIO を使ってクレジットカード情報を読み取る
PayPal が出してるライブラリに CardIO というものがあり、クレジットカード情報を読み込んでくれます。
#エンボス(凹凸)加工がないカードはうまく読み取れないかもしれません
使い方は簡単で、
- CardIOPaymentViewController を呼び出す
- クレジットカードをかざす
- CardIOPaymentViewControllerDelegate で結果が渡される
となります。
CardIOPaymentViewController の呼び出し
func onCameraTapped(sender: UIBarButtonItem) {
let cardIOVC = CardIOPaymentViewController(paymentDelegate: self)
cardIOVC.modalPresentationStyle = .FormSheet
presentViewController(cardIOVC, animated: true, completion: nil)
}
結果の受け取り
// MARK: CardIOPaymentViewControllerDelegate
func userDidCancelPaymentViewController(paymentViewController: CardIOPaymentViewController!) {
paymentViewController?.dismissViewControllerAnimated(true, completion: nil)
}
func userDidProvideCreditCardInfo(cardInfo: CardIOCreditCardInfo!, inPaymentViewController paymentViewController: CardIOPaymentViewController!) {
if let info = cardInfo {
// ここで情報を受け取る
card.number = info.cardNumber
card.expiryMonth = WPYMonth(rawValue: info.expiryMonth)!
card.expiryYear = info.expiryYear
card.cvc = info.cvv
// 受け取った情報を WebPay のフォームに渡す
form.removeFromSuperview()
form = WPYCardFormView(frame: cardBaseView.bounds, card: card)
form.delegate = self
cardBaseView.addSubview(form)
}
paymentViewController?.dismissViewControllerAnimated(true, completion: nil)
}
CardIO でのクレジットカード情報の読み取り
WebPay が公開しているデモビデオがありました、こんな感じでクレジットカードが読み取れます。
サンプルコード
今回説明したサンプルプロジェクト一式はこちらです。
サンプルコードはこちら。
WebPay でとても簡単に決済が導入できそうです。