# Webhook を設定してデプロイする

Webhook を設定してデプロイし、Stripe からのイベントをリッスンする方法をご紹介します。

# インタラクティブな Webhook エンドポイントビルダー

Webhook を設定してデプロイし、Stripe からのイベントをリッスンする方法をご紹介します。Webhook エンドポイントを使用して、カスタムのメール領収書の送信、注文のフルフィルメント、データベースの更新など、支払い後のコマースイベントを処理することができます。これらの手順は、本番環境で実行する前に一度サンドボックスでテストしてください。

1. Build the server

~~~
npm install
~~~

2. Run the server

~~~
npm start
~~~
1. Run the server

~~~
go run server.go
~~~
1. Build the server

~~~
pip3 install -r requirements.txt
~~~

2. Run the server

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

1. Build the server

~~~
bundle install
~~~

2. Run the server

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

1. Build the server

~~~
composer install
~~~

2. Run the server

~~~
php -S 127.0.0.1:4242 --docroot=public
~~~
1. Build the server

~~~
dotnet restore
~~~

2. Run the server

~~~
dotnet run
~~~
1. Build the server

~~~
mvn package
~~~

2. Run the server

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

~~~
stripe listen --forward-to localhost:4242/webhook.php
~~~

~~~
stripe listen --forward-to localhost:4242/webhook
~~~
### 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
```

### 新しいエンドポイントを作成する

[Webhook エンドポイント](https://docs.stripe.com/webhooks.md)は、Stripe からのリクエストを受信するサーバー上のデスティネーションであり、顧客による不審請求の申請や継続支払いの成功など、アカウントで発生するイベントについて通知します。サーバーに新しいエンドポイントを追加し、Stripe が未認証の POST リクエストを送信できるように、パブリックアクセス可能であることを確認してください。

### イベントデータを読み込む

Stripe は、リクエスト本文でイベントデータを送信します。それぞれのイベントは、`type`、`id` と `data` にネストされた Stripe の関連リソースが含まれる [Event (イベント) オブジェクト](https://docs.stripe.com/api/events.md)として構成されます。

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

イベントオブジェクトを入手したら、[タイプ](https://docs.stripe.com/api/events/types.md)を調べ、どのようなイベントが発生したのかを調べます。1 つの Webhook を使用して複数のイベントタイプを一度に処理することも、特定のイベントに対して個別のエンドポイントを設定することもできます。

### コード 200 のレスポンスを返す

妥当な時間内にレスポンスが送信されないと、Stripe はイベントを再試行するため、できるだけ速く[成功の 200 レスポンス](https://docs.stripe.com/webhooks.md#handle-events-asynchronously)を送信してください。Webhook エンドポイント外で非同期で実行できる、実行時間が長いプロセスはコードとして記述してください。

### サーバーを実行する

`STRIPE_WEBHOOK_SECRET` 環境変数を Webhook 署名シークレットに設定します。このシークレットは、ワークベンチの [Webhooks](https://dashboard.stripe.com/webhooks) タブ、または `stripe listen` を実行したときの CLI の出力で確認できます。

サーバーを構築して実行し、`http://localhost:4242/webhook` でエンドポイントをテストします。

```bash
npm start
```

### サーバーを実行する

