{
  "name": "Billable Transaction → Stripe Invoice → Gmail Delivery — Purrly",
  "platform": "zapier",
  "metadata": {
    "platform": "zapier",
    "title": "Billable Transaction → Stripe Invoice → Gmail Delivery",
    "trigger_app": "stripe",
    "trigger_event": "billable_transaction",
    "action_apps": ["stripe", "stripe", "gmail"],
    "required_accounts": [
      {
        "app": "Stripe",
        "purpose": "Source billing account and invoice system of record.",
        "fields": [
          "STRIPE_API_KEY (write invoices, read customers and payment records)"
        ]
      },
      {
        "app": "Gmail",
        "purpose": "Destination for the customer-facing invoice message.",
        "fields": ["GMAIL_ACCOUNT", "FROM_NAME"]
      }
    ],
    "placeholders": [
      "[STRIPE_API_KEY]",
      "[GMAIL_ACCOUNT]",
      "[FROM_NAME]",
      "[INVOICE_SUBJECT]",
      "[INVOICE_DUE_DAYS]",
      "[REPLAY_LOOKUP_KEY]"
    ]
  },
  "flow": {
    "modules": [
      {
        "id": 1,
        "key": "stripe.billable_transaction_trigger",
        "app": "stripe",
        "role": "trigger",
        "event": "billable_transaction",
        "description": "Fires when the chosen Stripe billing event marks work or a payment as ready to invoice. Use the included transaction reference as the stable replay key.",
        "output_fields": [
          "transaction.id",
          "transaction.created",
          "customer.id",
          "customer.email",
          "customer.name",
          "line_items",
          "total.amount",
          "total.currency",
          "due_date",
          "metadata"
        ]
      },
      {
        "id": 2,
        "key": "stripe.create_invoice_action",
        "app": "stripe",
        "role": "action",
        "operation": "create_invoice",
        "description": "Creates a draft Stripe invoice from the billable transaction. The customer, line items, amount, currency, due-date rule, and replay key are mapped from the trigger instead of typed into Zapier.",
        "input_fields": [
          "customer_id (from module 1.customer.id)",
          "line_items (from module 1.line_items)",
          "currency (from module 1.total.currency)",
          "due_date (from module 1.due_date or [INVOICE_DUE_DAYS])",
          "collection_method (send_invoice or charge_automatically)",
          "idempotency_key (from module 1.transaction.id or [REPLAY_LOOKUP_KEY])"
        ],
        "output_fields": [
          "invoice.id",
          "invoice.number",
          "invoice.status",
          "invoice.amount_due",
          "invoice.due_date",
          "invoice.customer_email"
        ]
      },
      {
        "id": 3,
        "key": "stripe.finalize_invoice_action",
        "app": "stripe",
        "role": "action",
        "operation": "finalize_invoice",
        "description": "Finalizes the draft invoice so Stripe locks the totals and exposes the hosted invoice URL. Keep Stripe as the source of truth for payment status; Gmail only carries the customer-facing notification.",
        "input_fields": [
          "invoice_id (from module 2.invoice.id)",
          "auto_advance (true)",
          "send_invoice (false — Gmail handles delivery)"
        ],
        "output_fields": [
          "invoice.id",
          "invoice.number",
          "invoice.status",
          "invoice.amount_due",
          "invoice.due_date",
          "invoice.hosted_invoice_url",
          "invoice.pdf_url"
        ]
      },
      {
        "id": 4,
        "key": "gmail.send_invoice_action",
        "app": "gmail",
        "role": "action",
        "operation": "send_email",
        "description": "Sends a concise customer-facing message with the finalized invoice number, amount, due date, and Stripe hosted invoice link. The link always opens the current Stripe payment page.",
        "input_fields": [
          "account ([GMAIL_ACCOUNT])",
          "to_email (from module 1.customer.email)",
          "from_name ([FROM_NAME])",
          "subject ([INVOICE_SUBJECT])",
          "invoice_number (from module 3.invoice.number)",
          "amount_due (from module 3.invoice.amount_due)",
          "due_date (from module 3.invoice.due_date)",
          "hosted_invoice_url (from module 3.invoice.hosted_invoice_url)",
          "pdf_url (optional, from module 3.invoice.pdf_url)"
        ],
        "output_fields": ["message.id", "thread.id", "message.timestamp"]
      }
    ]
  },
  "setup": {
    "estimated_minutes": 25,
    "steps": [
      {
        "order": 1,
        "title": "Create the Zap and connect Stripe",
        "detail": "In Zapier click Create Zap, choose Stripe as the trigger app, select the billable transaction event that matches your billing flow, and connect the Stripe account that owns the customers and invoices. Use [STRIPE_API_KEY] with permission to read customers and create or finalize invoices."
      },
      {
        "order": 2,
        "title": "Create the Stripe invoice",
        "detail": "Add the Stripe Create Invoice action. Map customer.id, line_items, total.currency, the source due date or [INVOICE_DUE_DAYS], and transaction.id as the idempotency or replay key. Test with a transaction that has one customer and at least one line item."
      },
      {
        "order": 3,
        "title": "Finalize the invoice and expose its hosted link",
        "detail": "Add Stripe Finalize Invoice, map invoice.id from the previous step, keep auto-advance enabled, and leave Stripe delivery off so the Gmail step owns the message. Confirm the test response includes invoice.number, amount_due, due_date, and hosted_invoice_url."
      },
      {
        "order": 4,
        "title": "Send the invoice through Gmail",
        "detail": "Connect [GMAIL_ACCOUNT], map the customer email from the trigger, set [FROM_NAME] and [INVOICE_SUBJECT], and build the body from the finalized invoice number, amount, due date, and hosted invoice URL. Add the PDF URL only if your process needs an attachment link."
      },
      {
        "order": 5,
        "title": "Test the replay guard and turn the Zap on",
        "detail": "Run the Zap twice with the same transaction ID to confirm the replay guard does not create a second invoice, then test a fresh transaction and verify the Gmail message opens the hosted Stripe invoice. Turn on the Zap and enable Zapier email-on-error notifications."
      }
    ]
  }
}
