Stripe を利用していてwebhookを使ったStripe 上で発生したイベントに対して処理を行うというのはよくあると思います。
Stripe ではイベントが第三者ではなく Stripe によって送信されたリクエストであることを確認するために Signature の検証ができるようになっています。
Check the webhook signatures
基本的にはwebhook でイベントを受け取るエンドポイントで Signature の確認処理を実行すると思いますが、テストでは自前で Signature を作成する必要があります。
ここでは公式のStripe API の Ruby Gems の stripe-ruby と Rspec でテストする前提での例を説明します。
Stripe-Signature の作成
stripe-ruby では Signature の計算とStripe-Signature ヘッダの文字列を作成するメソッドが提供されています。
これらを使ってStripe-Signature ヘッダを含む POST リクエストをするメソッドを用意します。
- Method: Stripe::Webhook::Signature.compute_signature — Documentation for stripe/stripe-ruby (master)
- Method: Stripe::Webhook::Signature.generate_header — Documentation for stripe/stripe-ruby (master)
# frozen_string_literal: true
module StripeEventHelpers
def post_with_stripe_signature(path, **options)
post(
path,
headers: {
'Stripe-Signature': generate_stripe_event_signature(options[:params])
},
**options
)
end
private
def generate_stripe_event_signature(payload)
time = Time.now
secret = ENV['STRIPE_WEBHOOK_SECRET']
signature = Stripe::Webhook::Signature.compute_signature(time, payload, secret)
Stripe::Webhook::Signature.generate_header(
time,
signature
)
end
end
Stripe の イベントを受け取るエンドポイントのテスト内での post
は基本的に Stripe-Signature
ヘッダを含めることになるので post
をオーバーライドするのもありだと思います。
- def post_with_stripe_signature(path, **options)
+ def post(path, **options)
- post(
+ super(
path,
headers: {
'Stripe-Signature': generate_stripe_event_signature(options[:params])
},
**options
)
end
ヘルパーをインポートしてヘッダーを含むリクエストをする
テスト用の Stripe::Event オブジェクトを作成するのに stripe-ruby-mock を使います。
Ref: stripe-ruby-mock/stripe-ruby-mock: A mocking library for testing stripe ruby
describe StripeEventsController do
include StripeEventHelpers
before { StripeMock.start }
after { StripeMock.stop }
let(:event) { StripeMock.mock_webhook_event('customer.created') }
it 'returns ok' do
post_with_stripe_signature stripe_events_path, params: event.to_json
expect(response).to have_http_status(200)
end
end