[nodejs][stripe] stripe を node で使う(subscription 定期支払いの作成)

customer が登録されている前提で subscription (定期支払いプラン)を作ってみましょう。
customer の登録方法は下記 URL で説明してますので、そちらも合わせて読んでくださいまし。
[stripe を node で使う(customer 情報の登録)](http://qiita.com/wokamoto/items/0be8471d38044ada9209)

# 参考URL

- [API Reference](https://stripe.com/docs/api/node#intro)
- [Subscriptions Quickstart](https://stripe.com/docs/subscriptions/quickstart)
- [Upgrading and Downgrading Plans](https://stripe.com/docs/subscriptions/upgrading-downgrading)
- [Stripe Subscription （定期支払い）101 - Part 1](http://qiita.com/y_toku/items/235b5e7ee00792edcbbf)
- [日本正式リリースしたStripeを使ってサブスクリプション型決済システムを実装する](http://qiita.com/tady/items/7617e62b2a5402ebd0fb)

# 使い方
サンプルコードはエラー処理甘いかもなので、適宜修正してくださいまし。

## 定期支払プランの作成
定期支払いプランを作成してみましょう。簡単です。
毎月 1,500円の定期支払いプランは、こんな感じで作れます。

```js:create-stripe-plan.js
var stripe = require('stripe')('STRIPE_API_KEY_HERE');
var params = {
  amount: 1500,        // 金額
  interval: "month",   // インターバル
  name: "Micro Plan",  // プラン名称
  currency: "jpy",     // 通貨
  id: "micro"          // プランID
};

stripe.plans.create(params, function(err, plan) {
  console.log(plan);
});
```

```json:example_response
{
  "id": "micro",
  "object": "plan",
  "amount": 1500,
  "created": 1488801118,
  "currency": "jpy",
  "interval": "month",
  "interval_count": 1,
  "livemode": false,
  "metadata": {
  },
  "name": "Micro Plan",
  "statement_descriptor": null,
  "trial_period_days": null
}
```

Plan なんて一回しか作らんのにコード書かなくてもええやんとか思った人は、stripe のダッシュボードからも作成できます。
でも、stripe のダッシュボードでは plan 情報の csv での export はできるけど、import はできないので、test 環境と live 環境両方に作るのがしんどいから、スクリプトで書いておいたほうがいいよ。

## 定期支払プランを customer に紐付け
お客さんが定期支払プランを契約してくれると、初回請求日から定期的に(plan に設定されている interval に沿って)お客さんのクレジットカードに請求してくれます。

```js:create-stripe-subscription.js
var stripe = require('stripe')('STRIPE_API_KEY_HERE');
var params = {
    customer: 'cus_xxxxxxxxxxxxxx',    // stripe の customer id
    plan: 'micro',                     // stripe.plans.create() で作成した plan の ID
    tax_percent: 8.0                   // 消費税率
};

// プランの存在確認（別にしなくてもいいかもだけど、一応）
stripe.plans.retrieve(params.plan, function(err, plan) {
    if (err) {
        console.log(err);
    } else {
        // サブスクリプションの作成
        stripe.subscriptions.create(params, function(err, subscription){
            console.log(subscription);
        });
    }
});
```

```json:example_response
{
  "id": "sub_xxxxxxxxxxxxxx",
  "object": "subscription",
  "application_fee_percent": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "created": 1488879267,
  "current_period_end": 1491557667,
  "current_period_start": 1488879267,
  "customer": "cus_xxxxxxxxxxxxxx",
  "discount": null,
  "ended_at": null,
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_xxxxxxxxxxxxxxxxxxxxxxxx",
        "object": "subscription_item",
        "created": 1488879268,
        "plan": {
          "id": "micro",
          "object": "plan",
          "amount": 1500,
          "created": 1488801118,
          "currency": "jpy",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "name": "Micro",
          "statement_descriptor": null,
          "trial_period_days": null
        },
        "quantity": 1
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_xxxxxxxxxxxxxx"
  },
  "livemode": false,
  "metadata": {
  },
  "plan": {
    "id": "micro",
    "object": "plan",
    "amount": 1500,
    "created": 1488801118,
    "currency": "jpy",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "name": "Micro",
    "tax_percent": 8,
    "statement_descriptor": null,
    "trial_period_days": null
  },
  "quantity": 1,
  "start": 1488879267,
  "status": "active",
  "tax_percent": null,
  "trial_end": null,
  "trial_start": null
}
```
subscription.id は、どっかに保存しておきましょう。
この後、定期支払いのプラン変更とか解約とかするときに使います。

## 定期支払プランの変更
毎月1,500円の Micro プランから、毎月3,000円の Small プランに契約変更したい時は ```subscriptions.update()``` で。
差額が発生する場合は、次回請求時に日割りで請求(or 相殺)を勝手にやってくれます。

```js:update-stripe-subscription.js
var stripe = require('stripe')('STRIPE_API_KEY_HERE');
var subscription_id = 'sub_xxxxxxxxxxxxxx';
var params = {
    plan: 'small',                     // stripe.plans.create() で作成した plan の ID
    tax_percent: 8.0                   // 消費税率
};

// プランの存在確認
stripe.plans.retrieve(params.plan, function(err, plan) {
    if (err) {
        console.log(err);
    } else {
        // サブスクリプションの更新
        stripe.subscriptions.update(subscription_id, params, function(err, subscription){
            console.log(subscription);
        });
    }
});
```

response は subscriotion オブジェクトですが、create した時と同様なので割愛。

## 定期支払いプランのキャンセル
残念ながら契約解除となった時の解約処理は、こんな感じ

```js:remove-stripe-subscription.js
var stripe = require('stripe')('STRIPE_API_KEY_HERE');
var subscription_id = 'sub_xxxxxxxxxxxxxx';
var customer_id = 'cus_xxxxxxxxxxxxxx';

// サブスクリプションの存在確認
stripe.subscriptions.retrieve(subscription_id, function(err, subscription) {
    if (err) {
        // サブスクリプション探したけど、なんかエラーあったで
        console.log(err);
    } else if (subscription.customer != customer_id ) {
        // 別のお客さんのサブスクリプションやで、勝手に解約しないで
    } else {
        // サブスクリプションの解約
        stripe.subscriptions.del(subscription_id, function(err,confirmation){
            console.log(confirmation);
        });
    }
});
```

## お客さんが契約してくれてる定期支払いプランの一覧取得
有効な定期支払いプランだけ取るには、こんな感じで

```js:list-stripe-subscriptions.js
var stripe = require('stripe')('STRIPE_API_KEY_HERE');
var params = {
    customer: 'cus_xxxxxxxxxxxxxx',
    status: 'active'
};
stripe.subscriptions.list(params, function(err, subscriptions){
    console.log(subscriptions);
});
```

```json:example_response
{
  "object": "list",
  "url": "/v1/subscriptions",
  "has_more": false,
  "data": [
    {..(subscription)..},
    {...}
  ]
}
```