コンテンツにスキップ
アカウントを作成
または
サインイン
Stripe ドキュメントのロゴ
/
AI に質問する
アカウントを作成
サインイン
始める
支払い
Revenue
プラットフォームおよびマーケットプレイス
資金管理
開発者向けのツール
概要
バージョン管理
変更ログ
API バージョンのアップグレード
SDK バージョンをアップグレードする
開発者向けのツール
SDK
API
テスト
ワークベンチ
イベントの送信先
ワークフロー
Stripe CLI
Stripe Shell
開発者ダッシュボード
エージェントツールキット
LLM を使用した構築Visual Studio Code をご利用の場合Stripe 健全性アラートファイルのアップロード
Security and privacy
セキュリティ
プライバシー
Stripe を拡張する
Stripe Apps
    概要
    始める
    アプリを作成する
    Stripe アプリの仕組み
    サンプルアプリ
    アプリを構築する
    シークレットを保存
    API 認証方法
    認証フロー
    サーバー側のロジック
    イベントのリッスン
    さまざまな環境を処理
    サンドボックスのサポートを有効にする
    アプリの設定ページ
    UI を構築する
      UI Extensions の仕組み
      UI テスト
      開発者向けのツール
      アプリのデザイン
      アプリのスタイル設定
      Stripe の UI 拡張機能 SDK をアップグレード
    アカウント登録
    アプリを配布する
    配布オプション
    アプリをアップロード
    バージョンとリリース
    アプリをテストする
    アプリを公開する
    自分のアプリを宣伝する
    ディープリンクを追加する
    インストールリンクを作成
    UI 拡張機能で役割を割り当て
    インストール後のアクション
    アプリのアナリティクス
    アプリの埋め込みコンポーネント
    サードパーティーの Stripe アプリを埋め込む
    Stripe Apps に移行
    拡張機能を移行または構築
    Stripe Apps または Stripe Connect にプラグインを移行
    参照情報
    アプリマニフェスト
    CLI
    拡張 SDK
    権限
    ビューポート
    設計パターン
    コンポーネント
Stripe のコネクター
パートナー
Partner Ecosystem
パートナー認定
ホーム開発者向けのツールStripe AppsBuild a UI

UI 拡張機能の仕組み

UI 拡張機能システムと、Stripeダッシュボードを拡張する方法についてご紹介します。

ページをコピー

Stripe アプリの UI 拡張機能 (TypeScript と React) を使用すると、Stripe プロダクトに独自の UI をレンダリングできるようになります。これらのツールは、React での開発経験を持つ人であればすぐにご利用いただけると思います。ただし、これらは別のウェブページに埋め込まれるサンドボックス化された安全な iframe 内で実行されるため、標準の React ブラウザーアプリケーションとはいくつかの点で異なります。

概要

スタックの学習

  • Intro to React (React の概要) (英語)
  • Get started with TypeScript (TypeScript の使用の開始) (英語)
  • Stripe の UI コンポーネント

UI Extensions は TypeScript で記述され、React を使用し、Stripe の UI ツールキットで UI を作成します。その他の React 環境とは異なり、UI Extensions は、任意の HTML をサポートしていません。代わりに、Stripe が提供する UI コンポーネントのみを使用します。UI 拡張機能の構造には、いくつかの主要なディレクトリーとファイルが含まれています。

  • stripe-app.json: アプリマニフェスト。アプリが Stripe と対話する方法を記述します。これには、必要な権限、UI 拡張機能が存在するかどうか、存在する場合はその拡張機能が Stripe の UI のどこに表示されるかなどが含まれます。
  • package.json: NPM パッケージのメタデータ。UI 拡張機能は通常の NPM パッケージです。npm または yarn を使用して依存関係を管理することができます。
  • src: UI 拡張機能の実際の TypeScript ソースコード。デフォルトでは、CLI は、汎用ビューを src/views に配置し、対応するエントリーを stripe-app.json に配置します。

