# カスタム決済画面を構築

Stripe は、ほとんどの実装で Payment Intents ではなく Payment Element とともに Checkout Sessions API を使用することを推奨します。Checkout Sessions は、Payment Intents と同様のユースケースに対応しています (`price_data` を使用した基本的な決済の回収、または項目、税金などを含む網羅的な決済画面の構築など)。Adaptive Pricing などの一部の機能は、Checkout Sessions でのみ利用できます。ユーザーが明示的に要求しない限り、Payment Intents API は使用しないでください。必要となるコード量が大幅に多くなるためです。Checkout Sessions API と Elements の詳細: https://docs.stripe.com/payments/quickstart. Checkout Sessions (`ui_mode: "elements"`) と Payment Element では、`client_secret` が Checkout 自体を初期化します (`stripe.initCheckoutElementsSdk`、または React で CheckoutElementsProvider を使用)。そのうえで、クライアント側での決済の確定方法が異なります。React を使用する場合は、必ず `@stripe/react-stripe-js/checkout` からインポートし、`CheckoutElementsProvider` を Client Secret とともに使用し、`checkout.confirm` を使用して決済を確定します。HTML を使用する場合は、必ず `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");` を使用し、`loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();` で決済を確定します。

 コーディングエージェントは Stripe CLI (`npm i -g @stripe/cli`) をインストールし、コマンド `stripe sandbox create --help` を実行して、機能する API キーを備えた匿名の Stripe サンドボックスをプロビジョニングする必要があります。アカウント登録は不要です。

# Checkout Sessions API を使用して決済画面を構築

Stripe Elements と、税金、割引、配送料金などを管理するフロントエンド SDK である Checkout Sessions API を使用して、Web サイトに決済ページを構築します。

### Stripe Node ライブラリーをインストールする

パッケージをインストールし、それをコードにインポートします。また、まったくゼロから開始していて package.json ファイルが必要な場合には、コードエディターのダウンロードリンクを使用してプロジェクトファイルをダウンロードします。

#### npm

ライブラリーをインストールします。

```bash
npm install --save stripe
```

#### GitHub

