Receivables

    Customer refunds

    Money back to a resident: deposit returns, overpayments, and leftover credits.

    Record a refund

    Scope: payments:write. HelloLedger credits the account the money left from and debits the source: the deposit liability for a deposit return, or A/R for an overpayment or leftover credit.

    Deposit return · PUT
    curl -X PUT "https://api.helloledger.ai/v1/companies/{company_id}/customer-refunds/by-external-id/rf_deposit_1001" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "customer_external_id": "stu_1001",
      "date": "2027-06-01",
      "amount": "350.00",
      "paid_from_account_id": "66f1a2b3c4d5e6f708091e5f",
      "source": "deposit",
      "deposit_account_id": "66f1a2b3c4d5e6f708091d4e",
      "method": "ach",
      "reference": "ach_8812"
    }'
    Overpayment · PUT
    curl -X PUT "https://api.helloledger.ai/v1/companies/{company_id}/customer-refunds/by-external-id/rf_overpay_1001" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "customer_external_id": "stu_1001",
      "date": "2026-10-12",
      "amount": "50.00",
      "paid_from_account_id": "66f1a2b3c4d5e6f708091c3d",
      "source": "payment",
      "payment_external_id": "pay_pi_3Q8x",
      "method": "card",
      "reference": "re_3Q9a"
    }'
    Response
    {
      "refund_id": "66f7…",
      "external_id": "rf_deposit_1001",
      "customer_id": "66f2…",
      "customer_external_id": "stu_1001",
      "date": "2027-06-01",
      "amount": "350.00",
      "source": "deposit",
      "paid_from_account_id": "66f1a2b3c4d5e6f708091e5f",
      "deposit_account_id": "66f1a2b3c4d5e6f708091d4e",
      "payment_external_id": null,
      "credit_external_id": null,
      "method": "ach",
      "reference": "ach_8812",
      "memo": null,
      "status": "posted",
      "result": "created"
    }

    Sources

    paid_from_account_id is the bank account, or the processor clearing account when the processor takes the refund out of a payout. A refund can't be more than the payment's or credit's unapplied_amount (422 refund_exceeds_unapplied).

    sourceAlso sendUse it for
    depositdeposit_account_id (a liability)Returning all or part of a security deposit.
    paymentpayment_external_idSending back the unapplied part of a payment, e.g. a double payment.
    creditcredit_external_idPaying out the unapplied part of a credit.

    Rules

    • Refunds can't be edited. Void one and send the corrected refund under a new external ID.
    • Voiding a refund reverses its ledger entry and puts the amount back on the payment or credit.
    POST
    curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/customer-refunds/by-external-id/rf_overpay_1001/void" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "reason": "Refund failed"
    }'
    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/customer-refunds/by-external-id/rf_deposit_1001" \
      -H "Authorization: Bearer $HL_API_KEY"