Skip to main content
All Docs
FeaturesPurple PepperUpdated April 7, 2026

Calmony Pay Payment Integration

Calmony Pay Payment Integration

The platform supports end-to-end payment processing via Calmony Pay, enabling agents to collect holding deposits, move-in balance payments, renewal fees, and custom one-off payments from tenants.

Overview

Payments flow through a central payments_ledger table that tracks every transaction from creation through to completion (or failure/cancellation). Tenant checkout is handled by a Calmony Pay hosted page. On successful payment, a webhook triggers an Inngest function that automatically updates the ledger, completes linked todos, and marks custom payment tasks as paid.

Payment Types

TypeDescription
holding_depositDeposit collected during offer acceptance
move_in_balanceBalance payment due before move-in
renewal_feeFee charged on tenancy renewal
customBespoke one-off payment created by an agent

Payment Methods

  • Card — standard card payment via Calmony Pay checkout
  • Pay by Bank (open banking) — bank-to-bank transfer initiated through Calmony Pay

Card Payment Limit

Each agency has a configurable maximum card payment ceiling (maxCardPaymentPence). Payments above this threshold are automatically forced to use Pay by Bank.

  • Default: £2,000 (200,000 pence)
  • No limit: set to null to allow all amounts via card
  • Managed via payment.getCardLimit and payment.updateCardLimit (admin-only)

Payment Lifecycle

pending → processing → succeeded
                    ↘ failed
                    ↘ refunded
                    ↘ cancelled

How Payments Work

1. Create a Payment Task

Call payment.createPaymentTask with the payment details. The system:

  • Creates a payments_ledger entry with status pending
  • Enforces the agency card limit — overrides method to open_banking if the amount exceeds the ceiling
  • Creates a Calmony Pay checkout session
  • Returns a checkout URL to redirect the tenant

2. Tenant Completes Checkout

The tenant is redirected to the Calmony Pay hosted checkout page to complete payment by card or Pay by Bank.

3. Webhook Processing

On successful payment, Calmony Pay sends a payment_intent.succeeded webhook to /api/webhooks/calmony-pay. This dispatches a calmony-pay/payment_intent.succeeded event to Inngest, which runs the paymentCompletedSync function:

  1. Deduplicates replayed webhooks using processedEvents
  2. Finds the payments_ledger entry by payment intent ID or ledger_id metadata
  3. Updates ledger status to succeeded and sets paidAt
  4. If linked to a custom payment task — marks it as paid
  5. If linked to a todo — marks it as complete
  6. Logs an audit entry for each state change

4. Manual Payment Fallback

Agents can manually confirm payments (e.g. for bank transfers received outside the platform) using payment.markPaymentManuallyPaid. This accepts an optional payment reference and updates the ledger, linked todo, and custom payment task in the same way as the webhook path.

API Reference

payment.createPaymentTask

Creates a ledger entry and Calmony Pay checkout session.

Returns: { checkoutUrl: string, ledgerEntryId: string }

Key inputs:

  • amountPence — amount in GBP pence
  • paymentTypeholding_deposit | move_in_balance | renewal_fee | custom
  • tenancyId — linked tenancy (optional)
  • todoId — linked todo to auto-complete on success (optional)
  • customPaymentTaskId — linked custom payment task (optional)
  • description — human-readable description shown on checkout

payment.getPaymentStatus

Returns full ledger entry details for a given payment ID.

payment.markPaymentManuallyPaid

Manually confirms a payment. Updates the ledger (manuallyPaid: true), linked todo, and linked custom payment task.

Key inputs:

  • paymentId — ledger entry ID
  • manualPaymentReference — reference string (e.g. bank transfer reference)

payment.list

Paginated list of payments. Supports filtering by:

  • tenancyId
  • status
  • paymentType

payment.stats

Returns aggregate counts and totals:

  • Number and total amount of pending payments
  • Number and total amount of succeeded payments

payment.getCardLimit / payment.updateCardLimit

Read or update the agency card payment ceiling. Admin-only.

payment.cancelPayment

Cancels a pending payment and updates ledger status to cancelled.

Audit Logging

All state-changing operations are audit logged with resourceType: "payment":

ActionTrigger
payment.createdcreatePaymentTask
payment.succeededpaymentCompletedSync webhook
payment.manually_paidmarkPaymentManuallyPaid
payment.cancelledcancelPayment

Environment Variables

No additional environment variables are required. The integration uses:

VariablePurpose
CALMONY_PAY_SECRET_KEYAuthenticates API requests to Calmony Pay
CALMONY_PAY_WEBHOOK_SECRETValidates incoming webhook signatures

Both variables must already be configured in your environment.