All guides
Workify
Slack
Communicationbeginner

Send Workify Invoice Notifications to Slack

Get real-time Slack alerts when invoices are viewed, paid, or overdue. Keep your team in the loop without checking the Workify dashboard constantly.

What You'll Build

A Slack notification system that posts messages to a channel whenever key invoice events happen in Workify — invoice viewed by client, payment received, invoice overdue, or new invoice created.

Why This Matters

Knowing the moment a client opens your invoice changes how you follow up. Instead of chasing after 7 days of silence, you can reach out with "Just checking you received my invoice" the same afternoon they open it. And when payments land, your whole team knows instantly — no need to log in to check.

What You'll Need

  • A Workify Pro account (webhooks are a Pro feature)
  • A Slack workspace where you can add an incoming webhook
  • 10 minutes

Step 1: Create a Slack Incoming Webhook

  1. Go to api.slack.com/apps and click Create New App → From scratch
  2. Name it "Workify Notifications" and select your workspace
  3. Go to Incoming Webhooks → toggle it on
  4. Click Add New Webhook to Workspace and choose the channel (e.g. #invoicing or #payments)
  5. Copy the webhook URL — it looks like https://hooks.slack.com/services/T.../B.../...

Step 2: Configure a Workify Webhook

In Workify:

  1. Go to Settings → Webhooks
  2. Click Add webhook
  3. Paste your Make/Zapier URL (see Step 3) — or skip to the direct option below
  4. Select the events you want to receive:
    • invoice.viewed — client opened the invoice email
    • invoice.paid — payment recorded
    • invoice.overdue — invoice passed due date
    • invoice.created — new invoice created

Step 3: Transform and Forward to Slack

Workify's webhook payload needs to be formatted as a Slack message before forwarding. Use one of these approaches:

Option A: Make (Simplest)

  1. In Make, create a scenario with Webhooks → Custom webhook as trigger
  2. Use this URL as your Workify webhook endpoint
  3. Add an HTTP → Make a request module:
    • URL: your Slack incoming webhook URL
    • Method: POST
    • Body:
{
  "text": "{{if(trigger.event == 'invoice.paid'; '💰 Payment received'; if(trigger.event == 'invoice.viewed'; '👀 Invoice opened'; if(trigger.event == 'invoice.overdue'; '⚠️ Invoice overdue'; '📄 New invoice')))}}: *{{trigger.data.invoice_number}}* — {{trigger.data.client_name}} — {{trigger.data.total}}",
  "unfurl_links": false
}

Option B: Zapier

  1. Trigger: Webhooks by Zapier → Catch Hook — copy the URL into Workify
  2. Action: Slack → Send Channel Message
  3. Map the message text using Zapier's field mapper

Option C: Direct (Cloudflare Worker)

For zero latency and no third-party dependency, deploy a tiny worker that receives Workify webhooks and formats them for Slack:

const EVENT_LABELS: Record<string, string> = {
  'invoice.paid': '💰 Payment received',
  'invoice.viewed': '👀 Invoice opened by client',
  'invoice.overdue': '⚠️ Invoice overdue',
  'invoice.created': '📄 New invoice created',
}

export default {
  async fetch(request: Request, env: any): Promise<Response> {
    const body = await request.json() as any
    const label = EVENT_LABELS[body.event] ?? body.event
    const inv = body.data

    const message = {
      blocks: [
        {
          type: 'section',
          text: {
            type: 'mrkdwn',
            text: `*${label}*\n*Invoice:* ${inv.invoice_number}\n*Client:* ${inv.client_name}\n*Amount:* ${inv.total}`,
          },
        },
      ],
    }

    await fetch(env.SLACK_WEBHOOK_URL, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(message),
    })

    return new Response('ok')
  },
}

Set SLACK_WEBHOOK_URL as a secret in your worker environment.

Step 4: Test It

In Workify, go to Settings → Webhooks, find your webhook, and click Send test. A test message should appear in your Slack channel within a few seconds.

Customising the Message Format

Slack's Block Kit lets you create rich, interactive messages. Here's a more detailed format for payment notifications:

{
  "blocks": [
    {
      "type": "header",
      "text": { "type": "plain_text", "text": "💰 Payment received" }
    },
    {
      "type": "section",
      "fields": [
        { "type": "mrkdwn", "text": "*Client:*\n{{client_name}}" },
        { "type": "mrkdwn", "text": "*Amount:*\n{{total}}" },
        { "type": "mrkdwn", "text": "*Invoice:*\n{{invoice_number}}" },
        { "type": "mrkdwn", "text": "*Paid on:*\n{{paid_at}}" }
      ]
    }
  ]
}

Routing Events to Different Channels

You can create multiple Workify webhooks pointing to different Slack channels:

Workify EventSlack Channel
invoice.paid#payments
invoice.overdue#chasing
invoice.viewed#sales
invoice.created#invoicing

Each webhook in Workify can subscribe to specific events, so you only get relevant messages in each channel.

Tips

  • Use Slack's User Group mentions (<!subteam^ID>) in overdue notifications to ping the right account manager
  • Add a View invoice button to the Slack message linking directly to the Workify invoice URL
  • Mute the invoice.viewed channel overnight — knowing a client opened your invoice at 11pm can wait until morning

Ready to automate your invoicing?

Get your Workify API key and start building in minutes. Pro plan includes full API and webhook access.