UI 拡張機能の開発には、Stripe CLI アプリプラグインを使用します。CLI は、アプリを正しい構造で初期化して、アプリマニフェストを設定し、開発サーバーを実行して、Stripe に送信するためにアプリを適切にバンドルします。

UI 拡張機能を開発する

  • アプリ開発者としてビューを作成します。このビューは、特定のビューポートが画面に表示されるときは常に表示されるように登録された React コンポーネントです。たとえば、あるビューを、ユーザーが請求書の詳細ページを表示するたびに表示されるようにするには、ビューポートの stripe.dashboard.invoice.detail に登録します。
  • アプリをアップロードする準備ができたら、CLI コマンドにより、コードがバンドルされて Stripe にアップロードされ、Stripe の CDN でホストされます。
  • アプリの UI 拡張機能が初期化されると、Stripe は、サンドボックス化された iframe にアプリのコードをダウンロードします。
  • ユーザーが特定のビューポートを持つページに移動する場合 (例: /invoices/inv_1283):
    • Stripe は、ビューポートに表示されるコンテキストを使用して、iframe 内の UI 拡張機能のビューを定義します。
    • Stripe がビューをダッシュボードに渡すと、ユーザーに表示されます。
    • ユーザーが UI 拡張機能を操作 (ボタンのクリックなど) すると、UI 拡張機能の iframe のイベントハンドラがイベントを受信し、ビューを更新します。
Stripe アプリの UI 拡張機能のシステム図

ビューとビューポート

UI をアプリのユーザーに表示するには、React ビューを作成してビューポートに登録します。

ビューは、アプリがエクスポートする React コンポーネントです。ビューポートは、ビューが表示される場所を示す識別子です。アプリがアップロードされると、アプリによってエクスポートされたすべてのビューが、関連付けられているビューポートに登録されます。

stripe apps add view を実行すると、ビューは自動的にビューポートに登録します。これにより、アプリマニフェストにエントリーが追加されます。

