### EventReceiver Integration Example Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Demonstrates the internal flow of VcrStripeWebhook when using a cassette in recording mode. Shows how the EventReceiver is initialized, how it uses an EventCassette, and the sequence of operations including starting the server, receiving webhooks, and waiting for events. ```ruby # This is automatically managed by VcrStripeWebhook.use_cassette # Showing the internal flow: cassette = EventCassette.new("test", vcr_cassette, recording: true) receiver = EventReceiver.instance receiver.use_cassette(cassette) do |vcr_cassette| # In recording mode: # 1. receiver.start() called # 2. Server listening on ephemeral port # 3. Stripe CLI forwarding webhooks to server # 4. Block yields, user code triggers Stripe operations # 5. Webhooks received via receive_webhook # 6. cassette.receive_event_payload stores events # 7. wait_for_rest_webhooks creates/deletes fence # 8. All events now in cassette, ready to serialize end ``` -------------------------------- ### Starting and Stopping the Server Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Demonstrates how to initialize the server with a callback, start it, and then gracefully shut it down. The callback function processes the incoming webhook payload. ```ruby # Starting a server callback = ->(payload) { event = JSON.parse(payload) puts "Received event: #{event['type']}" # Store event in cassette } server = VcrStripeWebhook::Server.new(0, &callback) puts "Server started on port #{server.port}" # Server now accepts connections in background thread # Stripe CLI forwards webhooks to http://localhost:{port}/ # Later, stop the server server.close server.join # Wait for accept thread puts "Server stopped" ``` -------------------------------- ### Server Port Example Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Demonstrates how to instantiate a server with an ephemeral port and then retrieve and display the assigned port number. The output shows an example of an OS-assigned port. ```ruby server = VcrStripeWebhook::Server.new(0) { |payload| ... } puts "Server listening on port #{server.port}" # Output: Server listening on port 54321 ``` -------------------------------- ### Stripe CLI Log Output Example Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md An example of the log output from the Stripe CLI during its startup and readiness reporting phase. ```text INFO: Spawning Stripe CLI: stripe listen --forward-to localhost:54321/ INFO: Stripe CLI PID=12345 INFO: Waiting for Stripe CLI to be ready... INFO: Stripe CLI: ERR: 2024-06-28 10:30:15 > Ready! Your webhook signing secret is whsec_test_... ``` -------------------------------- ### Use Cassette with Event Receiver Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Wraps a block of code with cassette management and server setup. In recording mode, it starts the server and CLI, yields to the block, and waits for remaining webhooks. In replay mode, it directly yields without starting the server. ```ruby event_receiver.use_cassette(cassette) { |vcr_cassette| ... } ``` -------------------------------- ### Stripe CLI Stdout Example Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Example of standard output from the Stripe CLI, showing connection and forwarding information. ```shell > Ready! Your webhook signing secret is whsec_test_... > Connecting to api.stripe.com > Forwarding events from * to http://localhost:54321/ ``` -------------------------------- ### start Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Initializes and starts the webhook server and Stripe CLI. This method is typically called automatically by `use_cassette` in recording mode and manual calls are usually not needed. ```APIDOC ## start ### Description Initializes and starts the webhook server and Stripe CLI. ### Method (Implicitly called) ### Endpoint N/A ### Parameters None ### Request Example ```ruby event_receiver.start ``` ### Response **Returns:** nil **Side effects:** - Creates internal Server instance listening for webhooks - Spawns Stripe CLI process with webhook forwarding - Waits for Stripe CLI to be ready - Sets up synchronization primitives for fence handling **Idempotent:** Returns early if already started (checks @started flag). **Precondition:** Configuration.stripe_api_key must be set. **Throws:** RuntimeError if Stripe CLI cannot be spawned. ``` -------------------------------- ### Start the Event Receiver Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Initializes and starts the webhook server and Stripe CLI. This method is called automatically in recording mode by `use_cassette`. Manual calls are typically not needed. Requires `Configuration.stripe_api_key` to be set. ```ruby event_receiver.start ``` -------------------------------- ### Install Stripe CLI on macOS Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Command to install the Stripe CLI using Homebrew on macOS. ```bash # macOS brew install stripe/stripe-cli/stripe ``` -------------------------------- ### Example Teardown with EventReceiver.terminate Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md An example of how `EventReceiver.terminate` (or `VcrStripeWebhook.stop` which delegates to it) can be integrated into a test suite's teardown process using `at_exit`. ```ruby # Typically called at test suite teardown at_exit do VcrStripeWebhook.stop # Delegates to EventReceiver.terminate end ``` -------------------------------- ### use_cassette Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Wraps a block of code with cassette management and server setup. It handles starting the server in recording mode and yielding to the provided block. ```APIDOC ## use_cassette ### Description Wraps a block with cassette management and server setup. ### Method (Implicitly called) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```ruby event_receiver.use_cassette(cassette) { |vcr_cassette| ... } ``` ### Parameters - **cassette** (EventCassette) - Required - The cassette to use for this block - **block** (Proc) - Required - Code that triggers Stripe operations ### Response **Returns:** Block yield value **Behavior:** - **Recording mode:** - Starts the server and Stripe CLI - Yields to the block - Waits for remaining webhooks via `wait_for_rest_webhooks` - **Replay mode:** - Directly yields without starting server ``` -------------------------------- ### Get Request Headers Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Retrieves all request headers as a hash with lowercase keys. Example includes content-type, content-length, and host. ```ruby { "content-type" => "application/json", "content-length" => "256", "host" => "localhost:54321" } ``` -------------------------------- ### Install Stripe CLI on Linux Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Commands to download and unzip the Stripe CLI for Linux systems. ```bash # Linux wget https://github.com/stripe/stripe-cli/releases/download/v#.#.#/stripe_#.#.#_linux_x86_64.zip unzip stripe_#.#.#_linux_x86_64.zip ``` -------------------------------- ### Initialize EventReceiver Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Creates a new instance of the EventReceiver. Direct instantiation is generally discouraged as the class is intended to be used as a singleton. The instance is not started until the `start` method is called. ```ruby EventReceiver.new ``` -------------------------------- ### Verify Stripe CLI Installation Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Check if the Stripe CLI is installed and accessible in your system's PATH. This is a prerequisite for certain Stripe operations. ```bash stripe --version which stripe ``` -------------------------------- ### Full Configuration Setup and Usage - VcrStripeWebhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/configuration-class.md Demonstrates setting up the VcrStripeWebhook configuration, including timeout, cassette directory, and Stripe API key, and then using it within an RSpec test. ```ruby require 'vcr_stripe_webhook' # Set up configuration VcrStripeWebhook.configuration.tap do |config| config.timeout = 10 config.cassette_library_dir = "spec/fixtures/webhook_cassettes" config.stripe_api_key = ENV['STRIPE_TEST_KEY'] end # Use in tests RSpec.describe "Stripe Integration" do it "records and replays webhook events" do VcrStripeWebhook.use_cassette("create_invoice") do webhook_event = VcrStripeWebhook.receive_webhook_event("invoice.created", timeout: VcrStripeWebhook.configuration.timeout) do # Stripe operation end end end end ``` -------------------------------- ### Basic Ruby Setup for VCR Stripe Webhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Configure VCR and Stripe API key for basic testing. Ensure VCR is set to hook into webmock. ```ruby # spec/spec_helper.rb require 'vcr' require 'vcr_stripe_webhook' require 'stripe' # Set Stripe API key for tests Stripe.api_key = ENV['STRIPE_TEST_KEY'] || 'sk_test_4eC39HqLyjWDarhtT657j51F' # VCR configuration VCR.configure do |config| config.cassette_library_dir = "spec/fixtures/cassettes" config.hook_into :webmock end # VcrStripeWebhook will use VCR's cassette directory + /stripe_webhooks # Results in: spec/fixtures/cassettes/stripe_webhooks/*.yml ``` -------------------------------- ### Stripe CLI Stderr Example Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Example of standard error from the Stripe CLI, including timestamps and API request status. ```shell 2024-06-28 10:30:15 > Ready! Your webhook signing secret is whsec_test_... 2024-06-28 10:30:16 > [stripe.com] POST /v1/customers (404 Not Found) ``` -------------------------------- ### Server Constructor Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Initializes a new VcrStripeWebhook::Server instance. It binds to a TCPServer on the specified port and starts a thread to listen for incoming connections. A callback proc is invoked with each received webhook JSON payload. ```APIDOC ## Server.new ### Description Initializes a new VcrStripeWebhook::Server instance. It binds to a TCPServer on the specified port and starts a thread to listen for incoming connections. A callback proc is invoked with each received webhook JSON payload. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Method Signature ```ruby Server.new(port = 0, &block) ``` ### Parameters - **port** (Integer) - Optional - Port number (0 = any available port) - **block** (Proc) - Required - Callback proc invoked when webhook received ### Returns Server instance ### Example ```ruby server = VcrStripeWebhook::Server.new(8000) do |payload| puts "Received webhook: #{payload}" end puts "Listening on port #{server.port}" ``` ``` -------------------------------- ### Set and Get Cassette Library Directory - VcrStripeWebhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/configuration-class.md Configure the directory where webhook cassette files are stored. The directory is created automatically if it does not exist. ```ruby VcrStripeWebhook.configuration.cassette_library_dir = "spec/cassettes/webhooks" dir = VcrStripeWebhook.configuration.cassette_library_dir ``` -------------------------------- ### Get HTTP Method Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Retrieves the HTTP method (e.g., "POST", "PUT", "GET") from the parsed request. ```ruby parser.method ``` -------------------------------- ### Docker/CI Environment Setup for VCR Stripe Webhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Configure VCR Stripe Webhook for Docker or CI environments. Adjusts timeout for slow environments and uses environment variables for the Stripe API key. ```ruby # spec/spec_helper.rb require 'vcr_stripe_webhook' # For slow CI environments VcrStripeWebhook.configuration.timeout = 30 # May need to increase for remote builds if ENV['CI'] || ENV['DOCKER'] VcrStripeWebhook.configuration.timeout = 60 end # Use environment variable for API key VcrStripeWebhook.configuration.stripe_api_key = ENV.fetch( 'STRIPE_SECRET_KEY', 'sk_test_4eC39HqLyjWDarhtT657j51F' ) ``` -------------------------------- ### Use VcrStripeWebhook.use_cassette for Single Webhook Event Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/README.md Wrap your test logic within `VcrStripeWebhook.use_cassette` to record or replay HTTP interactions and webhook events. This method automatically handles the setup and teardown for recording a single webhook event. ```ruby # This method wraps VCR.use_cassette VcrStripeWebhook.use_cassette('create_customer') do |vcr_cassette| stripe_customer = nil # Get a webhook payload from Stripe server or current cassette webhook_event = VcrStripeWebhook.receive_webhook_event('customer.created') do customer_params = { email: 'test-user@example.com', name: 'test-user', } stripe_customer = Stripe::Customer.create(customer_params) end # Call your webhook manually post your_stripe_webhook_path, params: webhook_event.as_json, headers: { 'Content-Type: application/json' } # Insert assertions here ensure stripe_customer&.delete end ``` -------------------------------- ### Get Server Instance Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/vcr-stripe-webhook-module.md Retrieves the internal Server instance. This method is for internal library use only and not part of the public API. Returns nil if the server is not available. ```ruby VcrStripeWebhook.server ``` -------------------------------- ### Example HTTP Exchange Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Illustrates a typical HTTP POST request exchange handled by the server, including headers and a JSON payload, and the expected 204 No Content response. ```http POST / HTTP/1.1 Host: localhost:54321 Content-Type: application/json Content-Length: 256 {"id":"evt_123","object":"event",...} HTTP/1.1 204 ``` -------------------------------- ### Example Cassette File Format Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/README.md Illustrates the YAML structure for VCR Stripe Webhook cassettes, including event types and wait boundaries. Each 'wait' entry corresponds to a 'receive_webhook_event(s)' call. ```yaml events: - type: customer.created value: id: evt_1234567890abcdef object: event type: customer.created created: 1719580800 data: object: id: cus_1234567890abcdef object: customer email: test@example.com waits: - start: 0 end: 1 ``` -------------------------------- ### Handle Stripe CLI Not Found Error Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Catch a RuntimeError if the Stripe CLI is not installed or not found in the system's PATH. Provides a helpful message to the user. ```ruby begin cli = VcrStripeWebhook::StripeCLI.new(port, key) rescue RuntimeError => e # e.message => "Could not spawn Stripe CLI" puts "Install Stripe CLI: https://stripe.com/docs/docs/stripe-cli" end ``` -------------------------------- ### Get Event Cassette File Path Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-cassette-class.md Returns the full file path where the webhook cassette YAML is stored. The pattern is `{cassette_library_dir}/{name}.stripe_webhooks.yml`. ```ruby cassette.path # => "spec/cassettes/stripe_webhooks/create_customer.stripe_webhooks.yml" ``` -------------------------------- ### Log Stripe CLI Check Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/errors.md Log a message to remind the user to check if the Stripe CLI is installed and running, which is necessary for recording webhooks. ```ruby # Check Stripe CLI is running (recording only) VcrStripeWebhook.logger.info("Check that Stripe CLI is installed and available") ``` -------------------------------- ### Set and Get Timeout - VcrStripeWebhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/configuration-class.md Configure the maximum time in seconds to wait for webhook events. This is useful for adjusting test environments. ```ruby VcrStripeWebhook.configuration.timeout = 10 timeout_value = VcrStripeWebhook.configuration.timeout ``` -------------------------------- ### Get Request Path Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Retrieves the requested path (e.g., "/" or "/webhook") from the parsed request. ```ruby parser.path ``` -------------------------------- ### Get Logger Instance Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/vcr-stripe-webhook-module.md Retrieve the global logger instance used by the VCR Stripe Webhook module. It defaults to writing to 'log/vcr_stripe_webhook.log'. ```ruby VcrStripeWebhook.logger ``` -------------------------------- ### Stripe Event Structure Example Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/types.md Illustrates the typical structure of a Stripe webhook event object when accessed via the `as_hash` method. This includes top-level event details and the nested `data` object containing the resource that triggered the event. ```ruby webhook_event.as_hash # => { # "id" => "evt_1234567890abcdef", # "object" => "event", # "api_version" => "2024-06-20", # "created" => 1719580800, # "data" => { # "object" => {...resource object...}, # "previous_attributes" => {...} # Only for update events # }, # "livemode" => false, # "pending_webhooks" => 0, # "request" => { # "id" => "req_...", # "idempotency_key" => nil # }, # "type" => "customer.created" # } ``` -------------------------------- ### RuntimeError: Could not spawn Stripe CLI Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/errors.md This error indicates that the Stripe CLI executable could not be found or executed. Ensure the Stripe CLI is installed and accessible in your system's PATH. ```ruby # Stripe CLI not installed or not in PATH VcrStripeWebhook.use_cassette("test", record: :new_episodes) do VcrStripeWebhook.receive_webhook_event("customer.created") do Stripe::Customer.create(...) end end ``` ```bash # Install Stripe CLI # macOS brew install stripe/stripe-cli/stripe # Linux wget https://github.com/stripe/stripe-cli/releases/download/v[VERSION]/stripe_[VERSION]_linux_x86_64.zip unzip stripe_[VERSION]_linux_x86_64.zip sudo mv stripe /usr/local/bin/ # Verify installation stripe --version ``` -------------------------------- ### Set and Get Stripe API Key - VcrStripeWebhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/configuration-class.md Configure the Stripe API key used for webhook listening. This must be a test-mode key for the Stripe CLI to forward webhooks correctly. ```ruby VcrStripeWebhook.configuration.stripe_api_key = 'sk_test_...' api_key = VcrStripeWebhook.configuration.stripe_api_key ``` -------------------------------- ### Get Content Type Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Extracts the MIME type from the Content-Type header, ignoring charset and other attributes. For example, 'application/json; charset=utf-8' becomes 'application/json'. ```ruby # Header: "application/json; charset=utf-8" parser.content_type # => "application/json" ``` -------------------------------- ### VcrStripeWebhook CassetteDataError Trigger Example Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/errors.md Illustrates how a change in test code structure after recording can lead to a CassetteDataError. The first version records one webhook event, while the second version attempts to replay with two events, exceeding the cassette's recorded waits. ```ruby # Test code v1 (original recording) VcrStripeWebhook.use_cassette("test") do webhook = VcrStripeWebhook.receive_webhook_event("customer.created") do Stripe::Customer.create(email: 'test@example.com') end # One receive_webhook_event call end # Test code v2 (new code, same cassette file) VcrStripeWebhook.use_cassette("test") do webhook1 = VcrStripeWebhook.receive_webhook_event("customer.created") do Stripe::Customer.create(email: 'test@example.com') end webhook2 = VcrStripeWebhook.receive_webhook_event("invoice.created") do Stripe::Invoice.create(customer: webhook1.dig("data", "object", "id"), ...) end # Two receive_webhook_event calls, but cassette only has one wait boundary # => CassetteDataError end ``` -------------------------------- ### Instantiate Configuration - VcrStripeWebhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/configuration-class.md Create a new Configuration instance with default values. This is typically accessed via `VcrStripeWebhook.configuration`. ```ruby Configuration.new ``` -------------------------------- ### StripeCLI Constructor Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Initializes a new StripeCLI instance, spawns the `stripe listen` process, and configures webhook forwarding. ```APIDOC ## Constructor Initializes a new StripeCLI instance. ### Signature ```ruby StripeCLI.new(server_port, api_key) ``` ### Parameters #### Path Parameters - **server_port** (Integer) - Required - Port number of local webhook server - **api_key** (String) - Required - Stripe test-mode API key (sk_test_...) ### Behavior - Spawns the `stripe listen` CLI process - Sets STRIPE_API_KEY environment variable - Configures webhook forwarding to localhost:{server_port} - Waits for Stripe CLI to report it's ready - Starts background threads to read stdout/stderr ### Throws RuntimeError if `stripe` command not found in PATH ### Side effects Spawns system process (stripe CLI) ### Example ```ruby cli = VcrStripeWebhook::StripeCLI.new(54321, 'sk_test_4eC39HqLyjWDarhtT657j51F') puts "Stripe CLI connected" # Later: cli.terminate ``` ``` -------------------------------- ### Instantiate Server with Callback Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Create a new Server instance, specifying the port and a callback block. The callback is invoked with the webhook's JSON payload. If port 0 is used, the OS assigns an available ephemeral port. ```ruby server = VcrStripeWebhook::Server.new(8000) do |payload| puts "Received webhook: #{payload}" end puts "Listening on port #{server.port}" ``` -------------------------------- ### Initialize EventCassette Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-cassette-class.md Instantiates an EventCassette. This is typically done internally by `VcrStripeWebhook.use_cassette` and not directly by consumer code. ```ruby EventCassette.new(name, vcr_cassette, recording) ``` -------------------------------- ### Initialize StripeCLI Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Instantiate the StripeCLI class to manage the Stripe CLI process. This requires the local server port and a Stripe test API key. The constructor spawns the `stripe listen` process and configures webhook forwarding. ```ruby cli = VcrStripeWebhook::StripeCLI.new(54321, 'sk_test_4eC39HqLyjWDarhtT657j51F') puts "Stripe CLI connected" ``` -------------------------------- ### Get Content Length Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Retrieves the integer value of the Content-Length header, or nil if not present. ```ruby parser.content_length ``` -------------------------------- ### Verify Stripe API Key Before Use Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Log the currently configured Stripe API key and ensure it is set before making calls within a VCR cassette context. This helps prevent errors due to uninitialized keys. ```ruby puts "Using API key: #{VcrStripeWebhook.configuration.stripe_api_key}" VcrStripeWebhook.use_cassette("test") do # Make sure key was set before this point end ``` -------------------------------- ### Get Associated VCR Cassette Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-cassette-class.md Returns the VCR::Cassette object linked to this EventCassette. ```ruby cassette.vcr_cassette ``` -------------------------------- ### Get Cassette Name Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-cassette-class.md Retrieves the name of the cassette, which is used to identify the associated YAML file. ```ruby cassette.name ``` -------------------------------- ### Get Event Types from EventTypeWaiter Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/waiter-classes.md Retrieve the array of Stripe event types that the EventTypeWaiter is configured to wait for. ```ruby waiter.event_types ``` -------------------------------- ### Stripe Ruby SDK Integration for Customer Creation Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/README.md Demonstrates using the Stripe Ruby SDK to create a customer, which in turn generates a 'customer.created' webhook event. ```ruby Stripe.api_key = 'sk_test_...' customer = Stripe::Customer.create(email: 'test@example.com') # Generates customer.created webhook ``` -------------------------------- ### Get Event Type Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-class.md Retrieve the type of the Stripe event. This is a direct attribute access on the Event object. ```ruby webhook_event = VcrStripeWebhook.receive_webhook_event("customer.created") { ... } puts webhook_event.type # => "customer.created" ``` -------------------------------- ### Override Logger Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/vcr-stripe-webhook-module.md Customize the logger for the VCR Stripe Webhook module, for example, to direct output to standard output. ```ruby VcrStripeWebhook.logger = Logger.new(STDOUT) ``` -------------------------------- ### Access Singleton Instance and Terminate Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Demonstrates how to access the singleton EventReceiver instance and how to terminate its processes. `terminate` is safe to call multiple times. ```ruby EventReceiver.instance EventReceiver.terminate ``` -------------------------------- ### Get Request Body Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Retrieves the raw request body bytes as a string. This is only present if a Content-Length header was provided in the request. ```ruby parser.body ``` -------------------------------- ### Configuration Options Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/GENERATED.txt Details on how to configure the VCR Stripe Webhook library, including settings for cassette storage, timeouts, and Stripe API keys. ```APIDOC ## Configuration The `VcrStripeWebhook` library can be configured to customize its behavior, such as the location of cassette files, request timeouts, and Stripe API credentials. ### Configuration Settings: - **`cassette_library_dir`**: Specifies the directory where VCR cassettes are stored. - **`stripe_secret_key`**: Your Stripe secret API key. - **`stripe_public_key`**: Your Stripe public API key. - **`webhook_secret`**: The secret used to verify webhook signatures. - **`timeout`**: The maximum time to wait for specific events. Refer to `configuration.md` and `api-reference/configuration-class.md` for a complete list of configuration options and detailed setup instructions. ``` -------------------------------- ### Get Gem Version Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/types.md Access the current version of the VCR Stripe Webhook gem. This is useful for checking compatibility or reporting issues. ```ruby VcrStripeWebhook::VERSION # => "0.3.0" ``` -------------------------------- ### Main Module Methods Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/README.md Public methods available in the main VcrStripeWebhook module for integrating with VCR and handling Stripe webhooks. ```APIDOC ## `use_cassette` ### Description Wraps VCR cassettes to enable webhook recording and replay functionality. ### Method Signature `VcrStripeWebhook.use_cassette(name, options = {}, &block)` ### Parameters - **name** (String) - The name of the VCR cassette. - **options** (Hash) - Optional configuration for VCR and webhook handling. - **block** (Proc) - The block of code to execute within the cassette context. ### Usage ```ruby VcrStripeWebhook.use_cassette('my_webhook_cassette') do # Your test code that triggers webhooks end ``` ``` ```APIDOC ## `receive_webhook_event` ### Description Waits for a single specific Stripe webhook event to be received. ### Method Signature `VcrStripeWebhook.receive_webhook_event(event_type, timeout: nil)` ### Parameters - **event_type** (String) - The type of the Stripe event to wait for (e.g., 'payment_intent.succeeded'). - **timeout** (Integer, optional) - The maximum time in seconds to wait for the event. ### Usage ```ruby VcrStripeWebhook.receive_webhook_event('customer.created') ``` ``` ```APIDOC ## `receive_webhook_events` ### Description Waits for multiple specific Stripe webhook events to be received. ### Method Signature `VcrStripeWebhook.receive_webhook_events(event_types, timeout: nil)` ### Parameters - **event_types** (Array) - An array of event types to wait for. - **timeout** (Integer, optional) - The maximum time in seconds to wait for all events. ### Usage ```ruby VcrStripeWebhook.receive_webhook_events(['charge.succeeded', 'customer.deleted']) ``` ``` ```APIDOC ## `configuration` ### Description Provides access to the gem's configuration object. ### Method Signature `VcrStripeWebhook.configuration` ### Returns - **Configuration** - An instance of the `VcrStripeWebhook::Configuration` class. ### Usage ```ruby config = VcrStripeWebhook.configuration config.timeout = 10 ``` ``` ```APIDOC ## `logger` ### Description Provides access to the gem's logger instance. ### Method Signature `VcrStripeWebhook.logger` ### Returns - **Logger** - The configured logger object. ### Usage ```ruby VcrStripeWebhook.logger.info('Webhook received') ``` ``` ```APIDOC ## `stop` ### Description Cleans up resources used by the `EventReceiver`, typically called after tests. ### Method Signature `VcrStripeWebhook.stop` ### Usage ```ruby VcrStripeWebhook.stop ``` ``` -------------------------------- ### Configuration Class Methods Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/README.md Methods for managing gem settings. ```APIDOC ## `Configuration#timeout` ### Description Gets or sets the timeout for waiting for webhook events. ### Method Signature `config.timeout` or `config.timeout = value` ### Parameters - **value** (Integer) - The timeout duration in seconds. ### Usage ```ruby VcrStripeWebhook.configuration.timeout = 15 ``` ``` ```APIDOC ## `Configuration#cassette_library_dir` ### Description Gets or sets the directory where VCR cassettes are stored. ### Method Signature `config.cassette_library_dir` or `config.cassette_library_dir = value` ### Parameters - **value** (String) - The path to the cassette library directory. ### Usage ```ruby VcrStripeWebhook.configuration.cassette_library_dir = 'test/cassettes' ``` ``` ```APIDOC ## `Configuration#stripe_api_key` ### Description Gets or sets the Stripe API key used for test mode. ### Method Signature `config.stripe_api_key` or `config.stripe_api_key = value` ### Parameters - **value** (String) - The Stripe API key. ### Usage ```ruby VcrStripeWebhook.configuration.stripe_api_key = 'sk_test_12345' ``` ``` -------------------------------- ### Initialize ReadyWaiter Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Instantiates the ReadyWaiter class, which is used internally to synchronize with the Stripe CLI's startup process. The initial state is not ready. ```ruby ReadyWaiter.new ``` -------------------------------- ### Signal Stripe CLI Readiness Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Signals that the Stripe CLI has completed its startup and is ready. This action wakes up any threads that are blocked in wait_ready. ```ruby waiter.signal_ready ``` -------------------------------- ### Handle VcrStripeWebhook EventWaitTimeout Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/errors.md Catch `VcrStripeWebhook::EventWaitTimeout` when webhook events are not received within the specified timeout. This example shows how to check if the cassette is in recording mode. ```ruby VcrStripeWebhook.use_cassette("test") do begin webhook_event = VcrStripeWebhook.receive_webhook_event("customer.created", timeout: 5) do Stripe::Customer.create(email: 'test@example.com') end rescue VcrStripeWebhook::EventWaitTimeout => e puts "Timeout waiting for webhook: #{e.message}" puts "Recording: #{@cassette.recording?}" end end ``` -------------------------------- ### Server Methods Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Methods to control the lifecycle and behavior of the VCR Stripe Webhook server. ```APIDOC ## close Stops the server and closes the TCP connection. ```ruby server.close ``` **Returns:** nil **Side effects:** - Closes the TCPServer - Accept thread will terminate (IOError caught and handled) - No new connections accepted ``` ```APIDOC ## join Waits for the accept thread to complete. ```ruby server.join ``` **Returns:** nil **Usage:** Block until server stops accepting connections. ``` -------------------------------- ### Set Environment Variables for Stripe Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Configure Stripe API keys and VCR recording mode using environment variables in a .env.test file. Useful for testing and CI environments. ```bash # .env.test STRIPE_SECRET_KEY=sk_test_4eC39HqLyjWDarhtT657j51F STRIPE_PUBLISHABLE_KEY=pk_test_51234567890abcdefghij VCR_RECORD_MODE=none # For CI ``` -------------------------------- ### Get Current Event Cassette Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/vcr-stripe-webhook-module.md Retrieves the currently active EventCassette within a `use_cassette` block. Returns nil if not within such a block. Primarily for internal library use. ```ruby VcrStripeWebhook.current_event_cassette ``` -------------------------------- ### Configure Stripe API Key in Ruby Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Set the Stripe API key globally for Stripe operations and for VCR Stripe Webhook configuration. Ensure environment variables are loaded before this code runs. ```ruby # config/initializers/stripe.rb Stripe.api_key = ENV['STRIPE_SECRET_KEY'] # spec/spec_helper.rb VcrStripeWebhook.configuration.stripe_api_key = ENV['STRIPE_SECRET_KEY'] ``` -------------------------------- ### Get Server Port Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Retrieve the port number the server is currently listening on. This is useful for configuring external services like the Stripe CLI to forward webhooks to this server. ```ruby server.port ``` -------------------------------- ### Get Event Data as JSON String Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-class.md Convert the Stripe event object into a JSON string. This is suitable for sending webhook payloads to HTTP endpoints that expect JSON. ```ruby webhook_event = VcrStripeWebhook.receive_webhook_event("customer.created") { ... } json_payload = webhook_event.as_json post webhook_endpoint_path, params: webhook_event.as_json, headers: { 'Content-Type' => 'application/json' } ``` -------------------------------- ### Access Global Configuration Object Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Access the global configuration object to inspect or modify settings. Returns a `VcrStripeWebhook::Configuration` instance. ```ruby VcrStripeWebhook.configuration ``` -------------------------------- ### Stripe CLI for Webhook Forwarding Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/README.md Configures the Stripe CLI to listen for webhooks and forward them to a local test server. ```bash stripe listen --forward-to localhost:54321/ ``` -------------------------------- ### Stop the Event Receiver Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-receiver-class.md Stops the webhook server and Stripe CLI. This method cleans up by closing the Stripe CLI process and the TCP server, and resets the internal started flag. ```ruby event_receiver.stop ``` -------------------------------- ### EventReceiver Class Definition Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/types.md Defines the EventReceiver class, a singleton responsible for managing the webhook server and Stripe CLI integration. Use `instance` to get the singleton and `terminate` to shut it down. ```ruby class EventReceiver def self.instance() -> EventReceiver def self.terminate() -> nil def initialize() def start() -> nil def stop() -> nil def use_cassette(cassette) { |vcr_cassette| ... } -> nil def wait_for_rest_webhooks() -> nil end ``` -------------------------------- ### VcrStripeWebhook.configuration Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/vcr-stripe-webhook-module.md Returns the global Configuration object for managing gem settings. This object allows accessing and setting properties like timeout, cassette_library_dir, and stripe_api_key. ```APIDOC ## configuration Returns the global Configuration object for managing gem settings. ```ruby VcrStripeWebhook.configuration ``` **Returns:** Configuration instance **Properties:** The returned Configuration object allows accessing and setting: - `timeout` — Webhook wait timeout in seconds (default: 5) - `cassette_library_dir` — Directory for storing webhook cassettes - `stripe_api_key` — Stripe API key for test mode **Example:** ```ruby # Get default timeout timeout = VcrStripeWebhook.configuration.timeout # Set custom timeout VcrStripeWebhook.configuration.timeout = 10 # Set cassette directory VcrStripeWebhook.configuration.cassette_library_dir = "spec/cassettes/webhooks" # Set Stripe API key VcrStripeWebhook.configuration.stripe_api_key = 'sk_test...' ``` ``` -------------------------------- ### Instantiate Event Class Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-class.md Create a new Event instance by providing the event type and the event hash. This is useful for manually constructing event objects. ```ruby event_hash = { "id" => "evt_123", "object" => "event", "type" => "customer.created", "data" => { "object" => { "id" => "cus_123", "object" => "customer" } } } event = VcrStripeWebhook::Event.new("customer.created", event_hash) ``` -------------------------------- ### Instantiate ProcWaiter Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/waiter-classes.md Create a ProcWaiter instance by providing a proc that accepts an array of events and returns a boolean. This proc defines the condition to wait for. ```ruby ProcWaiter.new(wait_until_proc) ``` ```ruby # Wait until 2 or more events received waiter = ProcWaiter.new(->(events) { events.size >= 2 }) ``` ```ruby # Wait for a specific event type or multiple conditions waiter = ProcWaiter.new(->(events) { types = events.map(&:type) types.include?('customer.created') && events.size >= 1 }) ``` -------------------------------- ### Access Event Data as Hash Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-class.md Get the complete Stripe event object as a Ruby Hash. This is useful for inspecting or processing event data using hash methods like `dig`. ```ruby webhook_event = VcrStripeWebhook.receive_webhook_event("customer.created") { ... } event_hash = webhook_event.as_hash customer_id = event_hash.dig("data", "object", "id") customer_object = event_hash.dig("data", "object", "object") expect(event_hash["type"]).to eq("customer.created") expect(event_hash["object"]).to eq("event") ``` -------------------------------- ### Configure Custom Cassette Location - VcrStripeWebhook Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/configuration-class.md Specify a custom directory path for storing recorded webhook events. This allows for better organization of test fixtures. ```ruby # Configure custom cassette location VcrStripeWebhook.configuration.cassette_library_dir = Rails.root.join("spec/fixtures/webhooks") VcrStripeWebhook.use_cassette("customer_created") do # Cassette will be stored at: # spec/fixtures/webhooks/customer_created.stripe_webhooks.yml end ``` -------------------------------- ### Event Constructor Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-class.md Initializes a new Event object with the event type and its corresponding hash data. ```APIDOC ## Constructor ### Description Initializes a new Event object with the event type and its corresponding hash data. ### Signature ```ruby Event.new(type, event_hash) ``` ### Parameters #### Path Parameters - **type** (String) - Required - Stripe event type (e.g., 'customer.created') - **event_hash** (Hash) - Required - Full Stripe event object as a Hash ### Returns Event instance ### Example ```ruby event_hash = { "id" => "evt_123", "object" => "event", "type" => "customer.created", "data" => { "object" => { "id" => "cus_123", "object" => "customer" } } } event = VcrStripeWebhook::Event.new("customer.created", event_hash) ``` ``` -------------------------------- ### Get Parsed JSON Value Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/server-class.md Returns the parsed JSON value (Hash or Array) if the content is JSON and parsing succeeds. Returns nil if the content is not JSON or if parsing fails, without throwing exceptions. ```ruby parser.json_value ``` -------------------------------- ### Use VcrStripeWebhook.use_cassette for Multiple Webhook Events Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/README.md Use `VcrStripeWebhook.receive_webhook_events` within `VcrStripeWebhook.use_cassette` to record or replay multiple webhook events triggered by a sequence of Stripe API calls. This is useful for testing scenarios involving several related events. ```ruby VcrStripeWebhook.use_cassette("create_customer_and_attach_payment_method") do |vcr_cassette| stripe_customer = nil # Get webhook payloads from Stripe server or current cassette webhook_events = VcrStripeWebhook.receive_webhook_events( event_types: %w[customer.created payment_method.attached]) do customer_params = { email: "test-user@example.com", name: "test-user" } stripe_customer = Stripe::Customer.create(customer_params) stripe_payment_method = Stripe::PaymentMethod.retrieve("pm_card_visa") stripe_payment_method.attach(customer: stripe_customer.id) end webhook_events.each do |webhook_event| post your_stripe_webhook_path, params: webhook_event.as_json, headers: { 'Content-Type: application/json' } end # Insert assertions here ensure stripe_customer&.delete end ``` -------------------------------- ### ProcWaiter Constructor Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/waiter-classes.md Initializes a ProcWaiter with a custom proc to evaluate webhook events. ```APIDOC ## ProcWaiter.new ### Description Waits for a custom condition defined by a proc to be satisfied. Used by `VcrStripeWebhook.receive_webhook_events`. ### Method `ProcWaiter.new(wait_until_proc)` ### Parameters #### Path Parameters - **wait_until_proc** (Proc) - Required - Proc that receives events array and returns boolean ### Request Example ```ruby # Wait until 2 or more events received waiter = ProcWaiter.new(->(events) { events.size >= 2 }) # Wait for a specific event type or multiple conditions waiter = ProcWaiter.new(->(events) { types = events.map(&:type) types.include?('customer.created') && events.size >= 1 }) ``` ### Returns ProcWaiter instance ``` -------------------------------- ### Set Stripe API Key Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/configuration.md Configure the Stripe test-mode API key used by the Stripe CLI. This key must be a test-mode key (starts with `sk_test_`) and have permissions for webhook forwarding. If not set, it defaults to `Stripe.api_key`. ```ruby VcrStripeWebhook.configuration.stripe_api_key = ENV['STRIPE_TEST_KEY'] ``` ```ruby VcrStripeWebhook.configuration.stripe_api_key = 'sk_test_4eC39HqLyjWDarhtT657j51F' ``` ```ruby Stripe.api_key = 'sk_test_...' # VcrStripeWebhook will use Stripe.api_key by default ``` ```ruby # config/initializers/stripe.rb Stripe.api_key = ENV.fetch('STRIPE_SECRET_KEY') # spec/spec_helper.rb require 'vcr_stripe_webhook' VcrStripeWebhook.configuration.stripe_api_key = ENV.fetch('STRIPE_SECRET_KEY') ``` -------------------------------- ### Configuration Class Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/GENERATED.txt The `Configuration` class allows you to customize the behavior of VCR Stripe Webhook, such as setting timeouts and specifying cassette storage directories. ```APIDOC ## Configuration Options ### timeout - **Type**: Integer - **Description**: The maximum time in seconds to wait for webhook events. Defaults to 30 seconds. ### cassette_library_dir - **Type**: String - **Description**: The directory where cassette files are stored. Defaults to 'vcr_cassettes'. ### stripe_api_key - **Type**: String - **Description**: Your Stripe API key, used for verifying webhook signatures. This should be set in your environment or configuration. ``` -------------------------------- ### Event#to_h Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/event-class.md Returns a serialization format used internally for cassette storage. ```APIDOC ## to_h ### Description Returns a serialization format used internally for cassette storage. ### Signature ```ruby event.to_h ``` ### Returns Hash with structure: `{ "type" => type, "value" => as_hash }` ### Usage Used internally for YAML serialization in cassette files. Generally not needed for consumer code. ### Example ```ruby event = VcrStripeWebhook::Event.new("customer.created", event_hash) serialized = event.to_h # => { "type" => "customer.created", "value" => {...full event hash...} } ``` ``` -------------------------------- ### Stripe CLI Listen Command Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md The command used to spawn the Stripe CLI for listening to webhooks. It forwards traffic to a specified local port. ```bash stripe listen --forward-to localhost:{server_port}/ ``` -------------------------------- ### EventReceiver Stripe CLI Lifecycle Management Source: https://github.com/shunichi/vcr_stripe_webhook/blob/main/_autodocs/api-reference/stripe-cli-class.md Illustrates the pattern for initializing and terminating the Stripe CLI within an EventReceiver class. This manages the CLI's lifecycle during webhook event processing. ```ruby # In EventReceiver.initialize: @cli = VcrStripeWebhook::StripeCLI.new(@server.port, api_key) # In EventReceiver.stop: @cli.terminate ```