---
title: "Record an offline refund (cash/check/bank transfer) of a refundable credit note"
canonical_url: "https://twominutebilling.com/help/developers/api-reference/invoices/record-an-offline-refund"
---
# Record an offline refund (cash/check/bank transfer) of a refundable credit note

<api-operation method="POST" path="/v1/businesses/{biz}/credit_notes/{cn}/record_refund">
<template v-slot:docs="">

## Path parameters

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        biz
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Business id (biz_…)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cn
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      The credit note's id (cn_…).
    </td>
  </tr>
</tbody>
</table>

## Headers

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        Idempotency-Key
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Safely retry writes — repeats return the original response. If a write FAILED after it had already taken effect, that failure is what repeats: the key is spent, and a new attempt needs a new key.
    </td>
  </tr>
</tbody>
</table>

## Body

The request body is **required**.

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        amount_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Amount in minor units; defaults to the full available amount
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        method
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      How the customer was refunded. One of <code>
        cash
      </code>
      
      , <code>
        check
      </code>
      
      , <code>
        bank_transfer
      </code>
      
      , <code>
        other
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        reference
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Optional external reference number
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        date
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      When the offline refund was made (defaults to now)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        reason
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      A note on why the refund was recorded.
    </td>
  </tr>
</tbody>
</table>

## Response

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The object type.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        id
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The credit note's id (cn_…).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Human-readable sequential number ("CN-42"); null on rows predating it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invoice
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The invoice this note credits (inv_…).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invoice_number
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      That invoice's human-readable number ("INV-42"); null on rows predating it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        kind
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      adjustment reduces an unpaid invoice; refundable credits the refundable bucket and can be refunded or allocated. One of <code>
        adjustment
      </code>
      
      , <code>
        refundable
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        status
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        refunded
      </code>
      
       means nothing is left available: by a refund, by allocation to invoices, or both. <code>
        settled_by
      </code>
      
       says which. One of <code>
        adjusted
      </code>
      
      , <code>
        refund_due
      </code>
      
      , <code>
        refunded
      </code>
      
      , <code>
        voided
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        settled_by
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Set on a <code>
        refunded
      </code>
      
       note: <code>
        refund
      </code>
      
       (cash went back), <code>
        allocation
      </code>
      
       (applied to invoices; <code>
        refunded_minor
      </code>
      
       is 0) or <code>
        mixed
      </code>
      
      . Null on every other status. One of <code>
        refund
      </code>
      
      , <code>
        allocation
      </code>
      
      , <code>
        mixed
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        reason_code
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The credit note's reason code. One of <code>
        write_off
      </code>
      
      , <code>
        subscription_change
      </code>
      
      , <code>
        subscription_cancellation
      </code>
      
      , <code>
        chargeback
      </code>
      
      , <code>
        other
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        subtotal_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The GROSS reversal this note documents, PRE-TAX and before any slice was routed back to a credit bucket. Reproduce the note as subtotal_minor − Σ discounts<span>
        
      </span>
      
      .amount_minor + tax = total_minor. Notes issued before this was recorded report their total_minor here, with no discounts and no tax.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        total_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The CASHABLE claim — what is refundable or allocatable, NOT the gross. 0 is legitimate: a reversal funded entirely from promotional credit returns all of it to that bucket.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        allocated_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      Already applied to invoices.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        refunded_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      Already drawn as a refund.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        available_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      total_minor − allocated_minor − refunded_minor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        payout_unconfirmed_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      A payout refund the gateway could not confirm (not found). Counted as paid out until a person resolves it with <code>
        POST …/credit_notes/{cn}/resolve_payout
      </code>
      
      , or the gateway answers later (a success settles it as paid, a failure returns it as credit). 0 = nothing to resolve.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        payout_duplicated_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      A refund that a person returned as credit and that the gateway later confirmed paid out: the customer has this amount as cash and as credit. We do not take the credit back on our own. A later bounce of that payout lowers it. 0 = none.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        payout_out_of_order_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      A refund the gateway reported failed (we returned it as credit) and then reported paid: its answers arrived out of order. Booked as paid; the credit stays. Check the gateway. 0 = none.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        currency
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The credit note's currency (ISO-4217 code).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        exchange_rate
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      INHERITED from the invoice this note credits, not resolved fresh — so the note and its invoice convert at the same rate and net to zero in a converted book. Same string/direction rules as <code>
        Invoice.exchange_rate
      </code>
      
      ; null when the credited invoice carried no rate.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        exchange_rate_base
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The exchange rate to the business's default currency at issue.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        reason
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Why the credit note was issued.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        customer_notes
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      A note shown to the customer on the credit note.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        voided_at
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      When the credit note was voided (ISO-8601 UTC), or null.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        channel
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Provenance at creation; null on rows predating the column. One of <code>
        api
      </code>
      
      , <code>
        dashboard
      </code>
      
      , <code>
        system
      </code>
      
      , <code>
        import
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        imported
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      Archival row imported from an external system (no ledger postings).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        metadata
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      Key-value pairs you attach to the credit note.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        created_at
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      When the credit note was created (ISO-8601 UTC).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        customer
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The payer (cus_…). Absent on the create receipt.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        customer_name
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The customer's name.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        customer_email
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The customer's email.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        items
      </code>
    </td>
    
    <td>
      <code>
        array of object
      </code>
    </td>
    
    <td>
      The CASHABLE lines, so they sum to total_minor rather than to subtotal_minor — the gap is exactly <code>
        discounts[]
      </code>
      
      . Absent on the create receipt.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        discounts
      </code>
    </td>
    
    <td>
      <code>
        array of object
      </code>
    </td>
    
    <td>
      What was taken off subtotal_minor and which bucket it went back to. Amounts are positive magnitudes. Present on the single credit-note read only.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        taxes
      </code>
    </td>
    
    <td>
      <code>
        array of object
      </code>
    </td>
    
    <td>
      The <code>
        + tax
      </code>
      
       term of that identity, split across the components the CREDITED INVOICE booked and named the way the invoice names them ("IGST (18.00%)"). A credit note stores neither the amount nor the names: the amount is the identity rearranged, the names come from the invoice's tax snapshot, in the proportion it booked them. Σ amount_minor === total_minor − subtotal_minor + Σ discounts<span>
        
      </span>
      
      .amount_minor. Falls back to a single unnamed "Tax" row when the credited invoice recorded no per-line tax (rows predating it, or an untaxed business). Empty when the note carries no tax. Present on the single credit-note read only.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        gateway_refundable_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      Cash on this note's invoice still reversible through a gateway. 0 means a gateway refund is impossible. Present on the single credit-note read only.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        allocations
      </code>
    </td>
    
    <td>
      <code>
        array of object
      </code>
    </td>
    
    <td>
      Where this note's credit was applied. Present on the single credit-note read only.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        refunds
      </code>
    </td>
    
    <td>
      <code>
        array of object
      </code>
    </td>
    
    <td>
      Refund transactions drawn against this note. Present on the single credit-note read only.
    </td>
  </tr>
