feat: add StripeClient.create_price for metered billing
This commit is contained in:
parent
448ed20401
commit
3e74ac5897
3 changed files with 79 additions and 1 deletions
|
|
@ -94,4 +94,6 @@ config :towerops,
|
|||
# Reduce debounce delay in tests for faster test execution (50ms vs 500ms in prod)
|
||||
agent_channel_debounce_ms: 50,
|
||||
# Reduce device deletion delay for faster tests (10ms vs 500ms in prod)
|
||||
device_deletion_delay_ms: 10
|
||||
device_deletion_delay_ms: 10,
|
||||
# Stripe test configuration
|
||||
stripe_product_id: "prod_test"
|
||||
|
|
|
|||
|
|
@ -125,6 +125,33 @@ defmodule Towerops.Billing.StripeClient do
|
|||
end
|
||||
end
|
||||
|
||||
# Price Management
|
||||
|
||||
@doc """
|
||||
Create a new Price object for metered billing.
|
||||
|
||||
Returns {:ok, price_object} or {:error, reason}.
|
||||
"""
|
||||
def create_price(unit_amount_decimal) when is_binary(unit_amount_decimal) do
|
||||
params = %{
|
||||
product: stripe_product_id(),
|
||||
currency: "usd",
|
||||
unit_amount_decimal: unit_amount_decimal,
|
||||
recurring: %{
|
||||
interval: "month",
|
||||
usage_type: "metered",
|
||||
aggregate_usage: "max"
|
||||
},
|
||||
billing_scheme: "per_unit",
|
||||
metadata: %{
|
||||
created_by: "towerops_admin_ui",
|
||||
created_at: DateTime.to_iso8601(DateTime.utc_now())
|
||||
}
|
||||
}
|
||||
|
||||
post("/v1/prices", params)
|
||||
end
|
||||
|
||||
# HTTP Request Helpers
|
||||
|
||||
defp get(path) do
|
||||
|
|
@ -255,4 +282,8 @@ defmodule Towerops.Billing.StripeClient do
|
|||
defp stripe_price_id do
|
||||
Application.fetch_env!(:towerops, :stripe_price_id)
|
||||
end
|
||||
|
||||
defp stripe_product_id do
|
||||
Application.fetch_env!(:towerops, :stripe_product_id)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -315,4 +315,49 @@ defmodule Towerops.Billing.StripeClientTest do
|
|||
StripeClient.create_customer(organization)
|
||||
end
|
||||
end
|
||||
|
||||
describe "create_price/1" do
|
||||
test "creates metered billing price at specified amount" do
|
||||
Req.Test.stub(StripeClient, fn conn ->
|
||||
assert conn.method == "POST"
|
||||
assert conn.request_path == "/v1/prices"
|
||||
|
||||
# Verify form params
|
||||
{:ok, body, conn} = Plug.Conn.read_body(conn)
|
||||
params = URI.decode_query(body)
|
||||
|
||||
assert params["unit_amount_decimal"] == "2.50"
|
||||
assert params["currency"] == "usd"
|
||||
assert params["recurring[interval]"] == "month"
|
||||
assert params["recurring[usage_type]"] == "metered"
|
||||
assert params["recurring[aggregate_usage]"] == "max"
|
||||
assert params["billing_scheme"] == "per_unit"
|
||||
|
||||
conn
|
||||
|> Plug.Conn.put_resp_content_type("application/json")
|
||||
|> Plug.Conn.send_resp(
|
||||
200,
|
||||
Jason.encode!(%{
|
||||
"id" => "price_test123",
|
||||
"object" => "price",
|
||||
"unit_amount_decimal" => "2.50"
|
||||
})
|
||||
)
|
||||
end)
|
||||
|
||||
assert {:ok, %{"id" => "price_test123"}} = StripeClient.create_price("2.50")
|
||||
end
|
||||
|
||||
test "returns error on API failure" do
|
||||
Req.Test.stub(StripeClient, fn conn ->
|
||||
error = %{"error" => %{"message" => "Invalid amount"}}
|
||||
|
||||
conn
|
||||
|> Plug.Conn.put_resp_content_type("application/json")
|
||||
|> Plug.Conn.send_resp(400, Jason.encode!(error))
|
||||
end)
|
||||
|
||||
assert {:error, {:bad_request, "Invalid amount"}} = StripeClient.create_price("invalid")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue