towerops/setup_stripe_meter.exs
Graham McIntire d0e7eb4308
feat: add Stripe meter ID configuration
- Add stripe_meter_id to dev, runtime, and test configs
- Add STRIPE_METER_ID to k8s deployment secret references
- Use real Stripe meter and price IDs from Stripe setup
- Meter: mtr_test_61UHPU067veEZ7bhl41S77kvnTfgyODY
- Price: price_1T81XBS77kvnTfgyPlw1jF8N ($1/device/month)
- Include setup script for Stripe billing configuration
2026-03-06 11:08:06 -06:00

103 lines
2.9 KiB
Elixir

#!/usr/bin/env elixir
# Setup script for Stripe billing meter
stripe_key = "sk_test_51T7zcQS77kvnTfgyu0DCQU2xVKzeaneVCueHaXV3jsIw6HAwGWWllEL3J8jGZOybHAtPyu6oYIiuvJHhReFtTycE00VrJYJ8Ao"
product_id = "prod_U6DpFdl21ftiDz"
IO.puts("Creating Stripe billing meter...")
# Create billing meter
form_data =
URI.encode_query(%{
"display_name" => "Devices Monitored",
"event_name" => "devices_monitored",
"default_aggregation[formula]" => "sum",
"value_settings[event_payload_key]" => "value"
})
{output, exit_code} =
System.cmd(
"curl",
[
"-X",
"POST",
"https://api.stripe.com/v1/billing/meters",
"-u",
"#{stripe_key}:",
"-H",
"Stripe-Version: 2024-11-20.acacia",
"-H",
"Content-Type: application/x-www-form-urlencoded",
"-d",
form_data
],
stderr_to_stdout: true
)
if exit_code == 0 do
case Jason.decode(output) do
{:ok, meter} ->
IO.puts("\n✓ Billing meter created successfully!")
IO.puts(" Meter ID: #{meter["id"]}")
IO.puts(" Display name: #{meter["display_name"]}")
IO.puts(" Event name: #{meter["event_name"]}")
IO.puts("\nNow creating metered price...")
# Create metered price linked to the meter
price_form =
URI.encode_query(%{
"product" => product_id,
"currency" => "usd",
"recurring[interval]" => "month",
"recurring[usage_type]" => "metered",
"recurring[meter]" => meter["id"],
"billing_scheme" => "per_unit",
# $1.00 in cents
"unit_amount" => "100",
"nickname" => "Per Device Monthly"
})
{price_output, price_exit} =
System.cmd(
"curl",
[
"-X",
"POST",
"https://api.stripe.com/v1/prices",
"-u",
"#{stripe_key}:",
"-H",
"Stripe-Version: 2024-11-20.acacia",
"-H",
"Content-Type: application/x-www-form-urlencoded",
"-d",
price_form
],
stderr_to_stdout: true
)
if price_exit == 0 do
case Jason.decode(price_output) do
{:ok, price} ->
IO.puts("\n✓ Price created successfully!")
IO.puts(" Price ID: #{price["id"]}")
IO.puts(" Amount: $#{price["unit_amount"] / 100}/device/month")
IO.puts("\n" <> String.duplicate("=", 60))
IO.puts("SETUP COMPLETE!")
IO.puts(String.duplicate("=", 60))
IO.puts("\nAdd these to your Kubernetes secret:")
IO.puts(" STRIPE_METER_ID=#{meter["id"]}")
IO.puts(" STRIPE_PRICE_ID=#{price["id"]}")
{:error, _} ->
IO.puts("\nError creating price: #{price_output}")
end
end
{:error, _} ->
IO.puts("\nError: #{output}")
end
else
IO.puts("\nCurl failed: #{output}")
end