Zodiac Tech CRM Docs

Commercial agreements

Create a client agreement with the 5-step wizard — pricing, entitlements, client approval and provider-verified activation.

super-admin Medium ⏱ 15 min Updated 2026-10-05

Commercial agreements

A commercial agreement is the contract behind a client's service: its price, its entitlements (the features the client may use), and its lifecycle. Everything else in billing — invoices, payments, restrictions — hangs off the agreement.

Create and manage them at /super-admin/billing/agreements.

Who this is for

Super Admins who set up client deals.

  • Difficulty: Medium
  • Time: 15 min
  • Prerequisites: A client business, a payment provider configured (Providers), and the agreed commercial terms.

Price and entitlements are separate — by design Line items decide what the client pays. Entitlements decide what the client can use. Adding a price line never grants a feature, and a discount never removes one. Only the checkboxes on the Services step control access. This is enforced in code, not just policy.

Step 1 — Start the wizard

Open Billing → Agreements → Create. The wizard has five steps; you can revisit any step before saving:

  1. 1. Agreement
  2. 2. Pricing
  3. 3. Services
  4. 4. Review
  5. 5. Send to Client

Step 2 — Step 1: Agreement basics

Field Notes
Business The client workspace this agreement is for
Name Internal name, e.g. "Acme — Growth plan 2026"
Description Optional summary
Billing type Default: Custom (monthly)
Currency Default: INR
Start / End dates Contract window
AutoPay enabled On by default — the client is asked to authorize AutoPay after approving
Payment provider Razorpay or Cashfree
Notes / Internal notes Client-visible notes vs staff-only notes

Step 3 — Step 2: Pricing

  • Discount at agreement level, and per line item.
  • Tax: enable, mark included or added, set the rate (default 18% GST).
  • Recurring interval and count — how often the recurring amount bills.
  • Line items (repeater): name, type, amount, quantity, service key, discount, description.

A live total is kept by the billing calculator as you build. The recurring total is the amount the provider will debit each cycle — the platform guarantees provider debit = renewal invoice = recurring gross amount.

One-time vs recurring Setup fees go on one-time line items. Renewal invoices only ever bill the recurring portion — a one-time fee is never charged twice.

Step 4 — Step 3: Services (entitlements)

Tick the features the client is entitled to and set any limits. This step is the only thing that grants access. If a client later says "I can't find feature X", check here first.

Step 5 — Step 4: Review

The review step shows the totals summary (via the billing calculator) and requires you to confirm one checkbox:

"I understand the agreement is saved as a draft and nothing is sent yet."

Every draft save snapshots a version — you can always see what changed and when. Only drafts are editable; once sent, changes go through a change request.

Step 6 — Step 5: Send to Client

Sending asks the client to review and approve the commercial terms. Nothing is charged yet.

After sending, the client sees Awaiting your approval in their portal. When they approve, the status moves to AutoPay setup pending, and they are taken to the provider to authorize AutoPay.

Activation only happens on provider confirmation The platform never treats "the client came back from the provider" as success. Activation happens only when a provider webhook confirms the authorization (BillingService::verifyAuthorization()). If the webhook does not arrive, the agreement stays pending — this is deliberate protection against faked payments.

Step 7 — Manage the agreement

Open an agreement to see its tabs: Overview, Line Items, Entitlements, Subscription, Invoices, Payments, Change Requests, Events, Timeline.

Available actions:

Action When What it does
Send to Client Draft only Sends for approval; freezes editing
Record Manual Payment Any live agreement Records an offline payment (bank transfer, UTR) and applies it to an open invoice
Create Change Request Active agreements Proposes new amount / interval / feature changes for the client to accept
Pause Live agreements Pauses AutoPay and renewals via the provider where supported — the state is never faked
Resume Paused agreements Re-enables billing
Refund When payments exist Records a refund against a payment
Cancel Agreement Live agreements Immediate or end-of-cycle; financial history is never deleted

Deletes are not possible Agreements are never deleted — cancellation keeps the financial history. Use the saved-view filters (pending approvals, payment failures, past due, active autopay, upcoming renewals) to work a queue.

Status lifecycle

Draft → Awaiting your approval → AutoPay setup pending → Active → Payment failed → Grace period → Past due → Restricted → Suspended (and Cancelled / Expired). Restriction details: Payment failures & restrictions.

Expected result

The client has the agreement in their portal, approves it, authorizes AutoPay, and the agreement flips to Active only after the provider confirms — from then on, renewals bill automatically.

Common mistakes

  • Promising a feature by adding a price line. Use entitlements.
  • Sending without checking entitles. Review the Services step before sending — post-send changes need a change request.
  • Expecting activation on redirect. Only webhook confirmation activates.
  • Editing a sent agreement. Only drafts are editable; everything else is versioned through change requests.
  • Choosing Cashfree without configuring it. Provider must be set up under Providers & Settings first.

Troubleshooting

Symptom What to check
Client approves but status stays pending autopay They have not completed provider authorization yet
Webhook not received Provider config + webhook URLs — Payment providers
Client rejects the terms Create a new agreement or send a change request; do not edit the sent one
Total looks wrong Tax included/add mode and discount at line level vs agreement level
Refund action missing There is no recorded payment to refund

Technical details

  • Resource: App\Filament\SuperAdmin\Resources\CommercialAgreementResource (slug billing/agreements); wizard steps in the resource form; labels in lang/en/filament/commercial_billing.php.
  • Model: App\Models\CommercialAgreement; statuses include DRAFT, PENDING_CLIENT_APPROVAL, PENDING_PAYMENT_AUTHORIZATION, ACTIVE, PAYMENT_FAILED, GRACE_PERIOD, PAST_DUE, RESTRICTED, SUSPENDED, CANCELLED, EXPIRED.
  • Services: BillingCalculator::summarize(), BillingService::verifyAuthorization(), BillingChangeService (create + send change requests).
  • Draft snapshots: every save creates an agreement version; deletes are prohibited.
  • Client side: /admin/billing/agreement — see Client billing portal.

Was this page helpful?