Skip to main content

Enforce spend thresholds

To reduce fraud in Product-Led Growth (PLG) workflows, Metronome supports spend threshold billing. This feature allows you to cap the amount a customer can spend before being charged, thereby limiting your exposure to uncollected revenue.

After applying a spend threshold to a contract, watch for webhook notifications to be alerted when payments succeed or fail.

info

Spend threshold billing is currently in beta. It’s available for production use, but you may encounter product limitations. Breaking changes may occur.

Create a contract with spend thresholds

When you create a contract in Metronome, you can optionally configure a spend_threshold_configuration. This config dictates:

  • The threshold_amount for the customer’s contract: how much they can spend before a payment attempt is triggered
  • The payment_gate_config:
    • Configure whether to payment gate the release of the commit and what gateway to use. Select EXTERNAL if you are using a gateway Metronome does not currently support.
    • If using Stripe, configure PAYMENT_TYPE to dictate whether payment is sent as an invoice through Stripe Billing or directly as a paymentIntent to Stripe's payment gateway.
    • If using Stripe, select your existing tax provider.
  • What product_id should be used to represent the commit: the product_id dictates what the customer sees on their incremental invoice
Configure billing

If using Stripe as your payment gateway, ensure there is a valid Stripe billing configuration set on the contract. Additionally, set spend_threshold_configuration.is_enabled to true if you want Metronome to immediately evaluate the contract after its creation.

Create contracts with spend threshold in the Metronome app or using the Metronome API.

{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"rate_card_id": "a7bc3775-b651-46b6-b7e4-d225a7e55c4c",
"starting_at": "2025-04-01T00:00:00.000Z",
"billing_provider_configuration": {
"billing_provider_configuration_id": "211ef270-098f-422c-9ca8-7999bb9156cb"
},
...
"spend_threshold_configuration": {
"commit": {
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"name": "black_mesa_commit",
"description": "hello_its_me_im_in_california_dreaming"
},
"is_enabled": true,
"payment_gate_config": {
"payment_gate_type": "NONE"
},
"threshold_amount": 200
}
}

Update a contract’s spend threshold

You can update or add a spend_threshold_configuration at any point by editing the user's contract. Add spend threshold limits to existing, non-limited contracts or change existing limits on a contract (for example, after some period of successful payments).

Note that these changes take effect immediately.

Edit contracts in the Metronome app or with the Metronome API. This API call adds a spend threshold to a contract:

{
"customer_id": "52f5a554-b887-4899-b919-4eb7789c6bf3",
"contract_id": "8a5529d3-f353-4231-bedf-7e83f5e9331d",
"add_spend_threshold_configuration": {
"commit": {
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"name": "threshold_charge",
"description": "one time for the one time"
},
"is_enabled": true,
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"stripe_config": {
"payment_type": "INVOICE"
}
},
"threshold_amount": 100
}
}

This API call updates an existing spend threshold:

{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"contract_id": "6058587f-763c-400f-a822-3edb3eb2b86b",
"update_spend_threshold_configuration": {
"is_enabled": true,
"threshold_amount": 100,
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"stripe_config": {
"payment_type": "INVOICE"
}
}
}
}

Spend threshold billing lifecycle

To best utilize spend threshold billing, consider its lifecycle: the actions Metronome takes and what actions you may need to take.

1. Charge for spend threshold amount (Metronome)

Once configured, Metronome evaluates the total spend of usage invoices on the contract to determine when the threshold_amount has been reached. If the payment_gate_config is set to Stripe, Metronome attempts to charge the customer the threshold_amount.

If payment is successful, Metronome creates a commit for the same amount, which the outstanding balance draws down from. If a customer still exceeds their threshold, Metronome continues to charge the customer their threshold_amount until their balance is brought below this amount.

2. Manage notifications (you)

Metronome fires three types of webhook notifications for spend threshold billing:

  • payment_gate.threshold_reached when the customer hits their threshold.
  • payment_gate.payment_status after payment has been attempted. The status of that payment, paid or failed, is denoted in the payment_status field.
  • payment_gate.payment_pending_action_required if intervention is required to process payment.

Your webhook endpoint must be configured to handle these notifications accordingly.

3. Handle failed payments (you)

When a payment fails, you receive a payment_gate.payment_status notification, with a value of failed. Additionally, the contract's spend_threshold_configuration.is_enabled field is set to false. You should expect to see a voided invoice in Metronome and Stripe for this transaction. See example webhook below:

