決済プラグイン

決済プラグインについて

決済プラグインを使用すると、Stripe経由で決済処理が出来るようになります。
決済処理は単発のお支払いの他、定期購入も可能です。

決済プラグインの有効化

プラグイン設定にて、決済プラグインを有効にしてください。
決済プラグインを有効にした状態でサーバーのビルドを行うと決済プラグインのAPIが生成されます。
なお、決済プラグインはStripeを利用して決済処理を実行するため、実際に使用するには後述するStripeへの登録が別途必要になります。

決済プラグインの初期設定

決済プラグインはStripeを利用して決済処理を実行するため、実際に使用するには後述するStripeへの登録が別途必要になります。
Stripe決済ごとの手数料が発生するのみで、月額の利用料はかからないため無料で始めることが出来ます。
また、Stripeの管理画面にて顧客データの確認や購入状況を確認することが可能です。

1. Stripeの登録

Stripe公式HPから登録を行ってください。
登録はコチラから

Stripe公式HP

2. StripeのKeyを取得

Stripe管理画面にて、公開可能キーとシークレットキーを取得します。
開発時にはテストAPIキーを利用してください。

Stripe管理画面

3. Stripeのシークレットキーをサーバーに登録

2.で取得したシークレットキーをサーバーのenvファイルを更新します。
更新後は必ず変更のCommit及びPushを行ってください。

SERVER_ROOT/src/app/.env

# Stripe Config
STRIPE_SECRET_API_KEY=ここにシークレットキーを設定

以上で設定は完了です。
2. で取得した公開可能キーはクライアントから利用時に必要です。
公開可能キーを使ったクライアントを実装することで、決済処理が実現可能になります。

4. クライアントにStripeのSDKをインストール

4-A. WebにStripeのライブラリをインストール

以下のyarnコマンドでstripeをインストールしてください。

yarn add @stripe/stripe-js
yarn add -D @types/stripe-v3

4-B. アプリ(React Native)にStripeのライブラリをインストール

以下のyarnコマンドでstripeをインストールしてください。

yarn add tipsi-stripe

Stripeプラグインの使い方

Stripeを利用する場合、公式HPのドキュメントを必ずご確認ください。
基本的な使い方は公式HPに網羅されていますが、ここではWebの場合の一般的なお支払いと定期購入のフローを記載します。
なお、Stripeの実装方法はアプリに合わせて様々なパターンがありますので、下記に記載するのはあくまで一例になります。その他のパターンでの実装を行いたい場合は公式HPやWebでの検索をご確認ください。

Stripeプラグインを使ったお支払い

お支払いのフローはPayment Intent(いくら払うかを予約するようなもの)を作成し、Payment Intentをクライアント側で承認することによって完了します。
Payment Intentを作成するタイミングはアプリによって異なりますが、多くはユーザーが支払い確定ボタンを押したタイミングが良いでしょう。

1. Payment Intentの作成

Payment Intentは1-A.クライアントのAPI経由で作成または、1-B.サーバーで直接作成することが可能です。
セキュリティ上の観点からAPIを一般公開するようなプロジェクトでは、後者のB.他API呼び出し時にメール送信処理を入れ込むことをお勧めします。

1-A. クライアントのAPI経由で作成する

StripeAPIのcreateStripePaymentIntentを支払いに関する情報を指定します。

async createStripePaymentIntent() {
  const res = await new StripeApi().createStripePaymentIntent({
    amount: 1000, // 支払い金額
    currency: 'jpy', // 支払い通過
    description: 'ユーザーによる支払い' // 支払い説明
  })
  const clientSecret = res.data.clientSecret
}

クライアントからの呼び出しは、テスト用に決済処理を組み込みたい場合やAPIが非公開な場合に有用です。
前途した通り、StripeAPIのcreateStripePaymentIntentが一般公開されている場合はAPIを呼び出すことで意図しないPaymentIntentの作成が可能になってしまいますので注意が必要です。

1-B. サーバーで直接作成する

PaymentIntent作成処理を入れ込みたいxxx_handler.go等に実装を行います。

SERVER_ROOT/src/app/hanlder/xxx_handler.go等

func (h *xxxHandler) createPaymentIntent() (*model.StripePaymentIntent, error) {
	paymentIntent, err := h.sm.Stripe.CreatePaymentIntent(&model.StripePaymentIntentParams{
		Amount:      stripe.Int64(1000), // 支払い金額
		Currency:    stripe.String(string(stripe.CurrencyJPY)), // 支払い通過
		Description: stripe.String("ユーザーによる支払い"), // 支払い説明
	})
	return paymentIntent, err
}

サーバーからの呼び出しは、特定のレコードが登録された際や更新、削除された場合にPaymentIntentを作成するケースや、他プラグインが呼び出された際にPaymentIntentを作成することが実現可能です。
なお、作成したPaymentIntentのClientSecretは後続の処理に必要なため、クライアントに必ず返却してください。

