Usual Docs
View as Markdown

Chase failed payments

When a renewal payment fails, Usual retries it on a schedule (by default 1, 3, 5 and 7 days later) and, for card problems, Shopify emails the customer a secure link to update their card. This recipe finds what's still failing and nudges the right customers.

1. What's failing

bash
curl "https://regular-subs.fly.dev/api/v1/billing/cycles?state=retry_scheduled&limit=100" \
  -H "Authorization: Bearer $USUAL_KEY"

Each cycle has its attempts, with Shopify's error code on each failed one: EXPIRED_PAYMENT_METHOD, INSUFFICIENT_FUNDS, CARD_DECLINED and so on, plus when the next retry is. GET /billing/summary gives the totals.

2. Ask for a new card where it'll help

Retrying an expired card won't work; a new card will. Send the secure update link:

bash
curl -X POST https://regular-subs.fly.dev/api/v1/subscriptions/sub_123/payment-update \
  -H "Authorization: Bearer $USUAL_KEY" \
  -H "Content-Type: application/json" -d '{}'

Shopify sends the email; nobody, including us, sees card details. It's sent at most once an hour per subscription. Usual already sends it automatically on the first card failure, so use this for follow-ups or when a customer asks.

3. Retry now (optional)

Once the customer has updated their card, you can retry without waiting:

bash
curl -X POST "https://regular-subs.fly.dev/api/v1/billing/cycles/cyc_456/retry?preview=true" \
  -H "Authorization: Bearer $USUAL_KEY" \
  -H "Content-Type: application/json" -d '{}'

Retrying takes money, so it's a financial change: from an API key or an agent it always waits for someone at the store to approve it in Usual โ†’ Activity.

A weekly report, with an agent

Ask your agent: "Every Monday, list the payments still failing, grouped by reason, and send card-update emails to anyone whose card expired." It uses list_billing_cycles and plans subscriptions.send_payment_update for each, which is low risk, so it doesn't need approval.