{
"id": "417fcaa4-f3cf-434e-ab20-f70204cfd5ef",
"properties": {
"workflow_type": "spend",
"customer_id": "d290dec8-4ebb-4e73-89ef-45ed3443ca67",
"contract_id": "80b07d70-c84e-4ff0-b42c-875defff0931",
"invoice_id": "dd864572-9787-573f-9c74-e5159b4ea97c",
"error_message": "three_d_secure_redirect",
"billing_provider": {
"type": "stripe",
"stripe": {
"payment_intent_id": "pi_3ROpJCIkTQSg6Mm31fNUnPKx",
"error": {
"type": "card_error",
"code": "expired_card",
"decline_code": "expired_card",
"message": "Your card has expired."
},
},
},
},
"type": "payment_gate.payment_status"
}

At this point, you should follow up with your customer either directly or by creating an automated workflow triggered by this webhook notification.

Once you are ready to reattempt payment, set the contract's spend_threshold_configuration.is_enabled field to true. This forces the contract to evaluate against the threshold_amount, resulting in a new payment attempt.

No automatic retries

Metronome does not automatically retry failed payments (as any automatic retries would likely fail, too).

Manually create payment-gated commits

Spend threshold billing supports the addition of payment-gated commits on contracts: Metronome must successfully charge the customer before the commit resource is created in Metronome. When you attempt to add a payment-gated commit to a contract:

  1. Metronome immediately triggers a payment attempt based on the invoice amount.
  2. If the payment succeeds, Metronome grants the release of the commit.
  3. If the payment fails, Metronome voids the resource and sends a webhook notification.

Create a contract with a payment-gated commit

If the customer does not exist or does not have a previous contract, you can create a contract with a payment-gated commit. When creating a commit, the fields are the exact same as the existing commit flow, except you need to complete the payment_gate_config. Set the type to STRIPE and make sure you add a valid Stripe billing configuration to the contract.

This API call creates a contract with a payment-gated commit:

{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"rate_card_id": "a7bc3775-b651-46b6-b7e4-d225a7e55c4c",
"starting_at": "2025-04-01T00:00:00.000Z",
"billing_provider_configuration": {
"billing_provider_configuration_id": "211ef270-098f-422c-9ca8-7999bb9156cb"
},
...
"commits": [
{
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"type": "prepaid",
"invoice_schedule": {
"schedule_items": [
{
"timestamp": "2025-04-01T00:00:00.000Z",
"amount": 2000
}
]
},
"access_schedule": {
"schedule_items": [
{
"amount": 2000,
"starting_at": "2025-04-01T00:00:00.000Z",
"ending_before": "2026-04-01T00:00:00.000Z"
}
]
},
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"tax_type": "STRIPE"
},
"priority": 100
}
]
}
info

When creating a commit, you need to specify the timestamp of the associated invoice in Metronome. Use the invoice_schedule.schedule_items.timestamp to do so. This does not impact when the charge is processed in Stripe (which is immediate), but rather sets the issued_at date in Metronome.

Add a payment-gated commit to an existing contract

You can add a payment-gated commit at any point by editing the user's contract. Ensure the contract has a valid billing configuration set up before creating the commit.

This is how we recommend clients handle manual recharging workflows for their customers where customers directly purchase credits in your platform.

This API call adds a payment-gated commit to an existing contract:

{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"contract_id": "d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc",
"add_commits": [
{
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"type": "prepaid",
"invoice_schedule": {
"schedule_items": [
{
"timestamp": "2025-04-01T00:00:00.000Z",
"amount": 2000
}
]
},
"access_schedule": {
"schedule_items": [
{
"amount": 2000,
"starting_at": "2025-04-01T00:00:00.000Z",
"ending_before": "2026-04-01T00:00:00.000Z"
}
]
},
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"tax_type": "STRIPE"
},
"priority": 100
}
]
}

Manage Notifications

Two types of webhook notifications are emitted when creating a payment-gated commit:

  • payment_gate.payment_status after payment has been attempted. The status of that payment, paid or failed , is denoted in the payment_status field.
  • payment_gate.payment_pending_action_required if intervention is required to process payment.

Handle failed payments

If payment fails, the associated invoice in Metronome and Stripe is voided and no commit is created. To retry the payment, send a new API request with the relevant commit information.

No automatic retries

Metronome does not automatically retry failed payments (as any automatic retries would likely fail, too).

Using external payment gate

If using the EXTERNAL option for payment_gate_type, you are responsible for facilitating payment and letting Metronome know the response. Follow this workflow:

  • Set the spend threshold config with payment_gate_type set to EXTERNAL
  • Listen for payment_gate.external_initiate that indicates Metronome is ready to recieve the outcome of the payment
  • Save the workflow_id - you will need this to release the commit
  • Charge the customer in your payment gateway of choice
  • Call commits/threshold-billing/release to either release the commit on successful payment, or cancel the commit in case of failure.