> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meterengine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 금액 계산 따라가기

> 구간 단가, 최소 사용료, 기본료가 있는 예시 하나로 청구 금액을 직접 계산하고 응답 값과 맞춰 봅니다.

이 페이지는 숫자 예시 하나를 끝까지 계산합니다. 각 규칙의 정의는 아래 페이지에 있습니다.

* 구간 단가의 규칙: [단가 모델과 버전](https://docs.meterengine.com/pricing/price-models.md)
* 기본료와 최소 사용료의 규칙: [기본료와 최소 사용료](https://docs.meterengine.com/pricing/price-plans.md)
* 10원 미만 버림과 세액: [예정액, 확정액, 수납액](https://docs.meterengine.com/concepts/amounts.md)

## 예시 조건

| 항목 | 값 |
| - | - |
| 미터 | `aggregation`은 `sum`, `unit_size`는 1, `rounding_mode`는 `none`(기본값), 차원 없음 |
| 단가 | 누진 구간(`graduated`): 100까지 10원, 1,000까지 8원, 그 위는 5원 |
| 요금제 | 월 기본료 500원, 월 최소 사용료 12,000원 |
| 그 달 사용량 | 한 고객이 이벤트 한 건으로 1500.5를 보냄 |

## 단계별 계산

**1. 수량을 구간에 나눈다**

누진 구간은 수량을 구간마다 잘라 각 구간의 단가를 곱합니다. 1500.5는 0 초과 100 이하에 100, 100 초과 1,000 이하에 900, 1,000 초과에 500.5로 나뉩니다.

**2. 구간마다 라인을 만들고 10원 미만을 버린다**

구간 하나가 라인 하나입니다. 버림은 라인마다 합니다.

| 라인 | 수량 | 단가 | 곱 | 라인 금액 |
| - | - | - | - | - |
| 구간 1 | 100 | 10원 | 1,000원 | 1,000원 |
| 구간 2 | 900 | 8원 | 7,200원 | 7,200원 |
| 구간 3 | 500.5 | 5원 | 2,502.5원 | 2,500원 |

사용료 합은 10,700원입니다.

**3. 최소 사용료를 채운다**

사용료 10,700원이 최소 사용료 12,000원보다 작으므로 차액 1,300원으로 '최소 사용료 조정' 라인을 더합니다.

**4. 기본료를 더한다**

'기본료' 라인 500원을 더합니다. 기본료는 최소 사용료를 채우는 데 쓰이지 않습니다.

**5. 공급가액이 나온다**

1,000 + 7,200 + 2,500 + 1,300 + 500 = **12,500원**입니다. 라인은 다섯 줄입니다. 청구 예정액은 이 공급가액이고 세금을 포함하지 않습니다.

**6. 확정하면 세액과 합계가 붙는다**

인보이스를 확정하면 세액은 공급가액의 10%인 1,250원, 합계는 13,750원입니다.

## 누진 구간과 총량 구간 비교

같은 구간표를 총량 구간(`volume`)으로 등록하면 계산이 달라집니다. 총량 구간은 전체 수량이 드는 구간 하나의 단가를 전체 수량에 곱하고 라인을 하나만 만듭니다.

> [tab] 누진 구간 (graduated)
>
> | 라인 | 금액 |
> | - | - |
> | 구간 1, 2, 3 | 1,000원 + 7,200원 + 2,500원 = 10,700원 |
> | 최소 사용료 조정 | 1,300원 |
> | 기본료 | 500원 |
> | 공급가액 | 12,500원 |

> [tab] 총량 구간 (volume)
>
> | 라인 | 금액 |
> | - | - |
> | 총량 단가 | 1500.5 x 5원 = 7,502.5원 -> 7,500원 |
> | 최소 사용료 조정 | 12,000원 - 7,500원 = 4,500원 |
> | 기본료 | 500원 |
> | 공급가액 | 12,500원 |

두 모델의 공급가액이 같은 것은 최소 사용료가 차이를 메웠기 때문입니다. 요금제를 빼고 사용료만 보면 수량에 따라 아래처럼 다릅니다.

| 그 달 수량 | 누진 구간 사용료 | 총량 구간 사용료 |
| - | - | - |
| 0 | 0원 | 0원 |
| 100 | 1,000원 | 1,000원 |
| 101 | 1,000원 | 800원 |
| 1,000 | 8,200원 | 8,000원 |
| 1500.5 | 10,700원 | 7,500원 |

* 누진 구간에서 101은 100 x 10원 + 1 x 8원 = 1,008원이고 버림으로 1,000원입니다. 구간 경계 값은 아래 구간에 듭니다.
* 총량 구간에서 101은 전체가 둘째 구간이라 101 x 8원 = 808원, 버림으로 800원입니다. 경계를 넘는 순간 사용료가 줄어듭니다.

## 응답에서 맞춰 보기

청구 예정액은 `GET /v1/invoices/draft`로 봅니다. `month`를 생략하면 이번 달입니다. 콘솔에서는 '청구 검토' 화면에서 같은 값을 봅니다.

```bash curl theme={null}
curl "https://meterengine.com/v1/invoices/draft?month=2026-11" \
  -H "Authorization: Bearer me_test_xxxxxxxx"
```

```javascript Node theme={null}
const response = await fetch(
  "https://meterengine.com/v1/invoices/draft?month=2026-11",
  { headers: { Authorization: "Bearer me_test_xxxxxxxx" } },
);
const draft = await response.json();
```

예시 고객 한 명만 있을 때 누진 구간의 응답은 아래와 같습니다. 미터 code는 `example-hours`, 집계 대상 속성은 `hours`로 만든 경우입니다.

```json 200 응답 theme={null}
{
  "month": "2026-11",
  "calculated_at": "2026-11-05T10:05:00+09:00",
  "auto_finalize_enabled": false,
  "auto_finalize_at": null,
  "auto_finalize_running": false,
  "total_amount": 12500,
  "customers": [
    {
      "customer_id": "8b0f4c2e-6d1a-4f3b-9a57-2c4e8d9b1f60",
      "customer_name": "계산 예시 고객",
      "amount": 12500,
      "lines": [
        {
          "billable_metric_code": "example-hours",
          "target_property": "hours",
          "dimension_values": {},
          "quantity": 100,
          "unit_price": 10,
          "amount": 1000,
          "line_type": "graduated_tier",
          "tier_index": 0,
          "quantity_numerator": 100,
          "quantity_denominator": 1
        },
        {
          "billable_metric_code": "example-hours",
          "target_property": "hours",
          "dimension_values": {},
          "quantity": 900,
          "unit_price": 8,
          "amount": 7200,
          "line_type": "graduated_tier",
          "tier_index": 1,
          "quantity_numerator": 900,
          "quantity_denominator": 1
        },
        {
          "billable_metric_code": "example-hours",
          "target_property": "hours",
          "dimension_values": {},
          "quantity": 500.5,
          "unit_price": 5,
          "amount": 2500,
          "line_type": "graduated_tier",
          "tier_index": 2,
          "quantity_numerator": 500.5,
          "quantity_denominator": 1
        },
        {
          "billable_metric_code": null,
          "target_property": null,
          "dimension_values": {},
          "quantity": 1,
          "unit_price": 1300,
          "amount": 1300,
          "line_type": "minimum_adjustment",
          "tier_index": 0,
          "quantity_numerator": 1,
          "quantity_denominator": 1
        },
        {
          "billable_metric_code": null,
          "target_property": null,
          "dimension_values": {},
          "quantity": 1,
          "unit_price": 500,
          "amount": 500,
          "line_type": "base_fee",
          "tier_index": 0,
          "quantity_numerator": 1,
          "quantity_denominator": 1
        }
      ],
      "unpriced_usages": [],
      "negative_usages": [],
      "auto_finalize_held": false
    }
  ]
}
```

`auto_finalize_enabled`, `auto_finalize_at`, `auto_finalize_running`, `auto_finalize_held`는 자동 확정이 꺼져 있을 때의 값입니다. 자동 확정 필드의 뜻은 [자동 확정과 보류](https://docs.meterengine.com/billing/auto-finalization.md)를 보세요.

도입사 쪽 계산과 맞출 때 보는 필드입니다.

**customers\[].amount** `integer`

고객의 청구 예정액(공급가액, 원)입니다. `lines[].amount`의 합과 같습니다.

**lines\[].line\_type** `string`

`per_unit`, `graduated_tier`, `volume`은 사용료 라인, `minimum_adjustment`는 최소 사용료 조정, `base_fee`는 기본료입니다. 조정과 기본료 라인은 `billable_metric_code`가 `null`이고 사용료 라인 뒤에 옵니다.

**lines\[].tier\_index** `integer`

누진 구간의 몇 번째 구간인지 0부터 셉니다. 콘솔에는 '구간 1'처럼 1부터 보입니다. 총량 구간 라인은 어느 구간이 골라졌든 0입니다.

**lines\[].quantity\_numerator** `number`

금액과 구간 판정에 쓴 정확한 수량의 분자입니다. `quantity`는 표시용이므로 금액을 다시 계산할 때는 `quantity_numerator / quantity_denominator x unit_price`를 계산한 뒤 10원 미만을 버립니다.

**unpriced\_usages** `array`

단가가 없어 라인과 금액에서 빠진 조합의 사용량입니다. 도입사가 이 조합에도 요금을 매겨 계산했다면 이 차이만큼 금액이 어긋납니다.

확정한 인보이스는 `GET /v1/invoices/{id}`로 봅니다. 위 예시를 확정하면 `supply_amount`는 12500, `tax_amount`는 1250, `total_amount`는 13750이고 `lines`는 다섯 줄입니다. 확정 방법은 [인보이스 수동 확정](https://docs.meterengine.com/billing/finalize-invoices.md)을 보세요.

## 테스트 환경에서 직접 재현하기

위 예시를 테스트 환경에서 그대로 만들어 볼 수 있습니다. 아래 요청은 모두 admin 권한의 테스트 환경 키를 씁니다. 날짜는 오늘이 속한 달로 바꿔 넣으세요.

> [!WARNING]
>
> 테스트 환경도 보낸 이벤트는 지울 수 없고, 만든 미터와 고객도 지우지 못하고 보관만 됩니다. 이 예시 전용의 미터 code, 이벤트 `type`, 고객을 따로 써서 다른 시험 데이터와 섞이지 않게 하세요. 테스트 환경의 성질은 [업무 환경](https://docs.meterengine.com/concepts/environments.md)을 보세요.

**1. 미터를 만든다**

다른 미터와 겹치지 않는 이벤트 `type`을 씁니다. 같은 `type`을 세는 미터가 이미 있으면 그 미터에도 이 이벤트가 집계됩니다.

```bash curl theme={null}
curl -X POST https://meterengine.com/v1/billable-metrics \
  -H "Authorization: Bearer me_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "example-hours",
    "name": "계산 예시 사용 시간",
    "event_type": "example_job",
    "aggregation": "sum",
    "target_property": "hours",
    "dimension_properties": []
  }'
```

**2. 누진 구간 단가를 등록한다**

차원이 없는 미터는 `dimension_values`에 빈 객체를 넣습니다. 마지막 구간의 `up_to`는 `null`입니다. `effective_from`을 생략하면 이번 달부터 적용됩니다.

```bash curl theme={null}
curl -X POST https://meterengine.com/v1/billable-metrics/example-hours/price-rates \
  -H "Authorization: Bearer me_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "dimension_values": {},
    "model": "graduated",
    "tiers": [
      { "up_to": 100, "unit_price": 10 },
      { "up_to": 1000, "unit_price": 8 },
      { "up_to": null, "unit_price": 5 }
    ]
  }'
```

**3. 고객을 등록한다**

응답의 `id`가 이후 요청의 고객 id입니다.

```bash curl theme={null}
curl -X POST https://meterengine.com/v1/customers \
  -H "Authorization: Bearer me_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "calc-example-001",
    "name": "계산 예시 고객"
  }'
```

**4. 이 고객에게만 요금제를 건다**

`customer_id`를 넣어 고객 요금제로 등록합니다. `customer_id`를 빼면 공통 요금제가 되고, 이번 달 공통 요금제가 이미 있으면 그 값을 덮어써 다른 고객의 청구 예정액까지 바뀝니다.

```bash curl theme={null}
curl -X POST https://meterengine.com/v1/price-plans \
  -H "Authorization: Bearer me_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "8b0f4c2e-6d1a-4f3b-9a57-2c4e8d9b1f60",
    "base_fee": 500,
    "minimum_amount": 12000
  }'
```

**5. 이벤트를 한 건 보낸다**

`timestamp`는 이번 달 안의 시각이어야 합니다. 보낸 이벤트는 되돌릴 수 없으니 값을 확인한 뒤 보냅니다.

```bash curl theme={null}
curl -X POST https://meterengine.com/v1/events \
  -H "Authorization: Bearer me_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "calc-example-0001",
    "customer_id": "8b0f4c2e-6d1a-4f3b-9a57-2c4e8d9b1f60",
    "type": "example_job",
    "timestamp": "2026-11-05T10:00:00+09:00",
    "properties": { "hours": 1500.5 }
  }'
```

응답은 `{"transaction_id":"calc-example-0001","duplicate":false}`입니다. 이벤트 형식은 [사용량 이벤트 보내기](https://docs.meterengine.com/integration/events.md)를 보세요.

**6. 청구 예정액을 조회한다**

`GET /v1/invoices/draft`의 이 고객 항목이 위 응답 예시와 같은지 봅니다. 청구 예정액은 조회할 때마다 다시 계산하므로 이벤트를 보낸 직후에도 바로 반영됩니다.

## 어긋날 때 확인할 것

> [accordion] 기본료를 최소 사용료에 넣어 계산했다
>
> 최소 사용료는 사용료 합하고만 비교합니다. 기본료 500원을 사용료에 넣어 11,200원으로 보면 조정이 800원이 되어 500원이 어긋납니다.

> [accordion] 합계에서 한 번만 10원 미만을 버렸다
>
> 버림은 라인마다 합니다. 소수 수량이 여러 라인에 나뉘면 합계에서 한 번 버린 값보다 작아질 수 있습니다.

> [accordion] 단가 없는 조합만 있는 고객에게 최소 사용료가 붙었다
>
> 단가가 없는 조합의 사용량도 요금제를 붙이는 기준이 되는 사용량으로 셉니다. 사용료는 0원이라 최소 사용료 전액이 조정 라인으로 붙습니다. `unpriced_usages`를 보고 단가를 등록하세요. 자세한 내용은 [기본료와 최소 사용료](https://docs.meterengine.com/pricing/price-plans.md)를 보세요.

> [accordion] 이벤트를 보냈는데 금액이 0원이다
>
> 미터의 이벤트 `type`, 단가의 조합, 이벤트의 `timestamp`가 맞는지 봅니다. 원인별 확인 순서는 [이벤트가 청구에 안 보일 때](https://docs.meterengine.com/troubleshooting/events-not-billed.md)를 보세요.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.