2. カード情報入力箇所の実装

クライアント側でカード情報の入力箇所を実装します。
ここで決済プラグインの初期設定で取得した、公開可能キーが必要になります。
なお、カード情報入力箇所の開発方法は公式ページが参考になりますのでご参照ください。
公式ページはコチラ

下記サンプルでは実装に必要な最低限のコードを記載しますので、公式ページと合わせて参考にしてください。

<div id="card-element"><!--Stripe.js injects the Card Element--></div>
import { loadStripe } from '@stripe/stripe-js/pure'

export default class Page extends Vue {
  stripe: stripe.Stripe | null = null
  card: stripe.elements.Element | null = null

  async mounted() {
    this.stripe = await loadStripe("Stripeの公開可能キー")
    const elements = stripe.elements()
    this.card = elements.create("card")
    // Stripe injects an iframe into the DOM
    card.mount("#card-element")
  }
}

3. 支払いの承認

最後に、1.で取得したPaymentIntentのClientSecretと2.で取得したカード情報でクライアント側で支払いの承認を行います。

async confirmPayment(clientSecret : string) {
  const res = await this.stripe.confirmCardPayment(clientSecret)
  console.log(res.error) // 支払いエラー
  console.log(res.paymentIntent.status)
}

以上でお支払い処理は完了です。
支払いエラーにカード情報の不備等も出力されますので、エラーがある場合は必ずユーザーに通知を行ってください。

Stripeプラグインを使った定期購入

定期購入を行うにはまず、定期購入を行う、Product及びPriceをStripeの管理画面から作成します。
次に、クライアントにてPayment Method(支払い方法)を作成し、Payment Methodが紐づいたStripe Customer(Stripe上の顧客情報)を作成し、Stripe Customerに対してSubscription(定期購入)を作成することによって完了します。ステップは多いですが、TemPlatが生成するAPIを順に実行していけば実現可能です。

1. Product及びPriceの作成

Stripe管理画面の商品の箇所からProduct及びPriceを作成してください。
ここで作成したPriceのID(price_xxxxxxxxx)が後続の処理で必要になります。
詳しくはコチラ

2. カード情報入力箇所の実装

クライアント側でカード情報の入力箇所を実装します。
ここで決済プラグインの初期設定で取得した、公開可能キーが必要になります。
なお、カード情報入力箇所の開発方法は公式ページが参考になりますのでご参照ください。
公式ページはコチラ

下記サンプルでは実装に必要な最低限のコードを記載しますので、公式ページと合わせて参考にしてください。

<div id="card-element"><!--Stripe.js injects the Card Element--></div>
import { loadStripe } from '@stripe/stripe-js/pure'

export default class Page extends Vue {
  stripe: stripe.Stripe | null = null
  card: stripe.elements.Element | null = null

  async mounted() {
    this.stripe = await loadStripe("Stripeの公開可能キー")
    const elements = stripe.elements()
    this.card = elements.create("card")
    // Stripe injects an iframe into the DOM
    card.mount("#card-element")
  }
}

3. PaymentMethodの作成

2.で取得したカード情報でStripe上にPaymentMethodを作成します。
ここで取得したpaymentMethodIDが後続の処理で必要になります。

async createPaymentMethod() {
  const result = await this.stripe.createPaymentMethod({
    type: 'card',
    card: this.card,
    billing_details: {
      email: 'user@example.com',
      name: 'user',
      phone: '090-1234-5678'
    }
  })
  const paymentMethodID = result.paymentMethod?.id
  console.log(paymentMethodID)
}

4. StripeCustomerの作成

3.で作成したPaymentMethodに紐づくCustomerを作成します。
作成にはStripeApiのcreateStripeCustomerを使用します。
ここで取得したCustomerのIDが後続の処理で必要になります。

async createStripeCustomer(paymentMethodID : string) {
  const res = await new StripeApi().createStripeCustomer({
    body: {
      email: 'user@example.com',
      name: 'user',
      phone: '090-1234-5678',
      paymentMethodID: paymentMethodID,
      defaultPaymentMethodID: paymentMethodID
    }
  })
  const customerID = res.data.id
  console.log(customerID)
}

5. Subscriptionの作成

4.で作成したStripeCustomerに対してSubscriptionを作成します。
作成にはStripeApiのcreateStripeSubscriptionを使用します。
ここで1.で作成したPriceのIDも必要になります。

async createStripeSubscription(customerID: string) {
  const res = await new StripeApi().createStripeSubscription({
    body: {
      customerID: customerID,
      items: [{ price: 'price_xxxxxxxxx' }]
    }
  })
  console.log(res.data.status)
}

以上で定期購入の処理は完了です。
実際のアプリではエラーの表示に合わせて、重複したSubscriptionを作らない等の制御も必要になる場合がありますので、公式HP等を参考に実装をしてください。