Scheduled Stripe reports: failed payments, balance, new customers
Three Stripe jobs founders and finance teams set up again and again, each one a few lines of JSON instead of a scheduled function.
Example: past-due subscriptions to Slack every morning
{
"name": "Past-due subscriptions to #revenue",
"cron": { "expression": "0 9 * * 1-5", "time_zone": "America/New_York" },
"nodes": [
{ "id": "subs", "stripe_list_subscriptions": { "credential_id": "YOUR_STRIPE_KEY_ID", "status": "past_due", "limit": 100 } },
{ "id": "lines", "transform": { "template": "{ \"count\": \"{{ $.data.length }}\", \"lines\": { \"{{#each $.data}}\": \"• <https://dashboard.stripe.com/customers/{{ $.customer }}|{{ $.customer }}>: <https://dashboard.stripe.com/invoices/{{ $.latest_invoice }}|unpaid invoice>\" } }" } },
{ "id": "post", "slack_send_message": {
"webhook_url": "https://hooks.slack.com/services/T000/B000/XXXX",
"text": "*{{ $.count }} subscriptions are past due*\n{{ join($.lines, \"\\n\") }}" } }
]
}Example: your balance by email
{
"name": "Stripe balance email",
"cron": { "expression": "30 7 * * *", "time_zone": "America/Chicago" },
"nodes": [
{ "id": "balance", "stripe_retrieve_balance": { "credential_id": "YOUR_STRIPE_KEY_ID" } },
{ "id": "email", "smtp_send_email": {
"credential_id": "YOUR_GMAIL_CREDENTIAL_ID",
"to": "founder@acme.com",
"subject": "Stripe: {{ $.available[0].amount / 100 }} {{ $.available[0].currency }} available",
"text": "Available: {{ $.available[0].amount / 100 }} {{ $.available[0].currency }}\nPending: {{ $.pending[0].amount / 100 }} {{ $.pending[0].currency }}" } }
]
}Stripe amounts are in the smallest currency unit, so / 100 turns cents into dollars.
Example: new customers into your CRM
{
"name": "Stripe customers to CRM",
"cron": { "expression": "*/15 * * * *" },
"nodes": [
{ "id": "customers", "stripe_list_customers": { "credential_id": "YOUR_STRIPE_KEY_ID", "limit": 100 } },
{ "id": "upsert", "request": {
"method": "POST",
"endpoint": "https://crm.example.com/api/contacts/batch-upsert",
"credential_id": "YOUR_CRM_TOKEN_ID",
"body": "{ \"contacts\": { \"{{#each $.data}}\": { \"email\": \"{{ $.email }}\", \"name\": \"{{ $.name }}\", \"stripe_id\": \"{{ $.id }}\" } } }" } }
]
}Set up
Create a restricted key with read access to only what the job needs (subscriptions, customers, or balance), and save it as a bearer_token credential. For anything the built-in steps don't cover, a request step can call any Stripe endpoint with the same credential.
Reference
List Stripe subscriptions: stripe_list_subscriptions
Sends GET https://api.stripe.com/v1/subscriptions. Output for the next step: Stripe’s list: data, each subscription with id, customer, status and latest_invoice.
| Field | Type | Notes |
|---|---|---|
credential_id |
string, required | The id of a bearer_token credential holding a Stripe secret or restricted key (sk_… or rk_…) that can read subscriptions. |
status |
string | active, past_due, unpaid, canceled, incomplete, trialing or all. Omit for Stripe’s default (everything but canceled). |
limit |
integer | 1 to 100. Omit for Stripe’s default of 10. |
List Stripe customers: stripe_list_customers
Sends GET https://api.stripe.com/v1/customers. Output for the next step: Stripe’s list: data, newest first, each customer with id, email, name and created.
| Field | Type | Notes |
|---|---|---|
credential_id |
string, required | The id of a bearer_token credential holding a Stripe key that can read customers. |
limit |
integer | 1 to 100. Omit for Stripe’s default of 10. |
Read your Stripe balance: stripe_retrieve_balance
Sends GET https://api.stripe.com/v1/balance. Output for the next step: Stripe’s balance: available and pending, each a list of {amount, currency} in the smallest currency unit (cents).
| Field | Type | Notes |
|---|---|---|
credential_id |
string, required | The id of a bearer_token credential holding a Stripe key that can read the balance. |