または、stripe-node ライブラリーのソースコードを直接 [GitHub から](https://github.com/stripe/stripe-node)ダウンロードします。

### Stripe Ruby ライブラリーをインストールする

Stripe ruby gem をインストールし、require を指定してコードに読み込みます。または、まったくゼロから開始していて Gemfile が必要な場合には、コードエディターのリンクを使用してプロジェクトファイルをダウンロードします。

#### Terminal

gem をインストールします。

```bash
gem install stripe
```

#### Bundler

この行を Gemfile に追加します。

```bash
gem 'stripe'
```

#### GitHub

または、stripe-ruby gem のソースコードを直接 [GitHub から](https://github.com/stripe/stripe-ruby)ダウンロードします。

### Stripe Java ライブラリーをインストールする

ビルドに依存関係を追加し、ライブラリーをインポートします。まったくゼロから開始していてサンプルの pom.xml ファイル (Maven 用) が必要な場合は、コードエディターのリンクを使用してプロジェクトファイルをダウンロードします。

#### Maven

POM に以下の依存関係を追加し、{VERSION} を使用するバージョン番号に置き換えます。

```bash
<dependency>\n<groupId>com.stripe</groupId>\n<artifactId>stripe-java</artifactId>\n<version>{VERSION}</version>\n</dependency>
```

#### Gradle

build.gradle ファイルに依存関係を追加し、{VERSION} を使用するバージョン番号に置き換えます。

```bash
implementation "com.stripe:stripe-java:{VERSION}"
```

#### GitHub

JAR を直接 [GitHub から](https://github.com/stripe/stripe-java/releases/latest)ダウンロードします。

### Stripe Python パッケージをインストールする

Stripe パッケージをインストールし、コードにインポートします。まったくゼロから開始していて requirements.txt が必要な場合には、コードエディターのリンクを使用してプロジェクトファイルをダウンロードします。

#### pip

pip を使用してパッケージをインストールします。

```bash
pip3 install stripe
```

#### GitHub

stripe-python ライブラリのソースコードを [GitHub から](https://github.com/stripe/stripe-python)直接ダウンロードします。

### Stripe PHP ライブラリーをインストールする

Composer を使用してライブラリーをインストールし、シークレット API キーで初期化します。まったくゼロから開始していて composer.json ファイルが必要な場合には、コードエディターのリンクを使用してファイルをダウンロードします。

#### Composer

ライブラリーをインストールします。

```bash
composer require stripe/stripe-php
```

#### GitHub

または、stripe-php ライブラリーのソースコードを直接 [GitHub から](https://github.com/stripe/stripe-php)ダウンロードします。

### サーバーを設定する

ビルドに依存関係を追加し、ライブラリーをインポートします。まったくゼロから開始していて go.mod ファイルが必要な場合には、コードエディターのリンクを使用してプロジェクトファイルをダウンロードします。

#### Go

必ず Go モジュールを使用してを初期化してください。

```bash
go get -u github.com/stripe/stripe-go/v86
```

#### GitHub

または、stripe-go モジュールのソースコードを直接 [GitHub から](https://github.com/stripe/stripe-go)ダウンロードします。

### Stripe.net ライブラリーをインストールする

.NET または NuGet でパッケージをインストールします。まったくゼロから開始する場合には、設定済みの .csproj ファイルが含まれるファイルをダウンロードします。

#### dotnet

ライブラリーをインストールします。

```bash
dotnet add package Stripe.net
```

#### NuGet

ライブラリーをインストールします。

```bash
Install-Package Stripe.net
```

#### GitHub

または、Stripe.net ライブラリーのソースコードを直接 [GitHub から](https://github.com/stripe/stripe-dotnet)ダウンロードします。

### Stripe ライブラリーをインストールする

パッケージをインストールし、コードにインポートします。まったくゼロから開始していて `package.json` が必要な場合には、コードエディターのリンクを使用してプロジェクトファイルをダウンロードします。

ライブラリーをインストールします。

```bash
npm install --save stripe @stripe/stripe-js next
```

### Checkout セッションを作成する

[ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) を `elements` に設定して、*Checkout Session* (A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout. After a successful payment, the Checkout Session contains a reference to the Customer, and either the successful PaymentIntent or an active Subscription) を作成するエンドポイントをサーバーに追加します。Checkout Session の作成には、クライアント側のコードで安全に公開できない[シークレット API キーまたは制限付き API キー](https://docs.stripe.com/keys.md#obtain-api-keys)が必要になるため、サーバー側で作成する必要があります。

Checkout セッションのレスポンスには [client_secret](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) が含まれ、クライアントはこれを使用して支払いを完了します。レスポンスで client secret を返します。

### 戻り先 URL を指定する

決済後に Stripe が顧客をリダイレクトする場所を定義するには、Checkout Session の作成時に [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url) パラメーターに戻りページの URL を指定します。決済の試行後、Stripe はウェブサイトでホストされている戻りページに顧客をリダイレクトします。

URL に `{CHECKOUT_SESSION_ID}` テンプレート変数を含めます。Checkout はこの変数を Checkout セッション ID に置き換えてから、顧客をリダイレクトします。自社のウェブサイトに戻り先ページを作成してホストすることはお客様の責任で行います。

### 販売する商品を定義する

Checkout Session の[商品と価格](https://docs.stripe.com/products-prices/manage-prices.md)を定義します。通常は、事前定義された商品の[価格 ID](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items-price) を使用します。ただし、事前に把握できない動的価格設定が必要な場合は、[price_data](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items-price_data) を使用して価格をインラインで定義します。

### 異なる取引タイプの処理

異なる取引タイプを扱うには、「[mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode)」パラメータを調整します：

- 一括払いの場合は、`payment` をご利用ください。
- [定期価格](https://docs.stripe.com/payments/subscriptions.md)を 1 つ以上お持ちの場合は、`subscription` をご利用ください。
- 顧客から最初の支払いを徴収していないが、[後で請求する](https://docs.stripe.com/payments/checkout/save-and-reuse.md?payment-ui=embedded-components)ために顧客の支払い情報を保存したい場合、`setup`を使用します。

### React アプリに Stripe を追加する

支払い情報を Stripe に直接送信し、お客様のサーバーには送信されないようにすることで *PCI 準拠* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business)を維持するには、[React Stripe.js](https://docs.stripe.com/sdks/stripejs-react.md) をインストールします。

```bash
npm install --save @stripe/react-stripe-js @stripe/stripe-js
```

### Stripe.js を読み込む

Stripe ライブラリを設定するには、Stripe の公開可能 API キーを使用して `loadStripe()` を呼び出します。

### Stripe.js を読み込む

*PCI 準拠* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business)を維持するには、*Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) を使用し、決済情報がサーバーを介することなく Stripe に直接送信されるようにします。Stripe.js を常に「js.stripe.com」から直接読み込むことにより、準拠が維持されます。スクリプトをバンドルに含めたり、自身でホストすることがないようにしてください。

Stripe.js を読み込むには、HTML ファイルにスクリプトを含めるか、[loadStripe](https://github.com/stripe/stripe-js/blob/master/README.md#loadstripe) を使用します。

### 支払いフォームを定義する

顧客情報を安全に収集するには、空のプレースホルダー `div` 要素を作成します。Stripe は各 `div` に iframe を挿入します。

### Stripe.js を初期化する

[公開可能な API キー](https://docs.stripe.com/keys.md#obtain-api-keys)で Stripe.js を初期化します。

### Checkout セッションの client secret を取得する

サーバーに [Checkout セッションの作成](https://docs.stripe.com/api/checkout/sessions/create.md)をリクエストし、client secret を取得します。

### Checkout を初期化する

`clientSecret` を使用して Checkout を初期化し、client secret 文字列またはそれを解決する Promise を渡します。[Checkout](https://docs.stripe.com/js/custom_checkout) オブジェクトは決済画面のバックボーンを形成し、Checkout セッションのデータとそれを更新するメソッドを含みます。

### Checkout を初期化する

[CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider) をレンダリングし、`clientSecret` (client secret 文字列、または client secret を解決する Promise) を渡します。

### 状態を設定する

支払いを記録し、エラーを表示し、ユーザーインターフェイスを管理するには、状態のいくつかを初期化します。

### Checkout への参照を保存する

`useCheckoutElements()` フックを使用して、CheckoutForm コンポーネント内の [checkout](https://docs.stripe.com/js/custom_checkout) オブジェクトにアクセスします。`checkout` オブジェクトは決済画面のバックボーンとして機能し、Checkout Session のデータとその更新メソッドを保持します。

### 顧客のメールアドレスを収集する

顧客のメールアドレスを収集するには、[Contact Details Element](https://docs.stripe.com/js/custom_checkout/create_contact_details_element) を使用します。これにより、メールアドレスの収集と検証が処理され、顧客の Link へのサインインが容易になります。

または、以下のいずれかの方法で顧客のメールアドレスを指定する場合には、このステップをスキップできます。

- Checkout Session の作成時に [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email) または [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) を渡します。Stripe はこの方法で指定されたメールアドレスを検証します。
  - これらを使用すると、顧客が決済画面で編集できないメールアドレスがセッションに事前入力されます。編集可能なメールアドレスを事前入力するには、決済の初期化時に [defaultValues.email](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-defaultValues-email) を使用します。
- [updateEmail](https://docs.stripe.com/js/custom_checkout/update_email) または [checkout.confirm](https://docs.stripe.com/js/custom_checkout/confirm) で検証済みのメールアドレスを渡します。

### 顧客のメールアドレスを収集する

顧客のメールアドレスを収集するには、[ContactDetails Element](https://docs.stripe.com/js/custom_checkout/create_contact_details_element) を使用します。これにより、メールアドレスの収集と検証が処理され、顧客の Link へのサインインが容易になります。

または、以下のいずれかの方法で顧客のメールアドレスを指定する場合には、このステップをスキップできます。

- Checkout Session の作成時に [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email) または [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) を渡します。Stripe はこの方法で指定されたメールアドレスを検証します。
  - これらを使用すると、顧客が決済画面で編集できないメールアドレスがセッションに事前入力されます。編集可能なメールアドレスを事前入力するには、決済の初期化時に [defaultValues.email](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-defaultValues-email) を使用します。
- [updateEmail](https://docs.stripe.com/js/react_stripe_js/checkout/update_email) または [confirm](https://docs.stripe.com/js/react_stripe_js/checkout/confirm) で検証済みのメールアドレスを渡します。

### Payment Element を追加する

[Payment Element](https://docs.stripe.com/js/custom_checkout/create_payment_element) を決済フォームに追加します。これにより、さまざまな決済手段の決済情報を収集する動的なフォームを備えた iframe が埋め込まれます。顧客は決済手段タイプを選択でき、フォームでは顧客の選択に応じて必要なすべての決済情報が自動的に収集されます。

### Payment Element を作成する

[Payment Element](https://docs.stripe.com/js/custom_checkout/create_payment_element) を作成し、それを決済フォームのプレースホルダー `<div>` にマウントします。これにより、設定済みの決済手段のタイプを表示する動的フォームを備えた iframe が埋め込まれ、顧客が決済手段を選択できます。このフォームでは、選択した決済手段タイプに関連付けられた決済情報が自動的に収集されます。

### (オプション) Payment Element のスタイルを設定する

[Appearance オブジェクト](https://docs.stripe.com/elements/appearance-api.md)を作成し、CheckoutElementsProvider にオプションとして渡すことで、Payment Element UI をカスタマイズできます。会社のカラースキームとフォントを使用して、決済画面の他の部分と一致させてください。[フォントセット](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-fonts)で Checkout を初期化することで、カスタムフォント (Google Fonts など) を使用できます。

必ず、右のプレビューを開き、変更内容が有効であることを確認してください。

このプレビューデモの一部は、実際の決済ページと一致しない場合があります。これらの設定は、[Appearanceオブジェクト](https://docs.stripe.com/payments/checkout/customization/appearance.md?payment-ui=embedded-components) の変数のサブセットのみを表しており、[Appearanceオブジェクト](https://docs.stripe.com/payments/checkout/customization/appearance.md?payment-ui=embedded-components) はStripe Elements の特定の属性のみを制御します。決済ページの残りの部分のスタイリングはお客様の責任です。

### (オプション) Payment Element のスタイルを設定する

[Appearance オブジェクト](https://docs.stripe.com/elements/appearance-api.md)を作成し、Checkout を初期化することで、Payment Element UI をカスタマイズできます。会社のカラースキームとフォントを使用して、決済ページの他の部分と一致させてください。[フォントセット](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-fonts)で決済を初期化することで、カスタムフォント (Google Fonts など) を使用できます。

必ず、右のプレビューを開き、変更内容が有効であることを確認してください。

このプレビューデモの一部は、実際の決済ページと一致しない場合があります。これらの設定は、[Appearanceオブジェクト](https://docs.stripe.com/payments/checkout/customization/appearance.md?payment-ui=embedded-components) の変数のサブセットのみを表しており、[Appearanceオブジェクト](https://docs.stripe.com/payments/checkout/customization/appearance.md?payment-ui=embedded-components) はStripe Elements の特定の属性のみを制御します。決済ページの残りの部分のスタイリングはお客様の責任です。

### 送信イベントを処理する

フォームの送信イベントをリッスンし、Stripe API を通じて支払いを確定するタイミングを認識できるようにします。

### 支払いを完了する

支払いボタンのクリックへの応答など、顧客が決済を完了する準備が整ったときに、[confirm](https://docs.stripe.com/js/custom_checkout/confirm) を呼び出します。

### エラーを処理する

即時[エラー](https://docs.stripe.com/error-codes.md)が発生した場合 (顧客のカードが拒否された場合など)、Stripe.js はエラーを返します。そのエラーメッセージを顧客に表示して、顧客が再試行できるようにします。

### エンドポイントを作成して Checkout セッションを取得する

エンドポイントを追加して Checkout セッションのステータスを取得します。

### 戻り先ページを追加する

顧客に注文情報を表示するには、Checkout セッション `return_url` として提供する URL の戻り先ページを作成します。顧客は支払いが完了すると、このページにリダイレクトされます。

### 戻り先コンポーネントを追加する

顧客に注文情報を表示するには、Checkout セッション `return_url` として提供する URL の新しいルートと戻り先コンポーネントを追加します。顧客は支払いが完了すると、このページにリダイレクトされます。

### Checkout セッションを取得する

戻り先ページが読み込まれたらすぐに、サーバー上のエンドポイントにリクエストを行います。URL の Checkout セッション ID を使用して Checkout セッションのステータスを取得します。

### セッションを処理する

次のステータスを使用してセッションの結果を処理します。

- `complete`: 支払いが成功しました。Checkout セッションの情報を使用して成功ページを表示します。
- `open`: 支払いが失敗またはキャンセルされました。顧客がやり直せるように Checkout を再度マウントします。

### アプリケーションを実行する

サーバーを起動し、<http://localhost:4242/checkout.html> に移動します。

### アプリケーションを実行する

サーバーを起動し、<http://localhost:3000/checkout> に移動します。

### サーバーアプリケーションを実行する

サーバーを起動します。

### クライアントアプリケーションを実行する

React アプリを起動し、<http://localhost:3000/checkout> に移動します。

```bash
npm start
```

### 試してみる

支払いボタンをクリックして支払いを完了します。指定した戻り先ページにリダイレクトされます。

戻り先ページが表示され、ダッシュボードで[成功した支払い](https://dashboard.stripe.com/test/payments?status%5B0%5D=successful)の一覧に支払いが表示されれば、実装は正常に機能しています。以下のテストカードを使用し、支払いをシミュレーションします。

| Scenario | Card Number |
| --- | --- |
| Payment succeeds | 4242424242424242 |
| Payment requires 3DS authentication | 4000002500003155 |
| Payment is declined | 4000000000009995 |

詳細については、[テスト](https://docs.stripe.com/testing.md)を参照してください。

## ご興味をお持ちいただき、ありがとうございます。

基本的な Checkout の実装が完了しました。次に、決済画面の外観のカスタマイズ、税金徴収の自動化、顧客の作成、決済手段の保存、通貨のローカライズについて学びましょう。

### 追加機能を有効にする

住所の収集や顧客データの事前入力などの追加機能を有効にするには、[Checkout Sessions](https://docs.stripe.com/api/checkout/sessions/create.md) を使用します。

### 顧客データを事前入力する

顧客のメールアドレスを事前入力するには、次の 2 つの方法があります。

- **変更できない事前入力**: Checkout Session の作成時に [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email)、[customer_account](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_account) (顧客が設定した `Account` ID)、または [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) (`Customer` ID) を渡します。これらを使用すると、顧客が決済画面で編集できないメールアドレスがセッションに事前入力されるため、フォームから連絡先情報 Element を省略できます。詳しくは、[Customer と Account を使用する場合の違い](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md)をご覧ください。
- **変更可能な事前入力**: Checkout の初期化時に [defaultValues.email](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-defaultValues-email) を渡します。これにより、顧客が決済画面で編集できるメールアドレスがメールアドレスフィールドに事前入力されます。顧客がフローの早い段階でメールアドレスを提供したものの、決済中に変更する可能性がある場合に使用します。

### 請求先情報と配送先情報を要求する

顧客の住所を必須にするには、[billing_address_collection](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-billing_address_collection) と [shipping_address_collection](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-shipping_address_collection) を使用します。[shipping_address_collection](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-shipping_address_collection) では `allowed_countries` のリストが必須であり、決済ページのドロップダウンメニューに表示されます。サンプルでは例として `US` と `CA` を使用しています。これらの値を、配送先の国の 2 文字の ISO 国コードに置き換えます。

### 請求先詳細および配送先詳細を収集する

Address Element を使用して顧客の住所を収集します。

### 税金の徴収を自動化する

Stripe 取引の適切な税額を計算して徴収します。[Stripe Tax](https://docs.stripe.com/tax.md) と [Checkout への追加方法](https://docs.stripe.com/tax/checkout.md)の詳細をご確認ください。

### ダッシュボードで Stripe Tax を設定する

[Stripe Tax を有効](https://dashboard.stripe.com/settings/tax/activate)にして、納税義務のモニタリングや、税金の自動徴収、納税申告書の提出に必要なレポートの表示などを行います。

### 税金の自動計算パラメーターを追加する

`automatic_tax` パラメーターを `enabled: true` に設定します。

### 請求詳細を収集する

Address Element を使用して顧客の住所を収集します。

### 決済時に顧客を作成

決済履歴の追跡、購入内容の関連付け、フィールドの事前入力を行うには、Checkout Session ごとに顧客を作成します。[顧客の管理](https://docs.stripe.com/customer-management.md)の詳細はこちら。

### 顧客作成パラメーターを追加

`customer_creation` パラメーターを `always` に設定すると、Checkout Session が完了するたびに新しい顧客が作成されます。

### リピーター顧客を指定

Checkout Session を既存の顧客に関連付けるには、セッションの作成時に [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) を指定します。Accounts v2 を使用して顧客をモデル化する場合は、[customer_account](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_account) フィールドに Account ID を渡して、関連付けられたメールアドレスを事前入力することもできます。[v1 Customer と v2 Account の違い](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md)について、詳細を表示。

### 顧客の決済手段を保存

決済時に顧客が今後の購入のために決済手段を保存できるようにします。[決済時の決済手段の保存方法](https://docs.stripe.com/payments/save-during-payment.md)の詳細はこちら。

### 保存済み決済手段パラメーターを追加

`saved_payment_method_options` 内で `payment_method_save` を `enabled` に設定します。既存の顧客の ID を指定するか (`Customer` オブジェクトを使用する場合は [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer)、顧客が設定した `Account` オブジェクトを使用する場合は [customer_account](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_account))、または [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_creation) を `always` に設定する必要があります。

### 通貨のローカライズ

Adaptive Pricing を使用すると、顧客は 150 カ国以上の現地通貨での支払いが可能になります。

### Adaptive Pricing を有効にする

ダッシュボード設定で [Adaptive Pricing を有効](https://dashboard.stripe.com/settings/adaptive-pricing)にします。

### 地域に合わせた料金設定と表示形式

[Session オブジェクト](https://docs.stripe.com/js/custom_checkout/session_object)からローカライズおよびフォーマットされた金額を表示します。

### 地域に合わせた料金設定と表示形式

[useCheckoutElements](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout_elements) フックからローカライズおよびフォーマットされた金額を表示します。

### Currency Selector Element のレンダリング

Currency Selector Element をマウントして、顧客に通貨の選択肢を提供し、為替レートを開示します。

### Adaptive Pricing の統合を準備完了とマークする

`adaptivePricing.allowed` パラメーターを `true` に設定します。

// This is a public sample test API key.
// Don't submit any personally identifiable information in requests made with this key.
// To see your own test secret API key embedded in code samples, sign in to your Stripe account.
// You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys.
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
const stripe = require("stripe")("<<YOUR_SECRET_KEY>>");
const YOUR_DOMAIN = "http://localhost:4242";
const YOUR_DOMAIN = "http://localhost:3000";
  const session = await stripe.checkout.sessions.create({

    ui_mode: "elements",
    customer_email: "customer@example.com",
    billing_address_collection: "auto",
    shipping_address_collection: {
      allowed_countries: ["US", "CA"],
    },
    line_items: [
      {
        // Provide the exact Price ID (for example, price_1234) of the product you want to sell
        price: "{{PRICE_ID}}",
        quantity: 1,
      },
    ],
    line_items: [{
      price_data: {
        product_data: {
          name: "{{PRICE_DATA_NAME}}",
        },
        currency: "{{PRICE_DATA_CURRENCY}}",
        unit_amount: {{PRICE_DATA_UNIT_AMOUNT}},
      },
      quantity: 1,
    }],
    line_items: [{
      price_data: {
        product_data: {
          name: "{{PRICE_DATA_NAME}}",
        },
        currency: "{{PRICE_DATA_CURRENCY}}",
        unit_amount: {{PRICE_DATA_UNIT_AMOUNT}},
        recurring: {
          interval: "{{PRICE_DATA_INTERVAL}}",
          interval_count: {{PRICE_DATA_INTERVAL_COUNT}},
        },
      },
      quantity: 1,
    }],
    mode: {{CHECKOUT_MODE}},
    return_url: `${YOUR_DOMAIN}/complete?session_id={CHECKOUT_SESSION_ID}`,
    return_url: `${YOUR_DOMAIN}/complete.html?session_id={CHECKOUT_SESSION_ID}`,
    automatic_tax: {enabled: true},
    customer_creation: 'always',
    saved_payment_method_options: {
      payment_method_save: 'enabled',
    },
  });

  res.send({ clientSecret: session.client_secret });
app.get("/session-status", async (req, res) => {
  const session = await stripe.checkout.sessions.retrieve(req.query.session_id, {expand: ["payment_intent", "subscription"]});

   res.send({
    status: session.status,
    payment_status: session.payment_status,
    payment_intent_id: session.payment_intent?.id,
    payment_intent_status: session.payment_intent?.status,
    subscription_id: session.payment_intent ? null : session.subscription?.id,
    subscription_status: session.payment_intent ? null : session.subscription?.status
  });
});
{
  "name": "stripe-sample",
  "version": "1.0.0",
  "description": "A sample Stripe implementation",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "author": "stripe-samples",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "stripe": "^22.4.0"
  }
}
{
  "name": "stripe-sample",
  "version": "0.1.0",
  "dependencies": {
    "@stripe/react-stripe-js": "^3.7.0",
    "@stripe/stripe-js": "^7.3.0",
    "express": "^4.17.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "^3.4.0",
    "stripe": "22.4.0"
  },
  "devDependencies": {
    "concurrently": "4.1.2"
  },
  "homepage": "http://localhost:3000/checkout",
  "proxy": "http://localhost:4242",
  "scripts": {
    "start-client": "react-scripts start",
    "start-server": "node server.js",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "start": "concurrently \"npm run start-client\" \"npm run start-server\""
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
\# This is a public sample test API key.
# Don't submit any personally identifiable information in requests made with this key.
# To see your own test secret API key embedded in code samples, sign in to your Stripe account.
# You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys.
\# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>', stripe_version: '2026-07-29.dahlia')
YOUR_DOMAIN = 'http://localhost:4242'
YOUR_DOMAIN = 'http://localhost:3000'
  session = client.v1.checkout.sessions.create({

    ui_mode: 'elements',
    customer_email: 'customer@example.com',
    billing_address_collection: 'required',
    shipping_address_collection: {
      allowed_countries: ['US', 'CA'],
    },
    line_items: [{
      \# Provide the exact Price ID (for example, price_1234) of the product you want to sell
      price: '{{PRICE_ID}}',
      quantity: 1,
    }],
    line_items: [{
      price_data: {
        product_data: {
          name: '{{PRICE_DATA_NAME}}',
        },
        currency: '{{PRICE_DATA_CURRENCY}}',
        unit_amount: {{PRICE_DATA_UNIT_AMOUNT}},
      },
      quantity: 1,
    }],
    line_items: [{
      price_data: {
        product_data: {
          name: '{{PRICE_DATA_NAME}}',
        },
        currency: '{{PRICE_DATA_CURRENCY}}',
        unit_amount: {{PRICE_DATA_UNIT_AMOUNT}},
        recurring: {
          interval: '{{PRICE_DATA_INTERVAL}}',
          interval_count: {{PRICE_DATA_INTERVAL_COUNT}},
        },
      },
      quantity: 1,
    }],
    mode: {{CHECKOUT_MODE}},
    return_url: YOUR_DOMAIN + '/complete.html?session_id={CHECKOUT_SESSION_ID}',
    return_url: YOUR_DOMAIN + '/complete?session_id={CHECKOUT_SESSION_ID}',
    automatic_tax: {enabled: true},
    customer_creation: 'always',
    saved_payment_method_options: {
      payment_method_save: 'enabled',
    },
  })

  { clientSecret: session.client_secret }.to_json
get '/session-status' do
  session = client.v1.checkout.sessions.retrieve(params[:session_id], {expand: ["payment_intent", "subscription"]})

  { status: session.status, payment_status: session.payment_status, payment_intent_id: session.payment_intent&.id, payment_intent_status: session.payment_intent&.status, subscription_id: session.payment_intent ? nil : session.subscription&.id, subscription_status: session.payment_intent ? nil : session.subscription&.status }.to_json
end
import stripe
\# This is a public sample test API key.
# Don't submit any personally identifiable information in requests made with this key.
# To see your own test secret API key embedded in code samples, sign in to your Stripe account.
# You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys.
client = stripe.StripeClient(
    \# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
    '<<YOUR_SECRET_KEY>>',
    stripe_version='2026-07-29.dahlia',
)
YOUR_DOMAIN = 'http://localhost:4242'
YOUR_DOMAIN = 'http://localhost:3000'
        session = client.v1.checkout.sessions.create(params={
            'ui_mode': 'elements',
            'customer_email': 'customer@example.com',
            'billing_address_collection': 'auto',
            'shipping_address_collection': {
              'allowed_countries': ['US', 'CA'],
            },
            'line_items': [
                {
                    \# Provide the exact Price ID (for example, price_1234) of the product you want to sell
                    'price': '{{PRICE_ID}}',
                    'quantity': 1,
                },
            ],
            'line_items': [
                {
                    'price_data': {
                      'product_data': {
                        'name': '{{PRICE_DATA_NAME}}',
                      },
                      'currency': '{{PRICE_DATA_CURRENCY}}',
                      'unit_amount': {{PRICE_DATA_UNIT_AMOUNT}},
                    },
                    'quantity': 1,
                },
            ],
            'line_items': [
                {
                    'price_data': {
                      'product_data': {
                        'name': '{{PRICE_DATA_NAME}}',
                      },
                      'currency': '{{PRICE_DATA_CURRENCY}}',
                      'unit_amount': {{PRICE_DATA_UNIT_AMOUNT}},
                      'recurring': {
                        'interval': '{{PRICE_DATA_INTERVAL}}',
                        'interval_count': {{PRICE_DATA_INTERVAL_COUNT}},
                      },
                    },
                    'quantity': 1,
                },
            ],
            'mode': {{CHECKOUT_MODE}},
            'return_url': YOUR_DOMAIN + '/complete.html?session_id={CHECKOUT_SESSION_ID}',
            'return_url': YOUR_DOMAIN + '/complete?session_id={CHECKOUT_SESSION_ID}',
            'automatic_tax': {'enabled': True},
            'customer_creation': 'always',
            'saved_payment_method_options': {
              'payment_method_save': 'enabled',
            },
        })
    return jsonify(clientSecret=session.client_secret)
@app.route('/session-status', methods=['GET'])
def session_status():
  session = client.v1.checkout.sessions.retrieve(request.args.get('session_id'), params={'expand': ["payment_intent", "subscription"]})

  return jsonify(status=session.status, payment_status=session.payment_status, payment_intent_id=session.payment_intent.id if session.payment_intent else None, payment_intent_status=session.payment_intent.status if session.payment_intent else None, subscription_id=None if session.payment_intent else (session.subscription.id if session.subscription else None), subscription_status=None if session.payment_intent else (session.subscription.status if session.subscription else None))
certifi==2026.1.4
chardet==5.2.0
click==8.3.1
Flask==3.1.2
idna==3.11
itsdangerous==2.2.0
Jinja2==3.1.6
MarkupSafe==3.0.3
requests==2.32.5
stripe==15.4.0
toml==0.10.2
Werkzeug==3.1.5
$stripe = new \Stripe\StripeClient([
  "api_key" => $stripeSecretKey,
  "stripe_version" => "2026-07-29.dahlia"
]);
$YOUR_DOMAIN = 'http://localhost:4242';
$YOUR_DOMAIN = 'http://localhost:3000';

$checkout_session = $stripe->checkout->sessions->create([

  'ui_mode' => 'elements',
  'customer_email' => 'customer@example.com',
  'billing_address_collection' => 'required',
  'shipping_address_collection' => [
    'allowed_countries' => ['US', 'CA'],
  ],
  'line_items' => [[
    \# Provide the exact Price ID (for example, price_1234) of the product you want to sell
    'price' => '{{PRICE_ID}}',
    'quantity' => 1,
  ]],
  'line_items' => [[
      'price_data' => [
        'product_data' => [
          'name' => '{{PRICE_DATA_NAME}}',
        ],
        'currency' => '{{PRICE_DATA_CURRENCY}}',
        'unit_amount' => {{PRICE_DATA_UNIT_AMOUNT}},
      ],
    'quantity' => 1,
  ]],
  'line_items' => [[
      'price_data' => [
        'product_data' => [
          'name' => '{{PRICE_DATA_NAME}}',
        ],
        'currency' => '{{PRICE_DATA_CURRENCY}}',
        'unit_amount' => {{PRICE_DATA_UNIT_AMOUNT}},
        'recurring' => [
          'interval' => '{{PRICE_DATA_INTERVAL}}',
          'interval_count' => {{PRICE_DATA_INTERVAL_COUNT}},
        ],
      ],
    'quantity' => 1,
  ]],
  'mode' => {{CHECKOUT_MODE}},
  'return_url' => $YOUR_DOMAIN . '/complete.html?session_id={CHECKOUT_SESSION_ID}',
  'return_url' => $YOUR_DOMAIN . '/complete?session_id={CHECKOUT_SESSION_ID}',
  'automatic_tax' => [
    'enabled' => true,
  ],
  'customer_creation' => 'always',
  'saved_payment_method_options' => [
    'payment_method_save' => 'enabled',
  ],
]);

echo json_encode(array('clientSecret' => $checkout_session->client_secret));
try {
  // retrieve JSON from POST body
  $jsonStr = file_get_contents('php://input');
  $jsonObj = json_decode($jsonStr);

  $session = $stripe->checkout->sessions->retrieve($jsonObj->session_id, ['expand' => ['payment_intent', 'subscription']]);

  echo json_encode(['status' => $session->status, 'payment_status' => $session->payment_status, 'payment_intent_id' => $session->payment_intent?->id, 'payment_intent_status' => $session->payment_intent?->status, 'subscription_id' => $session->payment_intent ? null : $session->subscription?->id, 'subscription_status' => $session->payment_intent ? null : $session->subscription?->status]);
  http_response_code(200);
} catch (Error $e) {
  http_response_code(500);
  echo json_encode(['error' => $e->getMessage()]);
}
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
$stripeSecretKey = '<<YOUR_SECRET_KEY>>';
          // This is a public sample test API key.
          // Don't submit any personally identifiable information in requests made with this key.
          // To see your own test secret API key embedded in code samples, sign in to your Stripe account.
          // You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys.
          // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
          services.AddSingleton(new StripeClient("<<YOUR_SECRET_KEY>>"));
            var domain = "http://localhost:4242";
            var domain = "http://localhost:3000";

                UiMode = "elements",
                CustomerEmail = "customer@example.com",
                BillingAddressCollection = "auto",
                ShippingAddressCollection = new SessionShippingAddressCollectionOptions
                {
                  AllowedCountries = new List<string>
                  {
                    "US",
                    "CA",
                  },
                },
                LineItems = new List<SessionLineItemOptions>
                {
                  new SessionLineItemOptions
                  {
                    // Provide the exact Price ID (for example, price_1234) of the product you want to sell
                    Price = "{{PRICE_ID}}",
                    Quantity = 1,
                  },
                },
                LineItems = new List<SessionLineItemOptions>
                {
                  new SessionLineItemOptions
                  {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                      ProductData = new SessionLineItemPriceDataProductDataOptions
                      {
                        Name = "{{PRICE_DATA_NAME}}",
                      },
                      Currency = "{{PRICE_DATA_CURRENCY}}",
                      UnitAmount = {{PRICE_DATA_UNIT_AMOUNT}},
                    },
                    Quantity = 1,
                  },
                },
                LineItems = new List<SessionLineItemOptions>
                {
                  new SessionLineItemOptions
                  {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                      ProductData = new SessionLineItemPriceDataProductDataOptions
                      {
                        Name = "{{PRICE_DATA_NAME}}",
                      },
                      Currency = "{{PRICE_DATA_CURRENCY}}",
                      UnitAmount = {{PRICE_DATA_UNIT_AMOUNT}},
                      Recurring = new SessionLineItemPriceDataRecurringOptions
                      {
                        Interval = "{{PRICE_DATA_INTERVAL}}",
                        IntervalCount = {{PRICE_DATA_INTERVAL_COUNT}},
                      },
                    },
                    Quantity = 1,
                  },
                },
                Mode = {{CHECKOUT_MODE}},
                ReturnUrl = domain + "/complete.html?session_id={CHECKOUT_SESSION_ID}",
                ReturnUrl = domain + "/complete?session_id={CHECKOUT_SESSION_ID}",
                AutomaticTax = new SessionAutomaticTaxOptions { Enabled = true },
                CustomerCreation = "always",
                SavedPaymentMethodOptions = new SessionSavedPaymentMethodOptionsOptions
                {
                    PaymentMethodSave = "enabled",
                },
            Session session = _client.V1.Checkout.Sessions.Create(options);

            return Json(new {clientSecret = session.ClientSecret});
    [Route("session-status")]
    [ApiController]
    public class SessionStatusController : Controller
    {
        private readonly StripeClient _client;

        public SessionStatusController(StripeClient client)
        {
            _client = client;
        }

        [HttpGet]
        public ActionResult SessionStatus([FromQuery] string session_id)
        {
            var options = new SessionGetOptions();
            options.AddExpand("payment_intent");
            options.AddExpand("subscription");
            Session session = _client.V1.Checkout.Sessions.Get(session_id, options);

            return Json(new {status = session.Status, payment_status = session.PaymentStatus, payment_intent_id = session.PaymentIntent?.Id, payment_intent_status = session.PaymentIntent?.Status, subscription_id = session.PaymentIntent != null ? null : session.Subscription?.Id, subscription_status = session.PaymentIntent != null ? null : session.Subscription?.Status});
        }
    }
    "github.com/stripe/stripe-go/v86"
  // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
  sc := stripe.NewClient("<<YOUR_SECRET_KEY>>")
  domain := "http://localhost:4242"
  domain := "http://localhost:3000"
  params := &stripe.CheckoutSessionCreateParams{

    UIMode: stripe.String("elements"),
    ReturnURL: stripe.String(domain + "/complete.html?session_id={CHECKOUT_SESSION_ID}"),
    ReturnURL: stripe.String(domain + "/complete?session_id={CHECKOUT_SESSION_ID}"),
    CustomerEmail: stripe.String("customer@example.com"),
    BillingAddressCollection: stripe.String("auto"),
    ShippingAddressCollection: &stripe.CheckoutSessionCreateShippingAddressCollectionParams{
      AllowedCountries: stripe.StringSlice([]string{
        "US",
        "CA",
      }),
    },
    LineItems: []*stripe.CheckoutSessionCreateLineItemParams{
      {
        // Provide the exact Price ID (for example, price_1234) of the product you want to sell
        Price: stripe.String("{{PRICE_ID}}"),
        Quantity: stripe.Int64(1),
      },
    },
    LineItems: []*stripe.CheckoutSessionCreateLineItemParams{
      {
        PriceData: &stripe.CheckoutSessionCreateLineItemPriceDataParams{
          ProductData: &stripe.CheckoutSessionCreateLineItemPriceDataProductDataParams{
            Name: stripe.String("{{PRICE_DATA_NAME}}"),
          },
          Currency: stripe.String("{{PRICE_DATA_CURRENCY}}"),
          UnitAmount: stripe.Int64({{PRICE_DATA_UNIT_AMOUNT}}),
        },
        Quantity: stripe.Int64(1),
      },
    },
    LineItems: []*stripe.CheckoutSessionCreateLineItemParams{
      {
        PriceData: &stripe.CheckoutSessionCreateLineItemPriceDataParams{
          ProductData: &stripe.CheckoutSessionCreateLineItemPriceDataProductDataParams{
            Name: stripe.String("{{PRICE_DATA_NAME}}"),
          },
          Currency: stripe.String("{{PRICE_DATA_CURRENCY}}"),
          UnitAmount: stripe.Int64({{PRICE_DATA_UNIT_AMOUNT}}),
          Recurring: &stripe.CheckoutSessionCreateLineItemPriceDataRecurringParams{
            Interval: stripe.String("{{PRICE_DATA_INTERVAL}}"),
            IntervalCount: stripe.Int64({{PRICE_DATA_INTERVAL_COUNT}}),
          },
        },
        Quantity: stripe.Int64(1),
      },
    },
    Mode: {{CHECKOUT_MODE}},
    AutomaticTax: &stripe.CheckoutSessionCreateAutomaticTaxParams{Enabled: stripe.Bool(true)},
    CustomerCreation: stripe.String("always"),
    SavedPaymentMethodOptions: &stripe.CheckoutSessionCreateSavedPaymentMethodOptionsParams{
      PaymentMethodSave: stripe.String("enabled"),
    },
  }

  s, err := sc.V1CheckoutSessions.Create(context.TODO(), params)

  if err != nil {
    log.Printf("sc.V1CheckoutSessions.Create: %v", err)
  }

  writeJSON(w, struct {
    ClientSecret string `json:"clientSecret"`
  }{
    ClientSecret: s.ClientSecret,
  })
func retrieveCheckoutSession(sc *stripe.Client, w http.ResponseWriter, r *http.Request) {
  params := &stripe.CheckoutSessionRetrieveParams{}
  params.AddExpand("payment_intent")
  params.AddExpand("subscription")
  s, _ := sc.V1CheckoutSessions.Retrieve(context.TODO(), r.URL.Query().Get("session_id"), params)

  var paymentIntentId, paymentIntentStatus string
  var subscriptionId, subscriptionStatus string
  if s.PaymentIntent != nil {
    paymentIntentId = string(s.PaymentIntent.ID)
    paymentIntentStatus = string(s.PaymentIntent.Status)
  } else if s.Subscription != nil {
    subscriptionId = string(s.Subscription.ID)
    subscriptionStatus = string(s.Subscription.Status)
  }

  writeJSON(w, struct {
    Status string `json:"status"`
    PaymentStatus string `json:"payment_status"`
    PaymentIntentId string `json:"payment_intent_id"`
    PaymentIntentStatus string `json:"payment_intent_status"`
    SubscriptionId string `json:"subscription_id"`
    SubscriptionStatus string `json:"subscription_status"`
  }{
    Status: string(s.Status),
    PaymentStatus: string(s.PaymentStatus),
    PaymentIntentId: paymentIntentId,
    PaymentIntentStatus: paymentIntentStatus,
    SubscriptionId: subscriptionId,
    SubscriptionStatus: subscriptionStatus,
  })
}
require github.com/stripe/stripe-go/v86 v86.2.0
    // This is a public sample test API key.
    // Don't submit any personally identifiable information in requests made with this key.
    // To see your own test secret API key embedded in code samples, sign in to your Stripe account.
    // You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys.
    // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
    StripeClient client = new StripeClient("<<YOUR_SECRET_KEY>>");
        String YOUR_DOMAIN = "http://localhost:4242";
        String YOUR_DOMAIN = "http://localhost:3000";
        SessionCreateParams params =
          SessionCreateParams.builder()

            .setUiMode(SessionCreateParams.UiMode.ELEMENTS)
            .setCustomerEmail("customer@example.com")
            .setBillingAddressCollection(SessionCreateParams.BillingAddressCollection.REQUIRED)
            .setShippingAddressCollection(
              SessionCreateParams.ShippingAddressCollection.builder()
                .addAllowedCountry(SessionCreateParams.ShippingAddressCollection.AllowedCountry.CA)
                .addAllowedCountry(SessionCreateParams.ShippingAddressCollection.AllowedCountry.US)
                .build())
            .setMode({{CHECKOUT_MODE}})
            .setReturnUrl(YOUR_DOMAIN + "/complete?session_id={CHECKOUT_SESSION_ID}")
            .setReturnUrl(YOUR_DOMAIN + "/complete.html?session_id={CHECKOUT_SESSION_ID}")
            .setAutomaticTax(
              SessionCreateParams.AutomaticTax.builder()
                .setEnabled(true)
                .build())
            .setCustomerCreation(SessionCreateParams.CustomerCreation.ALWAYS)
            .setSavedPaymentMethodOptions(
              SessionCreateParams.SavedPaymentMethodOptions.builder()
                .setPaymentMethodSave(SessionCreateParams.SavedPaymentMethodOptions.PaymentMethodSave.ENABLED)
                .build())
            .addLineItem(
              SessionCreateParams.LineItem.builder()
                .setQuantity(1L)
                // Provide the exact Price ID (for example, price_1234) of the product you want to sell
                .setPrice("{{PRICE_ID}}")
                .build())
            .addLineItem(
              SessionCreateParams.LineItem.builder()
                .setQuantity(1L)
                .setPriceData(
                  SessionCreateParams.LineItem.PriceData.builder()
                  .setProductData(
                    SessionCreateParams.LineItem.PriceData.ProductData.builder()
                    .setName("{{PRICE_DATA_NAME}}")
                    .build())
                  .setCurrency("{{PRICE_DATA_CURRENCY}}")
                  .setUnitAmount({{PRICE_DATA_UNIT_AMOUNT}}L)
                  .build())
                .build())
            .addLineItem(
              SessionCreateParams.LineItem.builder()
                .setQuantity(1L)
                .setPriceData(
                  SessionCreateParams.LineItem.PriceData.builder()
                  .setProductData(
                    SessionCreateParams.LineItem.PriceData.ProductData.builder()
                    .setName("{{PRICE_DATA_NAME}}")
                    .build())
                  .setCurrency("{{PRICE_DATA_CURRENCY}}")
                  .setUnitAmount({{PRICE_DATA_UNIT_AMOUNT}}L)
                  .setRecurring(
                    SessionCreateParams.LineItem.PriceData.Recurring.builder()
                    .setInterval(SessionCreateParams.LineItem.PriceData.Recurring.Interval.{{PRICE_DATA_INTERVAL}})
                    .setIntervalCount({{PRICE_DATA_INTERVAL_COUNT}}L)
                    .build())
                  .build())
                .build())
            .build();
      Map<String, String> map = new HashMap();
      map.put("clientSecret", session.getRawJsonObject().getAsJsonPrimitive("client_secret").getAsString());


      return map;
    get("/session-status", (request, response) -> {
      RequestOptions options = RequestOptions.builder().build();
      SessionRetrieveParams params =
        SessionRetrieveParams.builder().addExpand("payment_intent").addExpand("subscription").build();
      Session session = client.v1().checkout().sessions().retrieve(request.queryParams("session_id"), params, options);

      Map<String, String> map = new HashMap();
      map.put("status", session.getRawJsonObject().getAsJsonPrimitive("status").getAsString());
      map.put("payment_status", session.getRawJsonObject().getAsJsonPrimitive("payment_status").getAsString());
      var paymentIntentJson = session.getRawJsonObject().get("payment_intent");
      if (paymentIntentJson != null && paymentIntentJson.isJsonObject()) {
        map.put("payment_intent_id", paymentIntentJson.getAsJsonObject().getAsJsonPrimitive("id").getAsString());
        map.put("payment_intent_status", paymentIntentJson.getAsJsonObject().getAsJsonPrimitive("status").getAsString());
      } else {
        var subscriptionJson = session.getRawJsonObject().get("subscription");
        if (subscriptionJson != null && subscriptionJson.isJsonObject()) {
          map.put("subscription_id", subscriptionJson.getAsJsonObject().getAsJsonPrimitive("id").getAsString());
          map.put("subscription_status", subscriptionJson.getAsJsonObject().getAsJsonPrimitive("status").getAsString());
        }
      }

      return map;
    }, gson::toJson);
    <script src="https://js.stripe.com/dahlia/stripe.js"></script>
    <form id="payment-form">
      <div id="contact-details-element">
        <!--Stripe.js injects the Contact Details Element-->
      </div>
      <h4>Billing Address</h4>
      <div id="billing-address-element">
        <!--Stripe.js injects the Address Element-->
      </div>
      <h4>Billing Address</h4>
      <div id="billing-address-element">
        <!--Stripe.js injects the Address Element-->
      </div>
      <h4>Shipping Address</h4>
      <div id="shipping-address-element">
        <!--Stripe.js injects the Address Element-->
      </div>
      <h4>Payment</h4>
      <div id="currency-selector-element">
        <!--Stripe.js injects the Currency Selector Element-->
      </div>
      <div id="payment-element">
        <!--Stripe.js injects the Payment Element-->
      </div>
      <button id="submit">
        <div class="spinner hidden" id="spinner"></div>
        <span id="button-text">Pay now</span>
      </button>
      <div id="payment-message" class="hidden"></div>
    </form>
const stripe = Stripe("<<YOUR_PUBLISHABLE_KEY>>");
  const promise = fetch("/create-checkout-session", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
  })
    .then((r) => r.json())
    .then((r) => r.clientSecret);
  const promise = fetch('/create.php', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
  })
    .then((r) => r.json())
    .then((r) => r.clientSecret);
  const appearance = {
    {{APPEARANCE}}
  };

  checkout = stripe.initCheckoutElementsSdk({
    clientSecret: promise,
    elementsOptions: { appearance },
    adaptivePricing: { allowed: true },
  });
  checkout.on('change', (session) => {
    // Handle changes to the checkout session
    document.getElementById('submit').disabled = !session.canConfirm;
    document.querySelector("#button-text").textContent = `Pay ${
      session.total.total.amount
    } now`;
  });
  const contactDetailsElement = checkout.createContactDetailsElement();
  contactDetailsElement.mount("#contact-details-element");
  const paymentElement = checkout.createPaymentElement();
  paymentElement.mount("#payment-element");
  const billingAddressElement = checkout.createBillingAddressElement();
  billingAddressElement.mount("#billing-address-element");
  const billingAddressElement = checkout.createBillingAddressElement();
  billingAddressElement.mount("#billing-address-element");
  const shippingAddressElement = checkout.createShippingAddressElement();
  shippingAddressElement.mount("#shipping-address-element");
  const currencySelectorElement = checkout.createCurrencySelectorElement();
  currencySelectorElement.mount("#currency-selector-element");
async function handleSubmit(e) {
  e.preventDefault();
  setLoading(true);

  const confirmResult = await actions.confirm();

  // This point will only be reached if there is an immediate error when
  // confirming the payment. Otherwise, your customer will be redirected to
  // your `return_url`. For some payment methods like iDEAL, your customer will
  // be redirected to an intermediate site first to authorize the payment, then
  // redirected to the `return_url`.
  if (confirmResult.type === 'error') {
    showMessage(confirmResult.error.message);
  }

  setLoading(false);
}
    <script src="https://js.stripe.com/dahlia/stripe.js"></script>
    <script src="complete.js" defer></script>
  const queryString = window.location.search;
  const urlParams = new URLSearchParams(queryString);
  const sessionId = urlParams.get("session_id");
  if (!sessionId) {
    console.log("No session ID found");
    setErrorState();
    return;
  }
  const response = await fetch(`/session-status?session_id=${sessionId}`);
  const response = await fetch("/status.php", {
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    method: "POST",
    body: JSON.stringify({ session_id: sessionId }),
  });
  const session = await response.json();
  setSessionDetails(session);
{
  "name": "stripe-sample",
  "version": "0.1.0",
  "dependencies": {
    "@stripe/react-stripe-js": "^6.0.0",
    "@stripe/stripe-js": "^9.0.0",
    "express": "^4.17.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.16.0",
    "stripe": "^8.202.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.3.0",
    "concurrently": "^8.2.0",
    "vite": "^5.2.11"
  },
  "scripts": {
    "start-client": "vite",
    "start-server": "node server.js",
    "build": "vite build",
    "start": "concurrently \"yarn start-client\" \"yarn start-server\""
  }
}
{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@stripe/react-stripe-js": "^6.0.0",
    "@stripe/stripe-js": "^9.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.16.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.3.0",
    "vite": "^5.2.11"
  },
  "scripts": {
    "start": "vite",
    "build": "vite build"
  }
}
import React, { useMemo } from "react";
import {loadStripe} from '@stripe/stripe-js';

import {
  CheckoutElementsProvider
} from '@stripe/react-stripe-js/checkout';
// Make sure to call `loadStripe` outside of a component's render to avoid
// recreating the `Stripe` object on every render.
// This is a public sample test API key.
// Don't submit any personally identifiable information in requests made with this key.
// Sign in to see your own test publishable API key embedded in code samples.
// You can also find your test publishable API key at https://dashboard.stripe.com/test/apikeys.
const stripePromise = loadStripe("<<YOUR_PUBLISHABLE_KEY>>");
  const clientSecret = useMemo(() => {
    return fetch('/create-checkout-session', {
      method: 'POST',
    })
      .then((res) => res.json())
      .then((data) => data.clientSecret);
  }, []);
  const clientSecret = useMemo(() => {
    return fetch('/create.php', {
      method: 'POST',
    })
      .then((res) => res.json())
      .then((data) => data.clientSecret);
  }, []);
  const appearance = {
    {{APPEARANCE}}
  };

        <CheckoutElementsProvider
          stripe={stripePromise}
          options={{
            clientSecret,
            elementsOptions: {appearance},
            adaptivePricing: { allowed: true },
          }}
        >
          <Routes>
            <Route path="/checkout" element={<CheckoutForm />} />
            <Route path="/complete" element={<Complete />} />
          </Routes>
        </CheckoutElementsProvider>
  ContactDetailsElement,
  BillingAddressElement,
  BillingAddressElement,
  ShippingAddressElement,
  CurrencySelectorElement,
  const [message, setMessage] = useState(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const checkoutState = useCheckoutElements();

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  }

  if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }
  const handleSubmit = async (e) => {
    e.preventDefault();

    const {checkout} = checkoutState;
    setIsSubmitting(true);

    const confirmResult = await checkout.confirm();

    // This point will only be reached if there is an immediate error when
    // confirming the payment. Otherwise, your customer will be redirected to
    // your `return_url`. For some payment methods like iDEAL, your customer will
    // be redirected to an intermediate site first to authorize the payment, then
    // redirected to the `return_url`.
    if (confirmResult.type === 'error') {
      setMessage(confirmResult.error.message);
    }

    setIsSubmitting(false);
  };
      <h4>Contact Details</h4>
      <ContactDetailsElement/>
      <h4>Billing Address</h4>
      <BillingAddressElement/>
      <h4>Billing Address</h4>
      <BillingAddressElement/>
      <h4>Shipping Address</h4>
      <ShippingAddressElement/>
      <CurrencySelectorElement/>
      <PaymentElement id="payment-element" />
          `Pay ${checkoutState.checkout.total.total.amount} now`
  const [status, setStatus] = useState(null);
  const [paymentIntentId, setPaymentIntentId] = useState('');
  const [paymentStatus, setPaymentStatus] = useState('');
  const [paymentIntentStatus, setPaymentIntentStatus] = useState('');
  const [subscriptionId, setSubscriptionId] = useState('');
  const [subscriptionStatus, setSubscriptionStatus] = useState('');
  const [iconColor, setIconColor] = useState('');
  const [icon, setIcon] = useState('');
  const [text, setText] = useState('');

  useEffect(() => {
    const SuccessIcon =
      <svg width="16" height="14" viewBox="0 0 16 14" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fillRule="evenodd" clipRule="evenodd" d="M15.4695 0.232963C15.8241 0.561287 15.8454 1.1149 15.5171 1.46949L6.14206 11.5945C5.97228 11.7778 5.73221 11.8799 5.48237 11.8748C5.23253 11.8698 4.99677 11.7582 4.83452 11.5681L0.459523 6.44311C0.145767 6.07557 0.18937 5.52327 0.556912 5.20951C0.924454 4.89575 1.47676 4.93936 1.79051 5.3069L5.52658 9.68343L14.233 0.280522C14.5613 -0.0740672 15.1149 -0.0953599 15.4695 0.232963Z" fill="white"/>
      </svg>;
    const ErrorIcon =
      <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fillRule="evenodd" clipRule="evenodd" d="M1.25628 1.25628C1.59799 0.914573 2.15201 0.914573 2.49372 1.25628L8 6.76256L13.5063 1.25628C13.848 0.914573 14.402 0.914573 14.7437 1.25628C15.0854 1.59799 15.0854 2.15201 14.7437 2.49372L9.23744 8L14.7437 13.5063C15.0854 13.848 15.0854 14.402 14.7437 14.7437C14.402 15.0854 13.848 15.0854 13.5063 14.7437L8 9.23744L2.49372 14.7437C2.15201 15.0854 1.59799 15.0854 1.25628 14.7437C0.914573 14.402 0.914573 13.848 1.25628 13.5063L6.76256 8L1.25628 2.49372C0.914573 2.15201 0.914573 1.59799 1.25628 1.25628Z" fill="white"/>
      </svg>;

    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const sessionId = urlParams.get('session_id');

    fetch("/status.php", {
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      method: "POST",
      body: JSON.stringify({ session_id: sessionId }),
    })
    fetch(`/session-status?session_id=${sessionId}`)
      .then((res) => res.json())
      .then((data) => {
        setStatus(data.status);
        setPaymentIntentId(data.payment_intent_id);
        setPaymentStatus(data.payment_status);
        setPaymentIntentStatus(data.payment_intent_status);
        setSubscriptionId(data.subscription_id);
        setSubscriptionStatus(data.subscription_status);

        if (data.status === 'complete') {
          setIconColor('#30B130');
          setIcon(SuccessIcon);
          setText('Payment succeeded');
        } else {
          setIconColor('#DF1B41');
          setIcon(ErrorIcon);
          setText('Something went wrong, please try again.');
        }
      });
  }, []);

    return (
      <div id="payment-status">
        <div id="status-icon" style={{backgroundColor: iconColor}}>
        {icon}
      </div>
      <h2 id="status-text">{text}</h2>
      <div id="details-table">
        <table>
          <tbody>
            {paymentIntentId && (
              <tr>
                <td className="TableLabel">Payment Intent ID</td>
                <td id="intent-id" className="TableContent">{paymentIntentId}</td>
              </tr>
            )}
            {subscriptionId && (
              <tr>
                <td className="TableLabel">Subscription ID</td>
                <td id="intent-id" className="TableContent">{subscriptionId}</td>
              </tr>
            )}
            <tr>
              <td className="TableLabel">Status</td>
              <td id="intent-status" className="TableContent">{status}</td>
            </tr>
            <tr>
              <td className="TableLabel">Payment status</td>
              <td id="session-status" className="TableContent">{paymentStatus}</td>
            </tr>
            {paymentIntentId && (
              <tr>
                <td className="TableLabel">Payment Intent status</td>
                <td id="payment-intent-status" className="TableContent">{paymentIntentStatus}</td>
              </tr>
            )}
            {subscriptionId && (
              <tr>
                <td className="TableLabel">Subscription status</td>
                <td id="payment-intent-status" className="TableContent">{subscriptionStatus}</td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
      {(paymentIntentId || subscriptionId) && (
        <div className="sample-key-banner" role="note">
          You're using a public sample test key.{" "}
          <a
            id="view-details"
            href="https://dashboard.stripe.com/login"
            rel="noopener noreferrer"
            target="_blank"
          >
            Sign in or create an account
          </a>{" "}
          to use your own test API key.
        </div>
      )}
      <a id="retry-button" href="/checkout">Test another payment</a>
  </div>
    )
\## Set Price ID

In the server code, replace `{{PRICE_ID}}` with the Price ID (`price_xxx`) of the product you created in the quickstart guide. Find it in your [Stripe test Dashboard under Products](https://dashboard.stripe.com/test/products).

1. Build the server

~~~
pip3 install -r requirements.txt
~~~
1. Build the server

~~~
bundle install
~~~
1. Build the server

~~~
composer install
~~~
1. Build the server

~~~
dotnet restore
~~~
1. Build the server

~~~
mvn package
~~~

2. Run the server

~~~
export FLASK_APP=server.py
python3 -m flask run --port=4242
~~~

2. Run the server

~~~
ruby server.rb -o 0.0.0.0
~~~

2. Run the server

~~~
php -S 127.0.0.1:4242 --docroot=public
~~~

2. Run the server

~~~
dotnet run
~~~

2. Run the server

~~~
java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server
~~~

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)
1. Run the server

~~~
go run server.go
~~~

2. Build the client app

~~~
npm install
~~~

3. Run the client app

~~~
npm start
~~~

4. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)
1. Run the server

~~~
go run server.go
~~~

2. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)
1. Build the application

~~~
npm install
~~~

2. Run the application

~~~
npm start
~~~

3. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)
1. Build the server

~~~
npm install
~~~

2. Run the server

~~~
npm start
~~~

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)
\### Development

1. Build the application
~~~shell
$ npm install
~~~

2. _Optional_: download and run the [Stripe CLI](https://stripe.com/docs/stripe-cli)
~~~shell
$ stripe listen --forward-to localhost:3000/api/webhooks
~~~

3. Run the application
~~~shell
$ STRIPE_WEBHOOK_SECRET=$(stripe listen --print-secret) npm run dev
~~~

4. Go to [localhost:3000](http://localhost:3000)

### Production

1. Build the application
~~~shell
$ npm install

$ npm build
~~~

2. Run the application
~~~shell
$ npm start
~~~
## 次のステップ

#### [項目を動的に更新する](https://docs.stripe.com/payments/advanced/dynamically-update-line-items.md)

ユーザーが商品を追加、削除、変更するときに Checkout セッションの項目を動的に変更する方法をご紹介します。

#### [注文の処理](https://docs.stripe.com/checkout/fulfillment.md?payment-ui=embedded-components)

Webhook を設定し、支払いが成功したら注文のフルフィルメントを実行します。Webhook は、ビジネスにとって重要なイベントを処理するための最も信頼できる方法です。

#### [入金の受け取り](https://docs.stripe.com/payouts.md)

Stripe アカウントから銀行口座に売上を移動する方法をご紹介します。

#### [支払いの返金とキャンセル](https://docs.stripe.com/refunds.md)

Stripe API またはダッシュボードを使用し、返金のリクエストを処理します。

#### [顧客管理](https://docs.stripe.com/customer-management.md)

顧客が決済情報、請求書、サブスクリプションを自分で管理できるようにします。

#### [ワンクリックの決済ボタン](https://docs.stripe.com/elements/express-checkout-element/accept-a-payment.md?payment-ui=embedded-components#create-and-mount)

Express Checkout Element を使用して、ワンクリックの決済手段ボタンで決済を受け付ける。

#### [Checkout Studio](https://docs.stripe.com/payments/checkout-studio.md)

コードを記述せずに、ダッシュボードから Checkout の実装を設定および監視できます。
