11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

🌟LINE DC🌟 LINE Developer CommunityAdvent Calendar 2022

Day 11

LIFFとStripe.jsを組み合わせて、決済完了後にLINEでメッセージを送信できるようにする

Posted at

この記事は、🌟LINE DC🌟 LINE Developer Community Advent Calendar 2022 11日目の記事です。

Stripe.jsとLIFF SDKの2つを活用することで、顧客とのコミュニケーションと決済をReactなどのアプリ内で表現できます。

プロジェクトとライブラリのセットアップ

まずはReactアプリのセットアップと、依存するライブラリを準備しましょう。

ViteでReactアプリを立ち上げる

Viteを利用して、Reactアプリをセットアップします。

$ yarn create vite liff-stripe --template react

LIFFとLIFF向けReactライブラリを追加する

続いてLIFFを組み込むためのライブラリを追加します。

$ yarn add @line/liff react-liff @line/liff-mock

今回、Reactへの組み込みには、以下のライブラリを使用しています。

Stripe.jsライブラリを追加する

続けてStripe Elementsで使用するStripe.js系ライブラリも追加します。

$ yarn add @stripe/stripe-js @stripe/react-stripe-js 

環境変数を設定する

StripeとLIFFで使用するAPIキーなどを環境変数として設定します。

Viteの場合、VITE_から始めましょう。

VITE_LIFF_ID=123456789-abcdefg
VITE_STRIPE_PUBLISHABLE_API_KEY=pk_test_xxx

LIFFのセットアップ

LIFFをReactアプリに組み込みましょう。

src/main.tsxを次のように書き換えます。

import React from 'react'
import ReactDOM from 'react-dom/client'
import { LiffProvider } from 'react-liff'
import { LiffMockPlugin } from '@line/liff-mock'
import App from './App'
import './index.css'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <LiffProvider
      liffId={import.meta.env.VITE_LIFF_ID}
      plugins={[
        new LiffMockPlugin()
      ]}
      // @ts-ignore
      mock={true}
    >
      <App />
    </LiffProvider>
  </React.StrictMode>
)

続いて、ユーザー名を表示させましょう。

src/App.tsxを次のように変更します。

import { useEffect, useState } from 'react'
import './App.css'
import { useLiff } from 'react-liff'

function App() {
  const [username, setUsername] = useState("")
  const { isLoggedIn, liff } = useLiff()
  useEffect(() => {
    (async () => {
      if (!liff.isLoggedIn()) {
        liff.login()
      }
      const profile = await liff.getProfile();
      setUsername(profile.displayName)
    })();
  }, [liff, isLoggedIn]);

  return (
    <div className="App">
      <h1>Hello {username}</h1>
    </div>
  )
}

export default App

Hello Brownと画面に出れば成功です。

スクリーンショット 2022-12-06 21.03.03.png

src/main.tsxmock={true}を削除すると、LINEログイン画面に遷移します。

-      // @ts-ignore
-      mock={true}

Stripe Elementで決済フォームを表示する

ここからはStripe.jsを利用して、決済フォームをLIFFアプリに追加します。

クイックスタートを利用して、 Payment Intentを用意するAPIを作成する

Stripe.jsのカード要素を表示するには、事前にPayment IntentまたはSetup Intent(カード情報などの保存のみする場合)を作成します。

StripeドキュメントのクイックスタートなどでAPIを用意しましょう。

APIを呼び出して、Payment Intentを取得する

作成したAPIを呼び出して、アプリ側でPayment IntentのClient Secretを取得しましょう。

  }, [liff, isLoggedIn]);

+  const [paymentIntentClientSecret, setPIClientSecret] = useState("")
+  useEffect(() => {
+    fetch("http://localhost:3000/create_payment_intent", {
+      method: "POST"
+    }).then(data => data.json())
+      .then(data => setPIClientSecret(data.clientSecret))
+  }, [])

  return (
    <div className="App">

取得したPayment Intentで、決済フォームを表示する

続いてStripe.js用のProviderにClient Secretを渡します。

import { useLiff } from "react-liff"
+import { loadStripe } from "@stripe/stripe-js"
+import { Elements } from "@stripe/react-stripe-js"

function App() {

...

  return (
    <div className="App">
      <h1>Hello {username}</h1>
+      {paymentIntentClientSecret ? (
+        <Elements
+          stripe={loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_API_KEY)}
+          options={{
+            clientSecret: paymentIntentClientSecret
+          }}
+        >
+          
+        </Elements>
+      ): null}
    </div>
  )

Providerを用意しましたので、子コンポーネントを作成してフォームを表示させましょう。

import { PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js"

function PaymentForm() {
  const stripe = useStripe()
  const elements = useElements()
  return (
    <form
      onSubmit={async e => {
        e.preventDefault()
        if (!stripe || !elements) return;
        const result = await stripe.confirmPayment({
          elements,
          redirect: 'if_required',
        })
        console.log(result)
      }}
    >
      <PaymentElement />
      <button type="submit">Buy</button>
    </form>
  )
}

このコンポーネントを、Elementsの子要素で配置すればOKです。


        <Elements
          stripe={loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_API_KEY)}
          options={{
            clientSecret: paymentIntentClientSecret
          }}
        >
+          <PaymentForm />
        </Elements>

決済完了後に、LIFFでメッセージを送信する

決済が完了したタイミングで、LIFFのsendMessagesを利用してメッセージを送信できます。

 PaymentFormコンポーネントを次のように変更しましょう。

function PaymentForm({ displayName }: { displayName?: string}) {
  const stripe = useStripe()
  const elements = useElements()
+  const { liff } = useLiff()
  return (
    <form
      onSubmit={async e => {
        e.preventDefault()
        if (!stripe || !elements) return;
        const result = await stripe.confirmPayment({
          elements,
          redirect: 'if_required',
        })
+        await liff.sendMessages([{
+          type: "text",
+          text: `Your payment id: ${result.paymentIntent?.id}`
+        }])
      }}
    >
      <PaymentElement />
      <button type="submit">Buy</button>
    </form>
  )
}

このように、Stripe.jsとLIFFを組み合わせることで、Reactアプリ内で決済とメッセージングを連携することができます。

11
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?