{ //... other manifest properties "ui_extension": { "views": [ { "viewport": "stripe.dashboard.invoice.detail", // See all valid values at stripe.com/docs/stripe-apps/reference/viewports "component": "NameOfComponent" // This is provided by you } // ... additional views ] } }

UI 拡張機能のライフサイクル

UI 拡張機能は、非表示のサンドボックス化された iframe で実行され、UI の更新は Stripe ダッシュボードに非同期で送信されます。サンドボックス化された単一の iframe で、複数のビューに同時に対応できます。

サンドボックス化された iframe と、それによって表示されるビューのライフサイクルは次のように機能します。

  • ダッシュボードは、ダッシュボードが読み込まれてからユーザーがアプリを開くまでの間に発生する UI 拡張機能の iframe を読み込みます。
  • ビューを表示する必要がある場合、ダッシュボードはサンドボックス化された iframe が初期化されるのを待ってから正しいビューをマウントするように指示し、適切なコンテキストに渡します。
  • ユーザーがビューを閉じると (たとえば、アプリのドロワーを閉じる場合)、ビューのマウントが解除されます。マウントが解除されると、ビューは DOM とサンドボックス化された React ツリーから削除されます。
  • サンドボックス化された iframe は、リソースの使用状況に応じて、実行状態のままになるか、シャットダウンされます。ダッシュボードは iframe を終了する前に useEffect やその他のクリーンアップハンドラを実行できるように最善を尽くすことのみ保証しています。
Stripe Apps の UI 拡張機能のライフサイクル

Stripe Apps の UI 拡張機能のライフサイクル

サンドボックス化された iframe の制限事項

UI 拡張機能のコードは一意のサンドボックス環境で実行されるため、Stripe Apps の UI 拡張機能は、フルブラウザーのコンテキストで実行される通常の React アプリが行うすべてを実行できるわけではありません。

Stripe Apps と通常の React アプリの主な相違点

  1. Stripe Apps は、DOM に直接アクセスできません。ダッシュボードから不可視の別個の DOM を持つ iframe 内で実行されます。
  2. ダッシュボードがすべてのデータをシリアライズしてアプリにプロキシー送信します。UI ツールキットのコンポーネントはシリアライズ可能なデータのみを受け付けます。
  3. ダッシュボードはすべての「プロパティー」もシリアライズしてアプリにプロキシー送信するため、UI ツールキットのコンポーネントに渡される、またはこれによってトリガーされる関数は、非同期型になります。

React と JavaScript の制限事項

以下の制約は、アプリの開発時に React と JavaScript で何を実行できるかに影響します。React ツリーは、Stripe ダッシュボードのホスト環境がデシリアライズして評価するまで DOM にレンダリングされません。アプリの DOM が更新され、ダッシュボードの React のインスタンスがデータ入力を管理します。

グローバルな document オブジェクトと window オブジェクトは制限されている

UI 拡張コードが実行されている DOM 環境は、サンドボックス化された iframeによってロックダウンされます。そのため、localStorage、indexedDB、BroadcastChannel などの最上位の API は使用できません。同一生成元ポリシーに依存する DOM API は、サンドボックス化された iframe の生成元が null であるため、正常には機能しません。

React の ref プロパティがサポートされない

UI コンポーネントは、React ツリーがシリアル化され、レンダリングのために Stripe ダッシュボードに渡されるため、React ref プロパティをサポートしていません。コンポーネントが最終的にレンダリングされる DOM は、サンドボックス化された iframe で実行されているアプリコードからアクセスできません。

アプリでは React のバージョンを管理できない

各 Stripe アプリで生成されるデフォルトの package.json ファイルには、react の dependency エントリーがありません。Stripe アプリの package.json ファイルに特定のバージョンの React を追加しても、アプリが表示される React バージョンは管理されません。タイプチェックとユニットテストのみを実行します。Stripe ダッシュボードは、そのバージョンの React (現在のバージョン 17.0.2) を使用して、すべてのアプリを表示します。互換性を確保するため、Stripe から指示された場合にのみ変更してください。

インタラクションに非制御コンポーネントを使用する

ダッシュボードはすべてのデータ入力をシリアライズしてアプリにプロキシー送信します。この結果、React の制御コンポーネントの使用時に入力遅延が発生します。この遅延は、ユーザーに認識され、その間にユーザーが入力した文字を上書きする可能性があります。また、先頭でテキストを編集しようとすると、カーソルがテキスト入力の末尾にスキップします。

アプリの遅延を減らすために、非制御の方法でユーザーの入力を使用します。

import {useState} from 'react'; import {TextArea} from '@stripe/ui-extension-sdk/ui'; const App = () => { const defaultValue = 'Initial TextArea value'; const [text, setText] = useState(defaultValue); return ( <> <TextArea label="Message" // This doesn't work ❌ // Attempting to edit text at the beginning skips the cursor to the end value={text} onChange={e => setText(e.target.value)} /> <TextArea label="Message" // This will work ✅ defaultValue={defaultValue} onChange={e => setText(e.target.value)} /> </> ); };

UI コンポーネントの制約

以下の制約は、UI コンポーネントに当てはまります。拡張機能は分離された環境で実行されますが、UI コンポーネントはダッシュボードに直接表示されます。SDK は、UI ツールキットコンポーネントを表示するようにダッシュボードに指示し、その結果、次の制限事項が生じます。

コンポーネントはイベントの伝播を止められない

イベントハンドラーは非同期で呼び出されるため、アプリのイベントハンドラーが呼び出されるまでにイベントはすでに伝播しています。そのため、アプリは、イベントの伝播やバブリングを止めることができません。

コンポーネントはシリアライズ可能なデータタイプのみをプロパティとして受け付ける

UI コンポーネントはシリアライズ可能なデータタイプのみを受け付けます。Map または Set など、シリアライズできないデータタイプをプロパティーとして UI ツールキットのコンポーネントに渡すと、エラーが返されます。

プロパティにはシンプルな型、関数、または React イベントのみを使用してください。サポートされている型は以下のとおりです。

  • 文字列、数字、true、false、null、および undefined
  • キーと値がすべてシンプルな型のオブジェクト
  • 値がすべてシンプルな型の配列
  • 関数。ただし、プロキシー送信されると非同期になります。引数として渡されるすべての関数や返される関数にも、型の制限が適用されます。
  • React イベント

コンポーネントはレンダリング関数をサポートしない

React は同期的にレンダリングしますが、UI コンポーネントに渡される関数は、ダッシュボードがアプリにプロキシー送信した後で非同期になります。UI コンポーネントに渡されるマークアップを生成する関数では、React がその結果を使用するまでにレンダリングが完了しません。結果的に、レンダリング関数はどの UI コンポーネントでも受け付けられません。

したがって、次のパターンは機能しません。

// This doesn't work ❌ <ItemProvider> {(data) => ( <Item data={data} /> )} </ItemProvider>
// This doesn't work ❌ <Item renderFooter={() => <div>footer</div>} />

JSX は単一ノードとして子以外のプロパティにのみ渡すことが可能

UI コンポーネントは、次のような単一の React エレメントを取るプロパティーをサポートします。

// This will work ✅ <Item footer={<div>footer</div>} />

より複雑な JSX データ構造はサポートされません。ただし、次の例外があります。

// This doesn't work ❌ <Item footer={[<div>one</div>, <div>two</div>]} />
// This doesn't work ❌ <Item footer={{ one: <div>one</div>, two: <div>two</div> }} />

複数の React エレメントを UI コンポーネントに渡す必要がある場合は、次のようにフラグメント内にラップします。

// This works ✅ <Item footer={ <> <div>one</div> <div>two</div> </> }/>

同様の制約が children にあてはまります。JSX を含む配列とオブジェクトはサポートされませんが、複数の React エレメントは許可されます。

// This works ✅ <Item> <div>one</div> <div>two</div> </Item>

NPM パッケージのインストール

サードパーティーの NPM パッケージを Stripe アプリに追加する場合の制限はありません。お客様が適切だと思うパッケージを自由にインストールしてください。ただし、UI 拡張機能にはサンドボックス化された iframe の制限事項があるため、すべてのパッケージが正常に機能するわけではありません。

lodash は DOM アクセスを必要としないため、lodash のようなユーティリティライブラリを使用してもかまいません。

import { Box, Button } from "@stripe/ui-extension-sdk/ui"; import { useState } from "react"; import kebabCase from "lodash/kebabCase"; const text = "A note to the user"; const App = () => { const [isKebabCase, setIsKebabCase] = useState(false); return ( <> {/* This will work ✅ */} <Box>{isKebabCase ? kebabCase(text) : text}</Box> <Button onPress={() => { setIsKebabCase(!isKebabCase); }} > Toggle kebab-case </Button> </> ); };

react-hook-form は Ref を使用してフォームのステータスを管理するため、react-hook-form のようなフォームライブラリは機能しません。

import { TextField } from "@stripe/ui-extension-sdk/ui"; import { useForm } from "react-hook-form"; const App = () => { const { register } = useForm(); const { onChange, name, ref } = register("firstName"); return ( <TextField label="First name" placeholder="Enter your name" name={name} onChange={onChange} // This doesn't work ❌ ref={ref} /> ); };

参照情報

  • ビューの構築とテスト
  • アプリの設計
  • アプリのスタイル設定
  • 配布オプション
このページはお役に立ちましたか。
はいいいえ
お困りのことがございましたら 、サポートにお問い合わせください。
早期アクセスプログラムにご参加ください。
変更ログをご覧ください。
ご不明な点がございましたら、お問い合わせください。
LLM ですか?llms.txt を読んでください。
Powered by Markdoc