> ## 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.

# 고객에게 인보이스 보여 주기

> 고객이 로그인 없이 확정 인보이스와 결제 상태를 보는 조회 링크를 발급하고 전달하고 폐기하는 방법을 설명합니다.

필요 권한: 발급과 폐기는 admin(전체 관리), 발급 이력 조회는 read(조회)

고객 조회 링크는 확정 인보이스 하나를 로그인 없이 보여 주는 링크입니다. 링크를 연 고객은 MeterEngine이 제공하는 화면에서 청구 항목과 금액, 결제 상태를 봅니다. 링크 주소는 아래 형식입니다.

```text theme={null}
https://meterengine.com/invoice-links#<token>
```

`token`은 발급 응답에 한 번만 실립니다. MeterEngine은 이 값의 원문을 저장하지 않으므로 발급 이력에서도 다시 볼 수 없습니다.

MeterEngine은 메일을 보내지 않으니 링크와 안내는 도입사가 직접 전달합니다. 자세한 내용은 [MeterEngine 소개](https://docs.meterengine.com/index.md)에 있습니다.

> [!WARNING]
>
> 링크를 가진 사람은 누구나 그 인보이스를 볼 수 있습니다. 해당 고객에게만 전달하고, 잘못 보냈으면 바로 폐기하세요.

## 콘솔에서 발급하기

**1. 인보이스의 수납 상세로 들어간다**

'확정 인보이스' 화면에서 인보이스의 '수납과 고객 조회 링크'를 누르거나, '수납과 취소' 화면에서 고객 이름을 누릅니다. 화면 아래 '고객 조회 링크' 구역에서 발급합니다. admin 권한이 없는 사용자에게는 발급과 폐기 버튼이 보이지 않습니다.

**2. 사용 기간을 고른다**

'사용 기간'에서 7일, 30일, 90일 중 하나를 고릅니다. 다른 기간은 API로 발급합니다.

**3. 재시도 허용 여부를 정한다**

결제가 실패했을 때 고객이 이 링크에서 등록 카드로 다시 결제하게 하려면 '고객의 실패 결제 재시도 허용'에 체크합니다. 체크하지 않으면 조회 전용 링크가 됩니다. 고객 재시도의 조건은 [결제 실패와 재시도](https://docs.meterengine.com/payments/retries.md)에 있습니다.

**4. 발급하고 복사한다**

'고객 조회 링크 발급'을 누르면 '전달할 고객 조회 링크'에 전체 주소가 나옵니다. '고객 조회 링크 복사'로 복사합니다. '고객 화면 열기'로 고객이 볼 화면을 미리 볼 수 있습니다.

**5. 고객에게 전달한다**

메신저나 도입사의 메일로 고객에게 보냅니다.

> [!WARNING]
>
> 발급한 링크 원문은 그 화면에서만 보입니다. 복사하기 전에 화면을 닫았다면 새 링크를 발급하고, 쓰지 않을 이전 링크는 폐기하세요.

## API로 발급하기

**1. 링크를 발급한다**

`POST /v1/invoices/{id}/view-links`를 부릅니다. 본문은 생략할 수 있습니다.

```bash cURL theme={null}
curl -X POST "https://meterengine.com/v1/invoices/7b0c2f4e-5a1d-4c8e-9f3b-2d6a8e1c4b70/view-links" \
  -H "Authorization: Bearer me_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"expires_in_days": 30, "allow_payment_retry": false}'
```

```javascript Node theme={null}
const res = await fetch(
  "https://meterengine.com/v1/invoices/7b0c2f4e-5a1d-4c8e-9f3b-2d6a8e1c4b70/view-links",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer me_test_xxxxxxxx",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ expires_in_days: 30, allow_payment_retry: false }),
  },
);
const link = await res.json();
const url = `https://meterengine.com/invoice-links#${link.token}`;
```

| 본문 필드 | 형식 | 뜻 |
| - | - | - |
| `expires_in_days` | 정수, 선택 | 사용 기간(일). 1부터 90까지 받고, 생략하면 30일입니다 |
| `allow_payment_retry` | 불리언, 선택 | 고객의 실패 결제 재시도를 허용합니다. 생략하면 `false`입니다 |

**2. 응답의 token으로 주소를 만든다**

응답은 201입니다.

```json 응답 201 theme={null}
{
  "id": "d4b7fa05-9e6c-4dbf-8f40-8c5e1bad3f46",
  "token": "me_invoice_0xXTRGrmL2amO3eiruperPm8I7M82SIr",
  "created_at": "2026-11-05T10:00:00+09:00",
  "expires_at": "2026-12-05T10:00:00+09:00",
  "revoked_at": null,
  "mode": "test",
  "allow_payment_retry": false
}
```

`token`을 `#` 뒤에 붙여 `https://meterengine.com/invoice-links#me_invoice_0xXTRGrmL2amO3eiruperPm8I7M82SIr`처럼 만듭니다. 폐기할 때 쓰도록 `id`도 저장해 둡니다.

**3. 고객에게 전달한다**

만든 주소를 고객에게 보냅니다. `token` 원문은 링크를 보낸 뒤 도입사 시스템에 남기지 않아도 됩니다.

**mode** `string`

링크가 결제 상태를 보여 줄 결제 모드(`test` 또는 `live`)입니다. 발급할 때의 결제 모드로 정해지고 바뀌지 않습니다. 테스트 환경에서 발급한 링크는 `test`입니다.

## 고객이 보는 화면

링크를 연 고객은 '청구서 조회' 화면에서 아래를 봅니다.

* 청구서 번호, 확정 시각(KST), 공급자, 고객 이름
* 청구 항목마다 수량, 단가, 공급가액과 합계의 공급가액, 부가세, 확정 청구액
* 결제 내역: 수납 상태, 취소 제외 납부액, 취소 완료액, 결제 대기액, 최근 결제 처리 시각
* 재시도를 허용한 링크에서 결제가 실패했으면 '결제 다시 시도'
* 테스트 결제 링크에는 테스트 모드의 청구 내역이라는 안내

'공급자'에는 도입사 이름이 나옵니다. 공급자 정보가 어디에 쓰이는지는 [공급자 정보](https://docs.meterengine.com/account/supplier.md)를 보세요.

청구 항목과 금액은 확정 시점의 기록이라 이후 요금 변경이나 결제 취소로 바뀌지 않습니다. 결제를 취소하면 결제 내역의 '취소 완료액'에만 나타나고, 취소액을 '결제 대기액'에 다시 더하지 않습니다. 이 화면은 세금계산서나 영수증이 아닙니다.

> [!NOTE]
>
> 고객이 링크를 열면 주소창에서 `#` 뒤의 token이 지워집니다. 고객이 주소창의 주소를 복사해 다른 사람에게 보내면 열리지 않으니, 전달이 필요하면 화면의 '조회 링크 복사'를 쓰라고 안내하세요.

## 발급 이력과 폐기

필요 권한: 이력 조회는 read(조회), 폐기는 admin(전체 관리)

`GET /v1/invoices/{id}/view-links`는 인보이스에 발급한 링크를 최근 발급 순으로 돌려줍니다. `token`은 실리지 않습니다.

```json 응답 200 theme={null}
{
  "invoice_view_links": [
    {
      "id": "d4b7fa05-9e6c-4dbf-8f40-8c5e1bad3f46",
      "created_at": "2026-11-05T10:00:00+09:00",
      "expires_at": "2026-12-05T10:00:00+09:00",
      "revoked_at": null,
      "mode": "test",
      "allow_payment_retry": false
    }
  ]
}
```

링크를 더 쓰지 못하게 하려면 콘솔 '고객 조회 링크' 목록에서 '링크 폐기'를 누르거나 API로 폐기합니다.

```bash cURL theme={null}
curl -X POST "https://meterengine.com/v1/invoices/7b0c2f4e-5a1d-4c8e-9f3b-2d6a8e1c4b70/view-links/d4b7fa05-9e6c-4dbf-8f40-8c5e1bad3f46/revoke" \
  -H "Authorization: Bearer me_test_xxxxxxxx"
```

응답은 200이고 `revoked_at`이 채워진 링크입니다. 이미 폐기한 링크를 다시 폐기해도 같은 결과가 돌아옵니다.

> [!WARNING]
>
> 폐기는 되돌릴 수 없습니다. 이미 전달한 링크도 그 순간부터 열리지 않습니다. 다시 보여 주려면 새 링크를 발급하세요.

* 만료되거나 폐기된 링크, 도입사가 활성 상태가 아닌 링크는 고객 화면에서 모두 '사용할 수 없는 조회 링크입니다'로 보입니다. 고객에게는 새 링크를 발급해 전달합니다.
* 사용 기간과 재시도 허용은 발급한 뒤 바꿀 수 없습니다. 바꾸려면 새 링크를 발급하고 이전 링크를 폐기합니다.
* 폐기와 만료는 링크로 보는 권한만 끝냅니다. 확정 인보이스와 결제 기록은 그대로입니다.

## 오류

| 상태 | code | 뜻 |
| - | - | - |
| 400 | `validation_error` | 경로의 id가 UUID가 아니거나 `expires_in_days`가 1부터 90까지의 범위 밖입니다 |
| 404 | `invoice_not_found` | 그런 인보이스가 없습니다. 다른 업무 환경의 인보이스도 이렇게 보입니다 |
| 404 | `invoice_view_link_not_found` | 폐기하려는 링크가 그 인보이스에 없습니다 |
| 409 | `payment_mode_mismatch` | 재시도를 허용하는 링크를 API 키로 만들 때 키의 모드가 지금 결제 모드와 다릅니다 |

## 자체 서비스 화면에 청구 내용을 보여 주려면

도입사 서비스 안에 청구 내용을 직접 그리려면 도입사 서버에서 read 권한 API 키로 `GET /v1/invoices/{id}`를 불러 그 값을 씁니다. 결제 상태는 `GET /v1/invoice-payments`로 함께 조회합니다. 고객 조회 화면이 내부에서 쓰는 공개 경로는 API 참조에 싣지 않으니 도입사 서버에서 직접 부르지 마세요. 브라우저에서 MeterEngine API를 직접 부르는 것도 지원하지 않으므로 API 키는 도입사 서버에만 둡니다.


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