Stripe to Notion database without the glue
Append a row to any Notion database when a Stripe event fires. Customer logs, refunds journal, churn reasons. JSONata templating and idempotent retries, no glue code.
Free trial · From $19/mo · No credit card required
The problem
Every team builds the same Notion database eventually: a customers table, a refunds journal, a churn-reasons log. Then someone spends a Saturday gluing Stripe to Notion with a Zapier zap or a webhook handler running on a $5 box. The pipe stays brittle. Property names mismatch, dates arrive as strings, the rich text field wants an array of objects, and the Zap silently fails at 3am the day someone renames a property.
The Notion action handles the typing for you. Point it at a database by id, map Stripe event fields to Notion properties with JSONata, and Outbound takes care of the property type coercion, retries on 5xx, and dedup on Stripe's invocation id. It sits inside the Stripe Dashboard alongside the billing data, with one bill and one execution log.
How the Notion action works
- 1
Connect Notion via OAuth
Install Outbound, click Connect Notion, choose the workspace and which databases to expose. The integration token is stored encrypted and scoped to the pages you allowed — nothing else in the workspace is reachable. - 2
Pick a database and map properties
The action config lists every property on the database with its Notion type. Map each one to a JSONata expression against the Stripe event — {{customer.email}}, {{invoice.amount_paid / 100}}, today's date, anything. - 3
Add it to a workflow
Drop the Notion action into any Stripe Workflow. When the trigger event fires, the property mapping resolves against the event payload and Outbound posts the row. One invocation appends exactly one row, even on retry. - 4
Watch the execution log
Every append lands in the Outbound execution log with the Notion page id, latency, and any property validation errors. You can debug a bad mapping without leaving the Stripe Dashboard.
{
"trigger": "customer.subscription.created",
"action": "outbound.notion",
"database_id": "a1b2c3d4-...",
"properties": {
"Email": "{{customer.email}}",
"Plan": "{{items.data[0].price.nickname}}",
"MRR": "{{items.data[0].price.unit_amount / 100}}",
"Started": "{{$fromMillis(created * 1000)}}",
"Source": "Stripe"
}
}Example workflow configuration
Screenshot of the Notion action config panel inside the Stripe Workflow builder. Shows a database picker dropdown with a customer's workspace databases listed, a property mapping grid with Notion property names on the left and JSONata expression inputs on the right, and a small connection status indicator showing Notion is authenticated.
Outbound vs Zapier
| Outbound | Zapier | |
|---|---|---|
| Lives inside the Stripe Dashboard | — | |
| Pricing model | From $19/mo flat | Per-task billing |
| Notion property type checking before write | — | |
| Idempotent on Stripe invocation id | — | |
| Setup time | ≈3 minutes | 15–30 minutes |
| Templating language | JSONata | Zapier formatter steps |
| OAuth-scoped database access |
Frequently asked questions
Can I update an existing Notion row instead of appending?+
What Notion property types are supported?+
What if my Notion property names change?+
Does it count against my Notion API rate limits?+
Can multiple workflows write to the same database?+
Related integrations
Stripe to your own Postgres
When Notion isn't enough and you want the data in your own warehouse with full SQL access.
Send Stripe events to Discord
Pair with Notion: Notion as the durable log, Discord as the realtime alert channel.
Trigger Stripe workflows from Notion
Coming with Inbound: edit a Notion row and kick off a Stripe action.