Commercial agreements
Create a client agreement with the 5-step wizard — pricing, entitlements, client approval and provider-verified activation.
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. Agreement
- 2. Pricing
- 3. Services
- 4. Review
- 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(slugbilling/agreements); wizard steps in the resource form; labels inlang/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.
Related guides
Was this page helpful?
Thanks — noted. ✦