point of no return.

書ける時に頑張って書いていこう。

自社サービスにStripeを導入してみようかなーと思っている話

はじめに

この記事は Stripe Advent Calendar 2018 12日目の投稿です。
(投稿が遅くなり申し訳ありません…。)

世の中、キャッシュレス化の波が押し寄せてきつつある今日この頃。
みなさんキャッシュレスしてますか?

私が自社で開発しているアプリにも遂に決済機能を搭載しないといけない気配がしていたところ、
広島では丁度良く JP_Stripes Vol.3 が開催されることとなりました。
そこで、第1回目から参加していた私はついに登壇者側として参加することができました。

speakerdeck.com

発表した内容の中から、いくつか検討したケースをご紹介したいと思います。

ケース1: シンプルなお支払い

弊社のアプリには、Web上から該当サービスの日時を予約する機能があります。
ここに決済機能を搭載すれば、当日スムーズにサービスを提供できるはずです。

Stripeでは、アプリ内に顧客のカード情報を通さず、決済を完了することができます

// クライアントから受け取ったトークン情報を元に、お支払いを完了する
params := &stripe.ChargeParams{
    Amount:              stripe.Int64(1000),
    Currency:            stripe.String(string(stripe.CurrencyJPY)),
    Description:         stripe.String("これはテストです"),
    StatementDescriptor: stripe.String("statement"),
    ReceiptEmail:        stripe.String("hoge@gmail.com"),  // メールアドレスを指定しておくことで、領収書を送付してくれる
}
params.SetSource(token)
if _, err := charge.New(params); err != nil {
    // error handle
}

また、支払い時に発行されるIDを指定して、簡単に払い戻し処理等を行うことができます。

ケース2: 月々定額料金プラン

弊社のアプリには、お客様の契約内容に合わせて、
月々決まった料金をプラットフォーム利用料としてお支払い頂くプランがあります。

こんな時Stripeでは、事前にプランを作成し、定期購読を登録することができます

// 月々3万円のスタンダードプランを作成
params := &stripe.PlanParams{
    Amount:   stripe.Int64(30000),
    Interval: stripe.String("month"),
    Product: &stripe.PlanProductParams{
        Name: stripe.String("Standard Plan"),
    },
    Currency: stripe.String(string(stripe.CurrencyJPY)),
}
if _, err := plan.New(params); err != nil {
    // error handle
}
// 顧客にプランを登録する
params := &stripe.SubscriptionParams{
    Customer: stripe.String("cus_Dqq5YFZLdPTtF5"),
    Items: []*stripe.SubscriptionItemsParams{
        {
            Plan: stripe.String("plan_DqtzR4mPLkEOgq"),
        },
    },
}
if _, err := sub.New(params); err != nil {
    // error handle
}

また、定期購読で求められる以下のような、自分で実装しようとするとかなりめんどくさそうな機能も予め搭載されています。

  • 無料トライアル期間の設定
  • ダブル定額のような段階的価格設定
  • クーポンを使用した割引の適用  など

ケース3: 従量課金プラン

弊社のアプリには、1回のオーダー毎に料金が発生し、
月末にかかった料金をまとめてお支払い頂くというサービスがあります。

これだけだと普通なのですが、プラットフォーム側では1つのオーダーに対してサービス提供者をアサインし、
手数料を差し引いた料金を、サービス提供者へお支払いする必要があります。

Stripeでは、料金の支払いが完了すると同時に対象アカウントへ送金する機能が存在します。
※送金をするには、送金の受取人が以下のいずれかの方法でアカウントを作成している必要があるようです。
- Standard: 自身のStripeのアカウントを作成 - Express: OAuth認証を使用してアカウントを接続(※アメリカ在住限定) - Custom: 送金側が用意したカスタムアカウントに対して、本人確認

https://stripe.com/img/docs/connect/platform_charges.png

// カスタムアカウントを作成
params := &stripe.AccountParams{
    Country: stripe.String("JP"),
    Type:    stripe.String(string(stripe.AccountTypeCustom)),
    Email:   stripe.String("hoge@gmail.com"),
}
acct, _ := account.New(params)
// アカウントの利用規約の同意
params := &stripe.AccountParams{
    TOSAcceptance: &stripe.TOSAcceptanceParams{
        Date: stripe.Int64(time.Now().Unix()),
        IP:   stripe.String("192.168.x.x"), // Assumes you're not using a proxy
    },
}
if _, err := account.Update(${作成したアカウントのID}, params); err != nil {
    // error handle
}
// お支払い(3000円)
params := &stripe.ChargeParams{
    Amount:        stripe.Int64(3000),
    Currency:      stripe.String(string(stripe.CurrencyJPY)),
    TransferGroup: stripe.String("transfer001"),
}
params.SetSource(token)
_, _ = charge.New(params)

// 1人目に送金
transferParams := &stripe.TransferParams{
    Amount:        stripe.Int64(1000),
    Currency:      stripe.String(string(stripe.CurrencyJPY)),
    Destination:   stripe.String(${送金先アカウントのID}),
    TransferGroup: stripe.String("transfer001"),
}
_, _ = transfer.New(transferParams)

// 2人目に送金
secondTransferParams := &stripe.TransferParams{
    Amount:        stripe.Int64(1000),
    Currency:      stripe.String(string(stripe.CurrencyJPY)),
    Destination:   stripe.String(${送金先アカウントのID}),
    TransferGroup: stripe.String("transfer001"),
}
_, _ = transfer.New(secondTransferParams)

まとめ

まだ簡単に検証を行っただけで間違っている部分も多々あるかもしれませんが、
あらゆる支払いに対応しており、戻しなどの必要不可欠な機能もとても充実していると感じました。 これらを自分で管理してメンテするのはもちろん大変だし、今後も新しい機能がどんどん追加されていくことを考えると、
やはりこういったサービスに乗っかっておくのが良いのではないでしょうか。

また、こういったサービスで決済を自動化することによって、
決済にぶら下がる周辺の業務も自動化することができそうだということも見えてきました。
これらを自動化することで利用者に効率的にサービスを提供できるようになり、サービス提供側の回転率なども上がります。

弊社は医療系のサービスを提供する会社のため、
これらのサービスを充実させていくことで、時間的制約によりなかなか受診することが難しい検診の受診率アップや、
病院内の待ち時間短縮など、高品質な医療を提供するための貢献をしていくことができるのではないかと思いました。