`STRIPE_WEBHOOK_SECRET` 環境変数を Webhook 署名シークレットに設定します。このシークレットは、ワークベンチの [Webhooks](https://dashboard.stripe.com/webhooks) タブ、または `stripe listen` を実行したときの CLI の出力で確認できます。

サーバーを構築して実行し、`http://localhost:4242/webhook` でエンドポイントをテストします。

```bash
ruby server.rb
```

### サーバーを実行する

`STRIPE_WEBHOOK_SECRET` 環境変数を Webhook 署名シークレットに設定します。このシークレットは、ワークベンチの [Webhooks](https://dashboard.stripe.com/webhooks) タブ、または `stripe listen` を実行したときの CLI の出力で確認できます。

サーバーを構築して実行し、`http://localhost:4242/webhook` でエンドポイントをテストします。

```bash
python3 -m flask --app server run --port=4242
```

### サーバーを実行する

`STRIPE_WEBHOOK_SECRET` 環境変数を Webhook 署名シークレットに設定します。このシークレットは、ワークベンチの [Webhooks](https://dashboard.stripe.com/webhooks) タブ、または `stripe listen` を実行したときの CLI の出力で確認できます。

サーバーを構築して実行し、`http://localhost:4242/public/webhook.php`. でエンドポイントをテストします。

```bash
php -S 127.0.0.1:4242
```

### サーバーを実行する

`STRIPE_WEBHOOK_SECRET` 環境変数を Webhook 署名シークレットに設定します。このシークレットは、ワークベンチの [Webhooks](https://dashboard.stripe.com/webhooks) タブ、または `stripe listen` を実行したときの CLI の出力で確認できます。

サーバーを構築して実行し、`http://localhost:4242/webhook` でエンドポイントをテストします。

```bash
dotnet run
```

### サーバーを実行する

`STRIPE_WEBHOOK_SECRET` 環境変数を Webhook 署名シークレットに設定します。このシークレットは、ワークベンチの [Webhooks](https://dashboard.stripe.com/webhooks) タブ、または `stripe listen` を実行したときの CLI の出力で確認できます。

サーバーを構築して実行し、`http://localhost:4242/webhook` でエンドポイントをテストします。

```bash
go run server.go
```

### サーバーを実行する

`STRIPE_WEBHOOK_SECRET` 環境変数を Webhook 署名シークレットに設定します。このシークレットは、ワークベンチの [Webhooks](https://dashboard.stripe.com/webhooks) タブ、または `stripe listen` を実行したときの CLI の出力で確認できます。

サーバーを構築して実行し、http://localhost:4242/webhook でエンドポイントをテストします。

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

### CLI をダウンロードする

Stripe CLI を使用して Webhook をローカルでテストします。[CLI をダウンロード](https://docs.stripe.com/cli.md)し、Stripe アカウントにログインします。また、これ以外の方法として、ngrok のようなサービスを使用してローカルのエンドポイントをパブリックアクセス可能な状態にすることもできます。

```bash
stripe login
```

### Ｗebhook にイベントを転送する

CLI で[イベント転送](https://docs.stripe.com/webhooks.md#test-webhook)を設定し、サンドボックス内のすべての Stripe イベントをローカルの Webhook エンドポイントに送信します。

```bash
stripe listen --forward-to localhost:4242/webhook
```

### Ｗebhook にイベントを転送する

CLI で[イベント転送](https://docs.stripe.com/webhooks.md#test-webhook)を設定し、テスト環境のすべての Stripe イベントをローカルの Ｗebhook エンドポイントに送信します。

```bash
stripe listen --forward-to localhost:4242/public/webhook.php
```

### イベントをシミュレーションする

CLI を使用して、Webhook アプリケーションロジックをテストする[特定のイベントをシミュレート](https://docs.stripe.com/cli/trigger)します。この際、模擬の Stripe イベントオブジェクトを使用して、POST リクエストを Webhook エンドポイントに送信します。

```bash
stripe trigger payment_intent.succeeded
```

### Webhook を保護する

不正行為者による、偽のペイロードの送信や、バックエンドシステムを改変する SQL インジェクションを防止するために、Webhook リクエストの送信元を確認します。クライアントの署名で Webhook を保護して、Webhook リクエストが Stripe によって生成されたものであり、Stripe のふりをして機能するサーバーから生成されたものではないことを確認します。

### エンドポイント署名シークレットを追加する

各Webhookエンドポイントには一意の署名シークレットがあり、ワークベンチの[Webhook](https://dashboard.stripe.com/workbench/webhooks)タブで確認できます。Stripe CLIを使用してローカルでテストしている場合は、`stripe listen`コマンドを使用してCLI出力から署名シークレットを取得することもできます。

### イベントを検証する

Stripe ライブラリを使用して Stripe からのイベントを検証し、構築できます。イベントを正しく検証するには、エンドポイントシークレット、リクエストヘッダー、および未加工のリクエスト本文が必要です。または、Stripe ライブラリを使用せずに、署名を[手動で検証](https://docs.stripe.com/webhooks.md?verify=verify-manually#verify-manually)することもできます。

### リクエストの署名を読み込む

Stripe からの各リクエストには、`Stripe-Signature` ヘッダーが含まれます。後で使用できるように、このヘッダー値への参照を保存します。

### リクエストを検証する

Stripe ライブラリを使用してリクエストが Stripe からのものであることを検証します。未加工のリクエスト本文、`Stripe-Signature` ヘッダー、およびエンドポイントシークレットを渡して、[Event (イベント)](https://docs.stripe.com/api/events/object.md) を構築します。

### エラーを処理する

エラーを確認することにより、構成が不適切な Webhook、または Stripe 以外のサービスからの形式が正しくないリクエストを見つけることができます。よくあるエラーとしては、間違ったエンドポイントシークレットを使用している、リクエスト本文の解析された表現 (JSON など) が渡されている、間違ったリクエストヘッダーが読み込まれている、などがあります。

### エンドポイントをテストする

Stripe CLI を使用して保護されたエンドポイントをテストします。これにより、各テストイベントで適切な署名ヘッダーが送信されます。

// 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 API key embedded in code samples.
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
const stripe = require('stripe')('<<YOUR_SECRET_KEY>>');

// To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
// your endpoint's unique secret.
//
// If you are testing with the CLI, find the secret by running 'stripe listen'.
// If you are using an endpoint defined with the API or dashboard, look in
// your webhook settings at https://dashboard.stripe.com/webhooks.
//
// Don't include webhook secrets in code.
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

const express = require('express');
const app = express();

app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
  let event = request.body;
  // Only verify the event if you have an endpoint secret defined.
  // Otherwise use the basic event deserialized with JSON.parse
  if (endpointSecret) {
    // Get the signature sent by Stripe
    const signature = request.headers['stripe-signature'];
    try {
      event = stripe.webhooks.constructEvent(
        request.body,
        signature,
        endpointSecret
      );
    } catch (err) {
      console.log(`⚠️  Webhook signature verification failed.`, err.message);
      return response.sendStatus(400);
    }
  }
  // Handle the event
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log(`PaymentIntent for ${paymentIntent.amount} was successful!`);
      // Then define and call a method to handle the successful payment intent.
      // handlePaymentIntentSucceeded(paymentIntent);
      break;
    case 'payment_method.attached':
      const paymentMethod = event.data.object;
      // Then define and call a method to handle the successful attachment of a PaymentMethod.
      // handlePaymentMethodAttached(paymentMethod);
      break;
    default:
      // Unexpected event type
      console.log(`Unhandled event type ${event.type}.`);
  }
  // Return a 200 response to acknowledge receipt of the event
  response.send();
app.listen(4242, () => console.log('Running on port 4242'));
{
  "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.6.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.6.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"
    ]
  }
}
require 'stripe'
\# 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 API key embedded in code samples.
\# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

\# To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
# your endpoint's unique secret.
#
# If you are testing with the CLI, find the secret by running 'stripe listen'.
# If you are using an endpoint defined with the API or dashboard, look in
# your webhook settings at https://dashboard.stripe.com/webhooks.
#
# Don't include webhook secrets in code.
endpoint_secret = ENV['STRIPE_WEBHOOK_SECRET']

post '/webhook' do
  payload = request.body.read
  event = nil

  begin
    event = Stripe::Event.construct_from(
      JSON.parse(payload, symbolize_names: true)
    )
  rescue JSON::ParserError => e
    \# Invalid payload
    puts "⚠️  Webhook error while parsing basic request. #{e.message}"
    status 400
    return
  end
  \# Check if webhook signing is configured.
  if endpoint_secret
    # Retrieve the event by verifying the signature using the raw body and secret.
    signature = request.env['HTTP_STRIPE_SIGNATURE'];
    begin
      event = Stripe::Webhook.construct_event(
        payload, signature, endpoint_secret
      )
    rescue Stripe::SignatureVerificationError => e
      puts "⚠️  Webhook signature verification failed. #{e.message}"
      status 400
    end
  end
  \# Handle the event
  case event.type
  when 'payment_intent.succeeded'
    payment_intent = event.data.object # contains a Stripe::PaymentIntent
    puts "Payment for #{payment_intent['amount']} succeeded."
    # Then define and call a method to handle the successful payment intent.
    # handle_payment_intent_succeeded(payment_intent)
  when 'payment_method.attached'
    payment_method = event.data.object # contains a Stripe::PaymentMethod
    # Then define and call a method to handle the successful attachment of a PaymentMethod.
    # handle_payment_method_attached(payment_method)
  else
    puts "Unhandled event type: #{event.type}"
  end
  status 200
import stripe
\# 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 API key embedded in code samples.
\# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = stripe.StripeClient('<<YOUR_SECRET_KEY>>')

\# To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
# your endpoint's unique secret.
#
# If you are testing with the CLI, find the secret by running 'stripe listen'.
# If you are using an endpoint defined with the API or dashboard, look in
# your webhook settings at https://dashboard.stripe.com/webhooks.
#
# Don't include webhook secrets in code.
endpoint_secret = os.environ.get('STRIPE_WEBHOOK_SECRET')

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
    try:
        event = json.loads(payload)
    except json.decoder.JSONDecodeError as e:
        print('⚠️  Webhook error while parsing basic request.' + str(e))
        return jsonify(success=False)
    if endpoint_secret:
        \# Only verify the event if there is an endpoint secret defined
        # Otherwise use the basic event deserialized with json
        sig_header = request.headers.get('stripe-signature')
        try:
            event = client.construct_event(
                payload, sig_header, endpoint_secret
            )
        except stripe.error.SignatureVerificationError as e:
            print('⚠️  Webhook signature verification failed.' + str(e))
            return jsonify(success=False)
    \# Handle the event
    if event and event['type'] == 'payment_intent.succeeded':
        payment_intent = event['data']['object']  # contains a stripe.PaymentIntent
        print('Payment for {} succeeded'.format(payment_intent['amount']))
        # Then define and call a method to handle the successful payment intent.
        # handle_payment_intent_succeeded(payment_intent)
    elif event['type'] == 'payment_method.attached':
        payment_method = event['data']['object']  # contains a stripe.PaymentMethod
        # Then define and call a method to handle the successful attachment of a PaymentMethod.
        # handle_payment_method_attached(payment_method)
    else:
        # Unexpected event type
        print('Unhandled event type {}'.format(event['type']))
    return jsonify(success=True)
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.6.0
toml==0.10.2
Werkzeug==3.1.5
$stripe = new \Stripe\StripeClient($stripeSecretKey);

// To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
// your endpoint's unique secret.
//
// If you are testing with the CLI, find the secret by running 'stripe listen'.
// If you are using an endpoint defined with the API or dashboard, look in
// your webhook settings at https://dashboard.stripe.com/webhooks.
//
// Don't include webhook secrets in code.
$endpoint_secret = getenv('STRIPE_WEBHOOK_SECRET');

$payload = @file_get_contents('php://input');
$event = null;

try {
  $event = \Stripe\Event::constructFrom(
    json_decode($payload, true)
  );
} catch(\UnexpectedValueException $e) {
  // Invalid payload
  echo '⚠️  Webhook error while parsing basic request.';
  http_response_code(400);
  exit();
}
if ($endpoint_secret) {
  // Only verify the event if there is an endpoint secret defined
  // Otherwise use the basic decoded event
  $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
  try {
    $event = \Stripe\Webhook::constructEvent(
      $payload, $sig_header, $endpoint_secret
    );
  } catch(\Stripe\Exception\SignatureVerificationException $e) {
    // Invalid signature
    echo '⚠️  Webhook error while validating signature.';
    http_response_code(400);
    exit();
  }
}
// Handle the event
switch ($event->type) {
  case 'payment_intent.succeeded':
    $paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent
    // Then define and call a method to handle the successful payment intent.
    // handlePaymentIntentSucceeded($paymentIntent);
    break;
  case 'payment_method.attached':
    $paymentMethod = $event->data->object; // contains a \Stripe\PaymentMethod
    // Then define and call a method to handle the successful attachment of a PaymentMethod.
    // handlePaymentMethodAttached($paymentMethod);
    break;
  default:
    // Unexpected event type
    error_log('Received unknown event type');
}
http_response_code(200);
// 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.
      // Sign in to see your own test API key embedded in code samples.
      // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
      services.AddSingleton(new StripeClient("<<YOUR_SECRET_KEY>>"));
  [Route("webhook")]
  [ApiController]
  public class WebhookController : Controller

        // To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
        // your endpoint's unique secret.
        //
        // If you are testing with the CLI, find the secret by running 'stripe listen'.
        // If you are using an endpoint defined with the API or dashboard, look in
        // your webhook settings at https://dashboard.stripe.com/webhooks.
        //
        // Don't include webhook secrets in code.
        var endpointSecret = Environment.GetEnvironmentVariable("STRIPE_WEBHOOK_SECRET");

            var stripeEvent = EventUtility.ParseEvent(json);
            var signatureHeader = Request.Headers["Stripe-Signature"];

            stripeEvent = EventUtility.ConstructEvent(json,
                    signatureHeader, endpointSecret);
            // If on SDK version < 46, use class Events instead of EventTypes
            if (stripeEvent.Type == EventTypes.PaymentIntentSucceeded)
            {
                var paymentIntent = stripeEvent.Data.Object as PaymentIntent;
                Console.WriteLine("A successful payment for {0} was made.", paymentIntent.Amount);
                // Then define and call a method to handle the successful payment intent.
                // handlePaymentIntentSucceeded(paymentIntent);
            }
            else if (stripeEvent.Type == EventTypes.PaymentMethodAttached)
            {
                var paymentMethod = stripeEvent.Data.Object as PaymentMethod;
                // Then define and call a method to handle the successful attachment of a PaymentMethod.
                // handlePaymentMethodAttached(paymentMethod);
            }
            else
            {
                Console.WriteLine("Unhandled event type: {0}", stripeEvent.Type);
            }
            return Ok();
        catch (StripeException e)
        {
            Console.WriteLine("Error: {0}", e.Message);
            return BadRequest();
        }
  "github.com/stripe/stripe-go/v86"
  "github.com/stripe/stripe-go/v86/webhook"
  // 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 API key embedded in code samples.
  // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
  sc = stripe.NewClient("<<YOUR_SECRET_KEY>>")
  http.HandleFunc("/webhook", handleWebhook)
  event := stripe.Event{}

  if err := json.Unmarshal(payload, &event); err != nil {
    fmt.Fprintf(os.Stderr, "⚠️  Webhook error while parsing basic request. %v\n", err.Error())
    w.WriteHeader(http.StatusBadRequest)
    return
  }

  // To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
  // your endpoint's unique secret.
  //
  // If you are testing with the CLI, find the secret by running 'stripe listen'.
  // If you are using an endpoint defined with the API or dashboard, look in
  // your webhook settings at https://dashboard.stripe.com/webhooks.
  //
  // Don't include webhook secrets in code.
  endpointSecret := os.Getenv("STRIPE_WEBHOOK_SECRET")

  signatureHeader := req.Header.Get("Stripe-Signature")
  event, err = sc.ConstructEvent(payload, signatureHeader, endpointSecret)
  if err != nil {
    fmt.Fprintf(os.Stderr, "⚠️  Webhook signature verification failed. %v\n", err)
    w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature
    return
  }
  // Unmarshal the event data into an appropriate struct depending on its Type
  switch event.Type {
  case "payment_intent.succeeded":
    var paymentIntent stripe.PaymentIntent
    err := json.Unmarshal(event.Data.Raw, &paymentIntent)
    if err != nil {
      fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
      w.WriteHeader(http.StatusBadRequest)
      return
    }
    log.Printf("Successful payment for %d.", paymentIntent.Amount)
    // Then define and call a func to handle the successful payment intent.
    // handlePaymentIntentSucceeded(paymentIntent)
  case "payment_method.attached":
    var paymentMethod stripe.PaymentMethod
    err := json.Unmarshal(event.Data.Raw, &paymentMethod)
    if err != nil {
      fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
      w.WriteHeader(http.StatusBadRequest)
      return
    }
    // Then define and call a func to handle the successful attachment of a PaymentMethod.
    // handlePaymentMethodAttached(paymentMethod)
  default:
    fmt.Fprintf(os.Stderr, "Unhandled event type: %s\n", event.Type)
  }
  w.WriteHeader(http.StatusOK)
require github.com/stripe/stripe-go/v86 v86.4.0
        // 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 API key embedded in code samples.
        // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
        StripeClient client = new StripeClient("<<YOUR_SECRET_KEY>>");

        // To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
        // your endpoint's unique secret.
        //
        // If you are testing with the CLI, find the secret by running 'stripe listen'.
        // If you are using an endpoint defined with the API or dashboard, look in
        // your webhook settings at https://dashboard.stripe.com/webhooks.
        //
        // Don't include webhook secrets in code.
        String endpointSecret = System.getenv("STRIPE_WEBHOOK_SECRET");

        post("/webhook", (request, response) -> {
            String payload = request.body();
            Event event = null;

            try {
                event = ApiResource.GSON.fromJson(payload, Event.class);
            } catch (JsonSyntaxException e) {
                // Invalid payload
                System.out.println("⚠️  Webhook error while parsing basic request.");
                response.status(400);
                return "";
            }
            String sigHeader = request.headers("Stripe-Signature");
            if(endpointSecret != null && sigHeader != null) {
                // Only verify the event if you have an endpoint secret defined.
                // Otherwise use the basic event deserialized with GSON.
                try {
                    event = client.constructEvent(
                        payload, sigHeader, endpointSecret
                    );
                } catch (SignatureVerificationException e) {
                    // Invalid signature
                    System.out.println("⚠️  Webhook error while validating signature.");
                    response.status(400);
                    return "";
                }
            }
            // Handle the event
            switch (event.getType()) {
                case "payment_intent.succeeded":
                    PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
                    System.out.println("Payment for " + paymentIntent.getAmount() + " succeeded.");
                    // Then define and call a method to handle the successful payment intent.
                    // handlePaymentIntentSucceeded(paymentIntent);
                    break;
                case "payment_method.attached":
                    PaymentMethod paymentMethod = (PaymentMethod) stripeObject;
                    // Then define and call a method to handle the successful attachment of a PaymentMethod.
                    // handlePaymentMethodAttached(paymentMethod);
                    break;
                default:
                    System.out.println("Unhandled event type: " + event.getType());
                break;
            }
            response.status(200);
            return "";
## 次のステップ

#### [Webhook を保護する](https://docs.stripe.com/webhooks.md#verify-events)

Stripe からの確認済みイベントのみを許可して、Webhook エンドポイントを保護します。

#### [本番環境に移行する](https://docs.stripe.com/webhooks.md#register-webhook)

Webhook エンドポイントを本番環境にデプロイし、必要な特定のイベントのみを送信して大規模にイベントを処理する方法をご紹介します。

#### [ベストプラクティス](https://docs.stripe.com/webhooks.md#best-practices)

再試行や重複イベントの管理など、エンドポイントの維持に関するベストプラクティスをご紹介します。

#### [Stripe CLI](https://docs.stripe.com/cli.md)

Stripe CLI には、Webhook 以外の Stripe アプリケーションのテストに役立つコマンドがいくつか用意されています。
