Refunds & Cancellations

A cancellation costs the property a sale and the guest some money. Both deserve a fast, predictable, well-communicated process — no "we'll call you in 3 days". The refund engine evaluates the property's policy, computes a number, and runs it through Razorpay (or records cash) automatically.

What triggers a refund

Guest cancellation

From their account page, or by writing to support, or asking at the desk.

Property cancellation

Owner cancels (over-booking, force majeure, room damage). Full refund + apology email mandated.

No-show

Guest never arrived. Per policy: usually one-night charge held, the rest refunded.

Balance default

Partial-payment booking, balance never paid. Advance refund computed per policy.

System over-booking

OTA race made us oversold. Full refund + guest re-accommodated (separate flow).

Chargeback

Razorpay alerts a dispute. Booking auto-locked; finance gathers evidence.

Policy → refund amount, step by step

  1. Identify the policy

    The booking carries a snapshot of the property's cancellation policy at the time of booking — policies change, but each booking is locked to the policy that applied when it was made.

  2. Compute hours until check-in

    Use the property's local time zone.

  3. Look up refund tier

    For Flexible: ≥24 h → 100 %, <24 h → 50 %, after check-in → 0 %.

  4. Apply override

    Owner or manager can override (up or down) with a written reason. Audit-logged.

  5. Compute taxes

    Refund proportionally cancels GST & city tax. Razorpay receipt is reissued.

  6. Execute refund

    Per original payment method.

Refund per payment method

Original methodRefund pathSettlement time
Razorpay (card / UPI / netbanking / wallet)Razorpay refund API → original method3–7 working days
UPI (manual ref)Property sends UPI from registered hotel ID. Agent records the new transaction ID.Same day
CashCash refunded at desk. Numbered debit receipt issued.Immediate
Bank transfer / NEFTProperty initiates NEFT. Records UTR.1–2 working days
OTA-collectedCancellation pushed to OTA; OTA refunds the guest per their policy. ABc records, doesn't process.OTA-dependent

Cancellation UI — guest view

abc.com/account/bookings/ABC-24817/cancel
Cancel this booking?
Park View Hotel · 27 Dec → 30 Dec · ₹22,230 paid
Cancellation policyFlexible
Time until check-in3 days, 4 hours
You will receive₹22,230 (100 %)
Refund to original payment method · 3–7 working days

Refund computation — worked examples

PolicyTime before check-inPaidRefund
Flexible5 days₹22,230₹22,230 (100 %)
Flexible8 hours₹22,230₹11,115 (50 %)
Moderate3 days₹22,230₹11,115 (50 %)
Strict3 days₹22,230₹0 (0 %)
Non-refundable10 days₹22,230₹0
Property-cancelsany₹22,230₹22,230 (100 %) + apology credit ₹500

Refund API — server side

POST /api/payments/:id/refund
// Request
{
  "amount": 22230,        // optional — defaults to remaining refundable
  "reason": "guest_cancellation",
  "notes": "Travel plans changed; flexible policy, 5 days out, 100 %",
  "idempotency_key": "refund_bk_…_1"
}

// Server flow:
// 1. Check booking state + policy
// 2. Compute max refundable (avoid double refunds)
// 3. If original was Razorpay → razorpay.payments.refund(paymentId, {...})
//    If original was cash    → create debit payment row, mark for desk handout
// 4. Update booking → cancelled
// 5. Push availability release to OTAs
// 6. Email guest + email owner

// Response — 201
{
  "refund_id": "rfd_…",
  "amount": 22230,
  "method": "razorpay",
  "razorpay_refund_id": "rfnd_M…",
  "status": "processing",
  "eta": "3-7 working days"
}

Owner / manager override

Sometimes the system says "50 %" but the property wants to make a goodwill gesture (or vice versa, a strict policy needs to hold).

Override is audited.

The override modal forces a reason and a manager-or-higher role. Both the system-computed amount and the override amount are stored — finance can see exactly how often overrides happen and by whom.

Refund status tracking

StatusMeaning
initiatedAPI called, awaiting gateway confirmation
processingRazorpay accepted, settling to bank/card
completedGuest received the money (webhook confirmed)
failedRazorpay returned an error; manual intervention required
manual_pendingCash / NEFT refund waiting for desk to hand out / send

Edge cases

  • Refund after partial check-in — guest stayed 1 of 3 booked nights and leaves. Refund = total − (1 night × ADR) − pro-rata tax.
  • Refund across split payments — paid ₹10k cash + ₹12k card. Refund 22k: card portion via Razorpay, cash portion via desk debit.
  • Refund after gateway timeout — initial refund call to Razorpay times out. We retry with the same idempotency key — no double refund.
  • Chargeback while refund in flight — lock the booking; let finance reconcile. Cancel any pending refund to avoid double-out.

Reporting

Owners can see, per month:

  • Cancellation rate (% of confirmed bookings cancelled)
  • Average refund (₹) per cancelled booking
  • Top cancellation reasons
  • Net revenue after refunds vs gross bookings