WebPayLiteを使ってiOSから簡単にクレジットカード決済する

## WebPayLiteというライブラリを作ってみた

こんにちは！決済大好き、きょろ(@kyoro353)こと井上恭輔です。@sowawaからバトンを受け取り、WebPayの中の人じゃない人最初のWebPayアドベントカレンダー3日目です。
毎年師走になると盛り上がるAdvent Calendar。毎年参加したい！！と思うのですが、いつも忙しさに負けてROM専に甘んじていました。今回は「今年こそは！」という気持ちと、最近自分でオープンソースのコードを書いてないなーという自戒の念を込めて、自作のライブラリネタで参加させて頂きます。初投稿です。皆様お手柔らかにお願い致します。

ということで、今回は「[WebPayLite](https://github.com/kyoro/WebPayLite)」というObjective-C向けの軽量WebPayクライアント・ライブラリを作ってみましたのでご紹介します。

![webpay.jpg](https://qiita-image-store.s3.amazonaws.com/0/956/c6bcdf3b-4754-4a6d-4846-39da69739c16.jpeg)

## WebPayLiteとは？

WebPayはRESTfulで非常に良く整備されたAPIを持つペイメントゲートウェイです。基礎的なエンジニアリングの知識があれば、HTTPアクセスやBASIC認証と言った標準的な技術を使って簡単に決済機能を実装することができます。とはいえ、毎回APIアクセス部分を書くのは大変ですし、RubyやPHPと言ったLLならまだしも、Objective-Cでエンコーディングや認証、非同期処理を含めて毎回スクラッチで実装するのは地味に面倒くさい作業です。ということで、必要最低限なWebPayの決済処理を、超手軽に実装できる軽量でシンプルなクライアント・ライブラリ「[WebPayLite](https://github.com/kyoro/WebPayLite)」を作ってみました。WebPayLiteを使うと、iPhoneやiPadアプリに、簡単に独自の決済機能を実装できます。

##WebPayLiteの特徴

WebPayLiteは次のような特徴を持つライブラリです。

### 超シンプル
WebPayLite(.h/.m)ファイルをプロジェクトにドラックして追加するだけで簡単に使えます。

### 超軽量
課金とトークン作成に対応した基本的な決済機能を提供します。View部品などもありません。

### デリゲート実装による非同期動作
すべてのリクエストは非同期に処理され、デリゲート呼び出しによって結果を取得することができます。

### 他ライブラリ非依存
単体で利用できます。URL encodeやBase64 encode、Basic認証などの実装がライブラリに含まれています。Basic認証の実装のために必要なBase64 encodeなどは標準のNSStringなどでは提供されないので、外部のカテゴリ拡張を行う[nicklockwood / Base64](https://github.com/stripe/stripe-ios/tree/master/Stripe)などを利用するのが一般的ですが、コードベース間で選択するBase64ライブラリが異なる場合にコンフリクトが発生してしまいます。WebPayLiteは独自にエンコード機能を持っているので、依存に関しての心配が不要で、クリーンなコードベースを維持できます。

### Stripe.comでも使えます
WebPayの利点の副次作用ですが、apiBaseプロパティを変更することで、Stripe.comでも利用できます。

### iOS 6.0以降推奨
WebPayLiteの利用にはARCとJSON Frameworkが必要です。5.1でも動く気がしますが、6.0以降を推奨します。

## StripeのiOSバインディングとの違い、使い所
Stripeには[iOS Binding](https://github.com/stripe/stripe-ios)があり、変更を加えれば、おそらくWebPayでも利用可能です。しかし、Stripeのバインディングは非常に高性能で、逆を返せばヘビーなライブラリです。入力用View部品なども含むので「ちょっと決済リクエストを飛ばしてみたい」と言った需要には適しません。逆に、WebPayLiteは超シンプルな実装なので、アプリ単体で全ての決済処理をハンドリングしたい需要には適しません。利用するプロジェクトの需要に合わせてご利用ください。個人的なニーズとしては、アプリ単体の実装でサービスが完結するシーンはあまり無いので、サーバサイドを含む実装であれば、WebPayLite程度の機能で結構十分だったりします。中継サーバ介せばいいじゃん的な話もありますが、webpay.jp以外に生のカード情報をあまり投げたくない時とかに便利です。

## WebPayLiteの使い方
前置きが長くなりましたが、使い方を説明します。WebPayLiteにはサンプルの[iPhoneアプリのプロジェクト](https://github.com/kyoro/WebPayLite)が付随していますので、そちらを参考にしながら読み進めて下さい。

### 1. ファイルをプロジェクトに追加します。
[WebPayLite](https://github.com/kyoro/WebPayLite)をGithubから入手して、「WebPayLite.h」と「WebPayLite.m」をあなたのプロジェクトに追加します。ツリーのルートに突っ込むだけでOK、ビルドターゲットへの設定を忘れずに！

### 2. ViewController.hに、インポート宣言とデリゲート宣言、クラス変数の定義を追加します。
決済機能を実装するViewControllerのヘッダファイルに、WebPayLiteのインポート宣言、コールバックのデリゲートを受け取るためのデリゲート宣言、WebPayLiteのインスタンスを格納するクラス変数の定義を追加してください。

```objc
#import "WebPayLite.h"

@interface ViewController : UIViewController <WebPayLiteDelegate>{
    WebPayLite *wpl;
}
```

### 3.初期化処理
ViewController.mの実装ファイル側に、初期化処理を追加します。
大抵の場合、viewDidLoadedとかに追加すれば問題ないと思います。
内容はインスタンスの作成、デリゲートの登録、WebPayの秘密鍵の登録です。
秘密鍵のハードコーディングが気になる場合は、キーチェーンなどを利用して適切に保護してください。

```objc
//WebPayLite Initialize
wpl = [[WebPayLite alloc] init];
wpl.delegate = self;
wpl.secretKey = @"YOUR_SECRET_KEY";
```

### 4.突然の課金
ここまですれば後は課金メソッドを呼ぶだけです。createChargeメソッド、createTokenメソッドでトークンの作成ができます。基本的にはWebPayのAPI呼び出し時のパラメータをそのままNSDictionaryで与えればいいだけの薄いラッパなので、[WebPayのAPIドキュメント](https://webpay.jp/docs/api)を見ながら自由に呼び出してください。カードナンバーによる課金も、トークンによる課金も、どちらも可能です。

```objc
NSDictionary *params = @{ @"card[number]" : @"4242424242424242",
                              @"card[exp_month]" : @"12",
                              @"card[exp_year]" : @"18" ,
                              @"card[cvc]" : @"123",
                              @"card[name]" : @"KYOSUKE INOUE",
                              @"amount" : @"100",
                              @"currency" : @"jpy",
                              @"description" : @"Test Charge"
                              };
[wpl createCharge:params];
```

### 5. コールバックの実装
必要に応じてWebPayLiteDelegateの各種コールバックをViewControllerに実装してください。引数として渡されるjsonはNSStringですので、NSJSONSerializationなどを使って必要なキーを読み取って下さい。戻り値なども基本的には[WebPayのAPIドキュメント](https://webpay.jp/docs/api)の通りです。参考として、WebPayLiteDelegateCompletedを受け取って課金額と課金通貨をUIAlertViewで表示するサンプルを示します。

```objc
- (void)WebPayLiteDelegateCompleted:(NSString *)jsonBody {
    NSLog(@"%@",jsonBody);
    NSDictionary *jsonObject = [NSJSONSerialization
                                JSONObjectWithData: [jsonBody 
                                    dataUsingEncoding:NSUTF8StringEncoding]
                                options: NSJSONReadingAllowFragments
                                error:nil];
    NSString *amount = [jsonObject objectForKey:@"amount"];
    NSString *currency = [jsonObject objectForKey:@"currency"];
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"Succeed!"
                          message:[NSString 
                              stringWithFormat:@"%@ %@ charged!",
                              currency,amount]
                          delegate:self
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil];
    [alert show];   
}
```

**ね！(本当に)簡単でしょ?!**

## みんなで楽しく決済！決済！
こんな感じで、いろんなプラットフォームで、思いついたらすぐに決済できる時代がやって来ました。
当たり前の事が当たり前にできる時代が、もう私達の手の届く所まで来ているのです。ワクワクしますね！[WebPayLiteはGithubで、MITライセンスにて公開中](https://github.com/kyoro/WebPayLite)です。ご自由にお使い下さい＆プルリクエスト歓迎です。どうやらこのアドベントカレンダーは深刻な人手不足とお聞きしましたので、もしかすると私も後何個か小ネタを投下するかもしれませんが、引き続きオーサーの皆様、素敵な記事をよろしくお願い致します。

次は @asonas 君です。よろしくお願いします。