Stripe初心者のための基本的な使い方（Rails編）

[株式会社TECH LUCK](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)という会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご連絡いただけますと幸いです。

# 前提

Stripeを導入するにあたりはまったところなどをまとめておきました。
これからStripeを導入する人の参考になれば幸いです。

# 事前準備
## Stripeの登録
Stirpeに登録して、APIキーを取得します。
まずは、Stripeに登録しましょう。
[Stripeの登録画面](https://dashboard.stripe.com/register)

登録が完了したら、ダッシュボードのAPIキーを表示するところにいきます。
[StripeのAPIのキーを取得する画面](https://dashboard.stripe.com/account/apikeys)

APIキーを取得しましょう。
![ダッシュボード.png](https://qiita-image-store.s3.amazonaws.com/0/92443/a37c2308-4224-dc2e-0fed-f08770721f24.png)


## RubyでStripeを使ってみる
便利なことにgemでStripeが使えるようになっています。
[gemのStripe](https://github.com/stripe/stripe-ruby)

ターミナルでgemのStripeをインストールしましょう。

```bash
gem install stripe
```

Ruby on Railsの場合は、Gemfileの中に`gem 'stripe'`を記述して`bundle install` を実行する。
Stripeを使うには、さきほど取得したAPIキーをセットします。
**テストモードで実行したい場合は、`Stripe.api_key`を`sk_test_~~~`にしてください。`sk_live_~~~`は本番のAPIキーになりますので、実際のお金が変動してしまいます。**

```ruby
require "stripe"
Stripe.api_key = "#{API_KEY}"
```

# StripeのConnectの情報の保持について
Stripeが提供している`Connect`というプラットフォーム上で支払い情報、定額課金の情報、カスタマー情報、Stripeユーザーの銀行情報など、様々な情報を保持してくれます。
この`Connect`というプラットフォームの情報と、自身のアプリケーションのデータベースの情報をうまく使い、支払い情報の管理、プランの管理、カスタマーの情報などを管理していきます。

[Connectの詳細はこちら](https://stripe.com/docs/connect)


# アカウントとカスタマーについて
Stripe側のデータベースには`Account`と`Coustomer`という2つの情報があります。
**Accountがお金を払われる人の情報で、Customerがお金を払った人の情報となっています。**
ややこしいので注意してください。


## Stripe::Account
料金が支払われる人の情報を管理しています。
`Account`の作成時に注意しなければならないのが、Accountの種類。以前は`standalone`と`managed`という2つの種類でしたが、現在は`standard`、`custom`、`express`の3つになっています。
名前の変更は以下の通りです。

| 変更前 | 変更後 |
|:-:|:-:|
| standalone | standard |
| managed | custom |
| 新たに追加（アメリカのみ） | express |

**Expressはアメリカでしか使うことができません**
本記事ではExpressを除外して話を進めます。

`Standard`、`Custom`アカウントでできることは以下の通りです。

|  | Standard | Custom |
|:-:|:-:|:-:|
| 統合方法 | OAuth | APIのみ |
| 詐欺など被害の責任の所在 | アカウントを使用しているユーザー | 自身が運営するサービス（プラットフォーム） |
| プラットフォームで決済のタイミングを指定できるか？ | 不可 | 可 |
| アカウント所有者のダッシュボードへのアクセス権限 | 可能。Stripeダッシュボードに完全にアクセスできる。 | 不可。 |
| ユーザーサポートが提供される箇所 |　自身が運営するサービス&Stripe | 自身が運営するサービス（プラットフォーム）のみ |

### Standardアカウント
`Standardアカウント`はこのアカウントを持っているユーザー（つまり、自分のサービスを利用しているユーザー）により、直接管理されるアカウントです。
ダッシュボードで支払いや入金の履歴を見ることができたり、実際の支払い処理を行うことができます。

**Standardアカウントを作成した後に、アカウント承認の作業をしないと決済などができないので注意してください。**

以下のコードでStandardアカウントを作成することができます。（認証は別です）

```ruby
# standardアカウントの作成
Stripe::Account.create(
  type: "standard", 
  country: "JP",
  email: "standard@example.com"
)
```

#### StandardアカウントのOAuth認証
詳細は以下に書いてあるので、参考にしてください。（ここはいじってないのであまりわからず、、、。）
[StripeのStandardアカウントの認証](https://stripe.com/docs/connect/standard-accounts)


### Customアカウント
`Customアカウント`は、このアカウントのユーザー（アカウントを使用しているユーザー）からほとんど見ることができません。運営しているサービス自身が責任を持って管理していくことになります。

**Customアカウントを作成した後に、アカウント承認の作業をしないと決済などができないので注意してください。**

以下のコードで`Customアカウント`を作成することができます。（認証は別です）

```ruby
Stripe::Account.create(
  type: "custom",
  country: "JP",
  email: "custom@example.com"
)
```

#### Customアカウントの認証
個人や会社に資金を払う場合は、本人確認が必要になります。
`Customアカウント`の場合、本人確認のために様々な情報を`Stripe::Account`に登録しなければいけません。

以下のように事業者情報を登録します。
※今回は個人事業者（individual）として、事業者情報を登録します。

```ruby
stripe_account_id = 'acct_~~~'
stripe_account = Stripe::Account.retrieve(stripe_account_id)

# 事業者の種類（法人 or 個人）
stripe_account.legal_entity.type = "individual" #個人

# 事業者の住所（漢字）
stripe_account.legal_entity.address_kanji.postal_code = "1234567"
stripe_account.legal_entity.address_kanji.state = "東京"
stripe_account.legal_entity.address_kanji.city = "渋谷区"
stripe_account.legal_entity.address_kanji.town = "恵比寿"
stripe_account.legal_entity.address_kanji.line1 = "1-1-1"
stripe_account.legal_entity.address_kanji.line2 = "テストビルディング101号"

# 事業者の住所（かな）
stripe_account.legal_entity.address_kana.postal_code = "1234567"
stripe_account.legal_entity.address_kana.state = "とうきょうと"
stripe_account.legal_entity.address_kana.city = "しぶやく"
stripe_account.legal_entity.address_kana.town = "えびす"
stripe_account.legal_entity.address_kana.line1 = "1-1-1"
stripe_account.legal_entity.address_kana.line2 = "てすとびるでぃんぐ101ごう"

# 事業責任者の名前（漢字）
stripe_account.legal_entity.first_name_kanji = "太郎"
stripe_account.legal_entity.last_name_kanji = "田中"

# 事業責任者の名前（かな）
stripe_account.legal_entity.first_name_kana = "たろう"
stripe_account.legal_entity.last_name_kana = "たなか"

# 事業者責任者の誕生日
stripe_account.legal_entity.dob.day = "1"
stripe_account.legal_entity.dob.month = "1"
stripe_account.legal_entity.dob.year = "2000"

# 事業責任者の性別
stripe_account.legal_entity.gender = "male"

# 事業責任者の電話番号
stripe_account.legal_entity.phone_number = "090-0000-0000"

# 受理された日付とグローバルIPアドレス
stripe_account.tos_acceptance.date = Time.now.to_i
stripe_account.tos_acceptance.ip = "192.168.0.1" #グローバルIPアドレスを入力

# Stripeに画像ファイルをアップロードするための処理
# 免許証やパスポートなどをアップロードする
verification_document = Stripe::FileUpload.create(
  {
    purpose: 'identity_document',
    file: File.new("./verification_success.png")
  },
  {
    stripe_account: stripe_account_id
  }
)

# アップロードされたドキュメントのID番号
stripe_account.legal_entity.verification.document = verification_document.id

stripe_account.save
```

認証についての詳細は以下に書いてあるので、参考にしてください。

[StripeのCustomアカウントの認証](https://stripe.com/docs/connect/identity-verification)
[StripeのCustomアカウントの本人確認のために必要な情報](https://stripe.com/docs/connect/required-verification-information)

### 注意事項
`standardアカウント`を作成する場合は、すでに同じメールアドレスで作成されてるとエラーが返ってきます。
しかし、`customアカウト`の場合は、同じメールアドレスで作成されていても、エラーは出ずに新たなアカウントが作成されます。
また、`standardアカウント`は、`external_account`の作成ができませんが、`customアカウント`の場合は作成ができます。

[StripeのAccountの種類についての公式ドキュメント](https://stripe.com/docs/connect/accounts)

## Stripe::Customer
料金を支払う人の情報を管理しています。
以下のコードで`Customer`を作成することができます。
`"cus_~~~~"`というid番号で情報を管理しています。

```ruby
Stripe::Customer.create(
  description: "Subscription ご利用",
  email: "customer@example.com",
  source: "tok_~~~" #Stripe.jsで作成した情報
)
```

# 支払いについて
支払いの方法は、1回限りの支払い（`Stripe::Charge`）と、継続的に支払いが発生する定期支払い（`Stripe::Subscription`）の2つがあります。

## Stripe::Charge
1回限りの決済の情報を管理しています。
`"ch_~~~~"`というid番号で情報を管理しています。

**カスタマー（Customer）からアプリケーション運営者に対して料金を支払う場合と、カスタマー（Customer）から他のアカウント（Account）に対して料金を送金する場合とで、違うコードを記述することになります。**

また、**カスタマー（Customer）から他のアカウント（Account）に対して料金を送金する場合にも、2種類の決済方法があります。**
そちらに関してもしっかりと理解しておかないと後々痛い目をみます。

`カスタマー（Customer）`からアプリケーション運営者に対して料金を支払う場合は以下のコードです。

```ruby
Stripe::Charge.create(
  amount: 2000,
  currency: "jpy",
  source: "tok_mastercard", #Stripe.jsで自動で付与されるカード情報のトークン
  metadata: {"order_id": "6735"}
)
```

`カスタマー（Customer）`から他の`アカウント（Account）`に対して料金を送金する場合は以下のコードです。
**これはDirect Chargeと呼ばれる決済方法です。**

```ruby
Stripe::Charge.create({
  amount: 2000,
  currency: "jpy",
  source: "tok_mastercard", #Stripe.jsで自動で付与されるカード情報のトークン
  metadata: {"order_id": "6735"}
}, stripe_account: "acct_~~~~")
```

`カスタマー（Customer）`から他の`アカウント（Account）`に対して料金を送金する場合は以下のコードです。
**これはDestination Chargeと呼ばれる決済方法です。**

```ruby
Stripe::Charge.create({
  amount: 2000,
  currency: "jpy",
  source: "tok_mastercard", #Stripe.jsで自動で付与されるカード情報のトークン
  destination: {
    amount: 800,
    account: "acct_~~~~",
  },
  metadata: {"order_id": "6735"}
})
```

**Destination Chargeは主に、Customアカウントの場合に向いていて、Direct Chargeは`Standard Account`の場合に向いているそうです。（Stripeのカスタマーサポートの人から聞きました。）**

[Direct ChargeとDestination Chargeの詳しい違いについて](https://stripe.com/docs/connect/charges)



### Stripe::Charge情報を取得する
ある特定の`Charge`情報を取得する際には、retrieveメソッドで取得します。

```ruby
stripe_charge = Stripe::Charge.retrieve("ch_~~~") #"ch_~~~"のCharge情報を取得
```

また、直近の`Charge`情報を複数件取得するには、listメソッドで取得します。（デフォルトは100になります。）

```ruby
stripe_charges = Stripe::Charge.list #直近の100件を取得
stripe_charges = Stripe::Charge.list(limit: 3) #直近の3件を取得
```

他にも、時間を指定して`Charge`情報を取得することもできます。
時間を指定する際は、`UNIX TIME`で指定するので、注意が必要です。

```ruby
start_time = Time.parse("2018-01-05 00:00:00").to_i #指定日時の開始時刻
end_time = Time.parse("2018-01-06 00:00:00").to_i #指定日時の終了時刻

stripe_charges = Stripe::Charge.list({
    created: {gte: start_time, lte: end_time}
  },
  stripe_account: "acct_~~~"
)
```


### 注意事項
`Destination Charge`の場合は、`Stripe::Charge`にも`Stripe::Transfer`にも履歴が残ります。

## Stripe::Subscription

定期支払いの情報を保持しています。
`"sub_~~~"`というid番号で情報を管理しています。
**Subscriptionを作成するには、あらかじめPlanとCustomerを作成する必要があります。**

`Stripe::Customer`と`Stripe::Plan`を紐づけ、その情報を`Stripe::Subscription`に作成することで定額課金を実現することができます。
以下に`Stripe::Subscription`の作成のコードを示しますが、`Stripe::Customer`のid番号と`Stripe::Plan`の名前が必要になります。

```ruby
Stripe::Subscription.create(
   customer: "cus_~~~",   #Stripe::Customerのid情報
   plan: "basic-yearly"  #Stripe::Planのname情報
)
```

特定の`Stripe::Subscription`を取得するのは以下のコードです。

```ruby
Stripe::Subscription.retrieve("sub~~~")
```

また、`Stripe::Subscription`をキャンセルするには以下のコードです。
これをすると、次回の支払いは発生しないことになります。

```ruby
stripe_subscription = Stripe::Subscription.retrieve("sub~~~")
stripe_subscription.delete
```

現在も活用されている`Stripe::Subscription`を複数取得するには、listメソッドを使います。

```ruby
Stripe::Subscription.list(limit: 100) #100件取得
```

## Stripe::Plan

定期支払いを実行するための情報を保持しています。

**アプリケーション運用者がプランを作る場合と、アカウント保持者（Account）がプランを作る場合で、コードが異なりますので注意してください。**

以下のコードで、アプリケーション運営者がプランを作成できます。

**注意していただきたいのが、`Stripe::Plan`の`amount(金額)`、`currency(通貨)`、`interval(課金間隔)`は一切変更することができません。**
これらのパラメーターを変更したい場合は、また新しく作り直りなおすことになります。

以下のコードで自分のアプリケーションのプラットフォームのプランを作成できます。

```ruby
Stripe::Plan.create(
   name: "月額980円 ベーシックプラン",
   id: "basic-monthly",
   interval: "month",
   currency: "jpy",
   amount: 980
)
```


また、以下のコードで、特定のアカウント保持者がプランを作成できます。

```ruby
Stripe::Plan.create({
   name: "月額980円 ベーシックプラン",
   id: "basic-monthly",
   interval: "month",
   currency: "jpy",
   amount: 980
}, stripe_account: "acct_~~~")
```


また、当たり前のことですが、`Stripe::Plan`は削除することができます。
以下のコードで削除可能です。

```ruby
plan = Stripe::Plan.retrieve("月額980円 ベーシックプラン")
plan.delete
```

**あるカスタマーが、特定のプランをStripe::Subscriptionで支払っている場合、そのプランを削除しても、定期支払いには何の影響もなく支払いが続くことになります。**
`Stripe::Plan`を削除ということは、新しいカスタマーが`Stripe::Subscription`を作れなくすることができるということになります。
なお、`Stripe::Plan`を削除すると、retrieveなどを使っても一切見ることができなくなります。
そのため、Stripeの公式見解では、`Stripe::Plan`は削除しない方がいいとのことです。

[Stripe::PlanのAPIリファレンス](https://stripe.com/docs/subscriptions/plans)


### Plan作成の際の必須情報

|パラメータ名|説明|
|:-:|:-:|
|id|プランのプライマリーキーとなる情報です。|
|name|InvoiceやWeb上で表示される名前です。|
|interval|Invoiceを作成するサイクルの定義です。year, month, week, dayから選べます。|
|currency|3文字の通貨表示です。（ISO4217に則ります。）日本円は`jpy`です。|
|amount|プランの金額です。|


### Stripe::Accountに紐づいたPlanの作成

```ruby
# 支払い情報のためのstripe_tokenを作成する
stripe_token = Stripe::Token.create(
      card: {
        number:    4242424242424242, #テストカードの番号
        exp_month: 12, #有効期限（月）は12月
        exp_year:  20 #有効期限（年）は2020年
      }
    )

# さきほどの、Customアカウントの認証が通っているアカウントを取得
stripe_account = Stripe::Account.retrieve("acct_~~~")

# stripe_accountに紐づいた顧客（stripe_accountの顧客）の作成
stripe_customer = Stripe::Customer.create(
      {
        email: "test@gmail.com",
        source: stripe_token.id
      }, stripe_account: stripe_account.id
    )

# stripe_accountに紐づいたプラン（stripe_accountのプラン）の作成
stripe_plan = Stripe::Plan.create(
      {
        id:       "test_of_plan",
        name:     "プランのテストです",
        amount:   1000,
        interval: "month",
        interval_count: 4,
        currency:       "jpy"
      }, stripe_account: stripe_account.id
    )

# stripe_accountに紐づいた定額課金（stripe_accountの定額課金）の作成
stripe_subscription = Stripe::Subscription.create(
  {
    customer: stripe_customer.id,
    plan: stripe_plan.id
  }, stripe_account: stripe_account.id
)
```

|パラメータ名|説明|
|:-:|:-:|
|interval_count|デフォルトは1となります。それぞれ最大値は、1 year, 12 months, 52 weeksとなります。|
|statement_descriptor|クレジットカード明細に表記される文言です。|

[こちらから引用](
https://qiita.com/y_toku/items/235b5e7ee00792edcbbf)して来ました。詳しく書かれているので、参考にしてみてください。


# アカウントの収支
## Stripe::Balance
あるアカウントのStripe上での収支は、`Stripe::Balance`に情報が保持されています。
自分のプラットフォーム上の収支を確認するためのコードは以下となります。

```ruby
Stripe::Balance.retrieve()
```

また、プラットフォームに紐づいたアカウントの収支情報を取得するには以下のコードです。

```ruby
Stripe::Balance.retrieve(
  stripe_account: "acct_id~~~"
)
```

実行結果は以下のようになります。

```bash
{
  "object": "balance",
  "available": [
    {
      "currency": "jpy",
      "amount": 9688629,
      "source_types": {
        "card": 9688629 # テストモードの場合、card番号はamountと同じになります。
      }
    },
    {
      "currency": "usd",
      "amount": -58,
      "source_types": {
        "card": -58
      }
    }
  ],
  "connect_reserved": [
    {
      "currency": "jpy",
      "amount": 0
    },
    {
      "currency": "usd",
      "amount": 0
    }
  ],
  "livemode": false,
  "pending": [
    {
      "currency": "jpy",
      "amount": 62622,
      "source_types": {
        "card": 62622
      }
    },
    {
      "currency": "usd",
      "amount": 0,
      "source_types": {
        "card": 0
      }
    }
  ]
}
```

ここで、`available`と`pending`という2つの種類のお金があることがわかります。

**`available`はすぐに銀行口座に送金することができるお金で、`pending`はすに銀行口座に送金することができないお金となっています。**


### 注意事項

**Stripe::Chargeでアカウントにお金が支払われた場合は、Stripe::Balanceのpendingに入ります。しかし、後に後述するStripe::Transferでアカウントでお金が支払われた場合は、availableに送金されます。**


## 送金について
### Stripe::Transfer
`Stripe::Transfer`は、プラットフォーム上やあるアカウントの決済で得たお金を、他のアカウントへ送金することができます。
これは実際の銀行のお金が送金されるのではなくて、Stripe上で扱われている金額が送金されます。
実際に銀行口座へのお金を振り込むには、次に説明する`Stripe::Payout`を利用してください。

また、`Stripe::Transfer`で送金される金額は`Stripe::Balance`のavailable、つまり、実際の銀行に入金できるお金が送金され、送金される側もBalanceのavailabeに入金がなされることになります。

プラットフォームから、特定のアカウントに情報を送金するのは以下のコードです。

```ruby
Stripe::Transfer.create(
  amount: 1000,
  curreny: 'jpy',
  destination: "acct_id~~~"
)
```

また、送金履歴を取得するには`retrieve`メソッドを使います。

```ruby
Stripe::Transfer.retrieve()
```

**Stripe::Transfer.retrieveで送金履歴を取得した場合、Stripe::Payoutの情報も含まれているので注意してください。**


# 銀行への振込について
## Stripe::Payout

アカウントに紐づいて登録されている銀行へ送金するには、`Stripe::Payout`を使います、
**Stripe::BalanceはStripe上での収支となっており、実際に自分の銀行口座にお金が入るようにするにはPayoutを実行しなければなりません。**
`Stripe::Payout`はStripe上で自動的に送金してくれるように設定することもできますし、プラットフォーム上の好きなタイミングで送金することもできます。


### Stripe::PayoutとStripe::Transferの違い
> ・Payouts will mean moving money from Stripe to your bank account or debit card and will be represented by /v1/payouts.
> ・Transfers will mean moving money between Stripe accounts as part of Connect and will be represented by /v1/transfers.

`Stripe::Payout`はStripe上のお金から銀行口座へのお金の入金、`Stripe::Transfer`はStripeアカウント間のお金の移動を意味しているようです。
APIのバージョンによって挙動が違ってくるそうなので、詳しく知りたい方は[こちら](https://stripe.com/docs/transfer-payout-split)で確認していただければと思います。


# その他のTips
## expand（展開機能）
expandは展開機能で、listやretrieveなどで取得する際に指定するものです。
これを使うと、取得したオブジェクトに関連したオブジェクトまで詳細に指定することができます。

## auto_paging_each
listで100件以上あった場合に、eachで配列を回す時に`auto_paging_each`メソッドを使うことで、次の100件も自動で取得することができます。

# テストカード
テストカードの情報は以下ページに書いてあるので、参照してください。

[Stripeのテストカード一覧](https://stripe.com/docs/testing)

# リファレンス
[StripeのAPIリファレンス（英語)](https://stripe.com/docs/api)
[Stripeの定額課金についてのQiita Part1](https://qiita.com/y_toku/items/235b5e7ee00792edcbbf)
[Stripeの定額課金についてのQiita Part2](https://qiita.com/y_toku/items/404b3c99632161f18579)
[Stripeのざっくり把握](https://qiita.com/tanishi/items/877f0d6144c85e744ca5)
[Stripeについての日本語の詳細な説明](https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?Stripe)
[Stripe APIを翻訳してみた](https://qiita.com/koki1023/items/dd4310de9888efe278a9)

## まとめ
備忘録としてまとめていったので、まとまりがつかなくなってしまいました。
わからないことはカスタマーサポートに質問すると、とても早く的確な回答が返ってきますので、ぜひ質問してみてください。