ml-connector
VismaSlack

Visma and Slack integration

Visma.net ERP runs your financial management, accounts payable, procurement, and payroll. Slack keeps your team coordinated. Connecting them sends real-time notifications to the right channels when invoices arrive, orders ship, or expenses need approval. Finance teams stay aligned, approvers see what needs attention immediately, and the audit trail is automatic.

How Visma works

Visma.net ERP exposes suppliers, purchase orders, supplier invoices, journal transactions, customer invoices, accounts, dimensions, employees, and expense claims through REST APIs. It authenticates via OAuth 2.0 using the client_credentials grant with client_id, client_secret, and tenant_id, and requires an ipp-company-id header on every API call. Visma supports both webhooks for real-time events and polling via lastModifiedDateTime query parameters, though webhooks are delivered once with no automatic retry if the receiver is down. Test clients are rate-limited to 500 calls per hour per company.

How Slack works

Slack exposes teams, users, conversations, messages, and files through REST APIs. It authenticates via OAuth 2.0 Authorization Code flow, issuing non-expiring bot tokens (xoxb- prefix) passed via Authorization: Bearer header. Slack delivers workspace events in real time via the Events API, pushing HTTP POST callbacks to a registered HTTPS endpoint with HMAC-SHA256 signature verification required on every request. Endpoints must return HTTP 2xx within 3 seconds, and Slack retries failed deliveries up to 3 times with exponential backoff. The chat.postMessage method is rate-limited to 1 message per second per channel.

What moves between them

The main flow runs from Visma into Slack. Supplier invoices and purchase orders are polled from Visma on a schedule you control and posted as messages to designated Slack channels. Expense claims and journal transactions can also be synced based on approval status or financial threshold. Slack message reactions and thread replies can flow back to Visma as approval signals if configured. Employee and supplier reference data is kept in sync so notifications reference the correct people and vendors.

How ml-connector handles it

ml-connector stores Visma OAuth 2.0 credentials encrypted and refreshes the token on expiry before making API calls. It polls Visma supplier invoices, purchase orders, and expense claims using lastModifiedDateTime to fetch only changed records since the last run, avoiding redundant API calls. For each record matching your configured rules (invoice amount, approval status, vendor category), ml-connector formats a message and posts it to Slack using the chat.postMessage method with the stored bot token. On the Slack side, it validates every webhook callback signature using constant-time HMAC-SHA256 comparison with the Slack signing secret, rejects requests older than 5 minutes, and handles Slack's 1-per-second rate limit on posting by queueing messages. The tenant_id and ipp-company-id header required by Visma are included on every Visma call per customer. Because Visma webhooks do not retry on failure and Slack has strict timing windows, ml-connector polls Visma as the primary source and uses Slack Events API only for supplementary approval signals.

A real-world example

A mid-sized Nordic manufacturing company runs Visma.net ERP for procurement and finance, with a geographically distributed team on Slack. Before the integration, suppliers' invoices arrived in Visma but the AP team learned about them through email or manual checking, leading to missed early-payment discounts and approval bottlenecks. With Visma connected to Slack, each new supplier invoice is posted to the ap-approvals channel within minutes, showing the vendor, amount, and PO reference. Approvers click a thread reaction to signal approval, which ml-connector logs for the audit trail, and overdue invoices are automatically re-posted as reminders. The finance team no longer waits for email and catches discounts and mismatches immediately.

What you can do

  • Post Visma supplier invoices to Slack channels immediately, with vendor name, amount, and PO reference for instant visibility.
  • Notify teams of purchase order confirmations and receipts from Visma on a schedule you define.
  • Route approval workflows through Slack by mapping message reactions to approval signals logged in Visma.
  • Authenticate Visma with OAuth 2.0 tenant credentials and Slack with non-expiring bot tokens, handling token refresh and signature verification.
  • Poll Visma on a schedule while respecting Slack rate limits and the 1-per-second message posting ceiling per channel.

Questions

How does the integration handle Visma's webhook delivery limitations?
Visma webhooks deliver once with no automatic retry, and they require company-level enablement. ml-connector polls Visma supplier invoices, purchase orders, and expense claims on your defined schedule using lastModifiedDateTime to fetch only changed records. This avoids the one-time delivery problem and lets you control the sync cadence to match your business cycle.
What happens if the Slack bot token expires or the app is uninstalled?
Slack issues non-expiring bot tokens, so token refresh is not required, but the bot token becomes invalid if the Slack app is uninstalled from the workspace. ml-connector will return HTTP 401 on the next message post attempt. Validate the bot token and reinstall the app if needed, and update the stored credential.
How does ml-connector stay within Slack's rate limits?
Slack rate-limits chat.postMessage to 1 message per second per channel. ml-connector queues invoices and purchase orders when the posting rate exceeds the limit, spreading the posts over time. If the queue grows, the integration reduces the polling frequency or batches multiple records into a single message to stay within the ceiling.

Related integrations

Connect Visma and Slack

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started