</tbody>
</table>

## Status codes

<table>
<thead>
  <tr>
    <th>
      Status
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        200
      </code>
    </td>
    
    <td>
      Success
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      Nothing to refund / exceeds available
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      No such credit note
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        409
      </code>
    </td>
    
    <td>
      Idempotency-Key conflict — the key is already in flight, or was reused with a different request payload.
    </td>
  </tr>
</tbody>
</table>
</template>

<template v-slot:request="">

```bash [Request]
curl -X POST "$TMBILLING_URL/v1/businesses/biz_XXXXXXXXXXXX01/credit_notes/cn_XXXXXXXXXXXX01/record_refund" \
  -H "Authorization: Bearer $TMBILLING_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_minor": 2900,
    "method": "cash"
  }'
```

</template>

<template v-slot:response="">
<code-group>

```json [200 OK]
{
  "object": "credit_note",
  "id": "cn_XXXXXXXXXXXX01",
  "number": "INV-1001",
  "invoice": "inv_XXXXXXXXXXXX01",
  "invoice_number": "INV-1001",
  "kind": "adjustment",
  "status": "adjusted",
  "settled_by": "refund",
  "reason_code": null,
  "subtotal_minor": 2900,
  "total_minor": 2900,
  "allocated_minor": 2900,
  "refunded_minor": 0,
  "available_minor": 2900,
  "payout_unconfirmed_minor": 2900,
  "payout_duplicated_minor": 2900,
  "payout_out_of_order_minor": 2900,
  "currency": "USD",
  "exchange_rate": "0.920000",
  "exchange_rate_base": "USD",
  "reason": "Requested by the customer.",
  "customer_notes": "Thank you for your business.",
  "voided_at": null,
  "channel": "api",
  "imported": false,
  "metadata": {
    "crm_id": "acct-1001"
  },
  "created_at": "2026-03-14T09:30:00Z",
  "customer": "cus_XXXXXXXXXXXX01",
  "customer_name": "Maya Castillo",
  "customer_email": "maya@example.com",
  "items": [
    {
      "id": "cni_XXXXXXXXXXXX01",
      "description": "Everything a growing team needs.",
      "amount_minor": 2900,
      "period_start": "2026-03-14T09:30:00Z",
      "period_end": "2026-04-14T09:30:00Z"
    }
  ],
  "discounts": [
    {
      "object": "discount",
      "type": "promotional_credits",
      "amount_minor": 2900,
      "description": "Promotional"
    }
  ],
  "taxes": [
    {
      "object": "taxe",
      "description": "IGST",
      "amount_minor": 2900
    }
  ],
  "gateway_refundable_minor": 2900,
  "allocations": [
    {
      "object": "allocation",
      "invoice": "inv_XXXXXXXXXXXX01",
      "amount_minor": 2900,
      "allocated_at": "2026-03-14T09:30:00Z"
    }
  ],
  "refunds": [
    {
      "object": "refund",
      "transaction": "txn_XXXXXXXXXXXX01",
      "status": "active",
      "amount_minor": 2900,
      "currency": "USD",
      "offline": false
    }
  ]
}
```

```json [400 Bad Request]
{
  "error": {
    "type": "invalid_request_error",
    "message": "Nothing to refund / exceeds available"
  }
}
```

```json [404 Not Found]
{
  "error": {
    "type": "invalid_request_error",
    "message": "No such credit note"
  }
}
```

```json [409 Conflict]
{
  "error": {
    "type": "idempotency_error",
    "message": "Idempotency-Key conflict — the key is already in flight, or was reused with a different request payload."
  }
}
```

</code-group>
</template>
</api-operation>


## Sitemap

See the full [sitemap](https://twominutebilling.com/sitemap.md) for all pages.
