SPIKEのREST APIを操作するPHPライブラリを作った

[SPIKE](https://spike.cc)は非常に低料金 (※) でクレジットカード決済が可能な国内の決済サービスプロバイダです。比較的新しいサービスですが、安いだけでなく会員登録してすぐ利用可能な手軽さも売りの1つのようですね。

決済の方法としては、JavaScript SDKにより生成される決済画面で購入者にカード情報を入力して貰い（クライアントサイド) 、それで得たカードトークンを用いてREST APIで課金を行う（サーバサイド) 、と言った流れになります。

そこでREST API用のSDKを探してみたところ、Rubyのgemはいくつか見つかりましたが、PHPには無さそうなので作ってみました。（公式がPHP用のサンプルを公開していますが、cURLを直接操作するだけの物でした) 

まだBETA版ですが、[GitHub](https://github.com/issei-m/spike-php)に公開＆[Packgist](https://packagist.org/packages/issei-m/spike-php)で配信しています。なお、PHPは5.4以降が必須となっています。

※ フリープランは100万円/月まで無料（以降は4.0%+30円) 、ビジネスプレミアムプランは1000万円/月まで無料（以降は2.5%+30円) 。（2015年1月19日時点) 

## 試してみる

Composerを使ってインストールします。

```
$ composer require issei-m/spike-php
```

インストール後は、 `Spike`オブジェクトをAPIの秘密鍵を使って初期化します。このオブジェクトを使って、全APIにアクセスすることができます:

```php
$secret = 'sk_test_xxxxxxxxxxxxxxxx';
$spike  = new \Issei\Spike\Spike($secret);
```

### 課金を行う

新しく課金を行う場合は、`ChargeRequest`オブジェクトを作って課金内容の設定を行い、`Spike::charge()`に渡します。課金に成功すると、このメソッドはSPIKEから返却された課金情報（固有のIDなど) を課金オブジェクト（`Charge`クラス) に格納して返します:

```php
// SPIKE Checkout (クライアントサイド) で取得した値を格納する。
$token = new Issei\Spike\Model\Token('tok_xxxxxxxxxxxxxxxx');

$request = new \Issei\Spike\ChargeRequest();
$request
    ->setCard($token)
    ->setAmount(3000, 'JPY')
    ->addProduct(
        (new \Issei\Spike\Model\Product('my-product-001'))
        ->setTitle('商品A')
        ->setDescription('商品Aの説明')
        ->setPrice(3000, 'JPY')
        ->setLanguage('JA')
        ->setCount(1)
    )
;

/** @var $newCharge \Issei\Spike\Model\Charge */
$newCharge = $spike->charge($request); // 成功すると新しく作られた Charge オブジェクトが返却される
var_dump($newCharge);
```

尚、`ChargeRequest::setCard()` にはトークンオブジェクトのIDを直接文字列で指定する事も可能です:

```php
$request->setCard('tok_xxxxxxxxxxxxxxxx');
```

また、トークンオブジェクトはREST APIからも取得可能です。詳しくは[トークンの取得](#%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E5%8F%96%E5%BE%97)をご覧ください。

### 既存の課金オブジェクトを取得する

既存の課金オブジェクトの取得には、`getCharge()`または`getCharges()`メソッドを使用します。
前者は課金IDから課金オブジェクトを取得します:

```php
/** @var $charge \Issei\Spike\Model\Charge */
$charge = $spike->getCharge('20150101-123456-xxxxxxxxxx');
var_dump($charge);
```

後者はこれまで行った課金の一覧を取得します:

```php
/** @var $charges \Issei\Spike\Model\Charge[] */
$charges = $spike->getCharges(5);
var_dump($charges);
```

#### ページング

`getCharges()`の第1引数には取得する数を指定できます (デフォルトで10)。また、第2引数と第3引数に既存の課金オブジェクト (または課金オブジェクトのID) を渡すことで、ページングが可能となっています:

```php
/** @var $charges \Issei\Spike\Model\Charge[] */
$charges = $spike->getCharges(5, $chargeX, $chargeY); // $chargeX〜$chargeY間の課金一覧を取得。
var_dump($charges);
```

※引数に渡した課金オブジェクトは一覧に含まれません。

### 課金の取り消し

課金オブジェクトを `refund()`メソッドに渡すと、課金の取り消しを行う事ができます:

```php
/** @var $refundedCharge \Issei\Spike\Model\Charge */
$refundedCharge = $spike->refund($charge);
```

refund()は取り消しを行った課金の最新情報を格納した課金オブジェクトを返却します（引数に渡したオブジェクトとは別のインスタンスになります)。
また、課金オブジェクトの代わりに、課金オブジェクトのIDを文字列として直接渡す事も可能です:

```php
$spike->refund('20150101-123456-xxxxxxxxxx');
```

### トークンの取得

課金に必要なトークンオブジェクトは、SPIKE CheckoutだけでなくREST APIから直接請求が可能です (※)。その場合は、`TokenRequest`を作ってカード情報を入力し、`Spike::requestToken()`メソッドに渡します:

※2015年3月30日現在、有料オプション。詳しくは[【NEW】決済ページのUIをカスタマイズできるAPI機能とはなんですか？](https://support.spike.cc/hc/ja/articles/204252504--NEW-%E6%B1%BA%E6%B8%88%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AEUI%E3%82%92%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%81%A7%E3%81%8D%E3%82%8BAPI%E6%A9%9F%E8%83%BD%E3%81%A8%E3%81%AF%E3%81%AA%E3%82%93%E3%81%A7%E3%81%99%E3%81%8B-)を参照。

```php
$request = new \Issei\Spike\TokenRequest();
$request
    ->setCardNumber('4444333322221111')
    ->setExpirationMonth(12)
    ->setExpirationYear(19)
    ->setHolderName('Taro Spike')
    ->setSecurityCode('123')
    ->setCurrency('JPY')
    ->setEmail('test@example.jp')
;

/** @var $charge \Issei\Spike\Model\Token */
$token = $spike->requestToken($request);
```

取得したトークンオブジェクトをそのまま`charge()`に渡して新たに課金を行う事もできます:

```php
/** @var $charge \Issei\Spike\Model\Charge */
$charge = $spike->charge($token);
```

また、IDから既存のトークンオブジェクトを取得する事が可能です:

```php
/** @var $token \Issei\Spike\Model\Token */
$token = $spike->getToken('tok_xxxxxxxxxxxxxxxxxxxxxxxx');
```

## カスタマイズ

### Guzzleクライアントを使う

本ライブラリはHTTP通信にcURLを使用しますが、バージョン4.0以降の[Guzzle](https://github.com/guzzle/guzzle)がインストールされていれば、そちらを使うこともできます。その場合は`Spike`初期化時に第2引数に`GuzzleHttpClient`オブジェクトを渡せばOKです。
以下は、StreamAdapterを採用したGuzzleのクライアントの使用例です:

```php
$guzzleClient = new \GuzzleHttp\Client([
'adapter' => new \GuzzleHttp\Adapter\StreamAdapter(
new \GuzzleHttp\Message\MessageFactory()
),
]);

$client = new \Issei\Spike\Http\Client\GuzzleHttpClient($guzzleClient);
$spike = new \Issei\Spike\Spike($secret, $client);

var_dump($spike->getCharges());
```

### DateTimeのタイムゾーン

課金オブジェクトなどに使用される`DateTime`オブジェクトは、デフォルトではタイムゾーンがシステムのデフォルト値 (php.iniの`date.timezone`の値) に設定されますが、以下のようにして、好きなタイムゾーンを指定することもできます:

```php
$timeZone = new \DateTimeZone('UTC'); // 協定世界時

$objectConverterBuilder = new \Issei\Spike\Converter\RecursiveObjectFactoryConverterBuilder();
$objectConverterBuilder->setTimeZone($timeZone);
$spike = new \Issei\Spike\Spike($secret, null, $objectConverterBuilder->getConverter());
```