BOLT11 인보이스는 생성 timestamp와 선택적 expiry를 담으며 expiry가 없으면 기본 3,600초가 적용됩니다. 만료는 `생성 시각+expiry`로 계산하고, 금액 필드가 비어 있으면 지갑이 사용자의 입력을 요구할 수 있습니다. 결제 전 네트워크 prefix, 최종 금액, 수신 설명, 남은 시간과 payment hash를 확인하고 만료된 인보이스는 새로 발급받으세요.
인보이스는 주소가 아니라 조건이 서명된 결제 요청입니다
BOLT11 문자열에는 네트워크와 선택적 금액을 나타내는 human-readable part, 생성 timestamp, payment hash, 설명 또는 설명 해시, 수신 노드 서명이 들어갑니다. 지갑은 이를 디코딩해 사용자가 읽을 수 있는 결제 화면을 만듭니다. 문자열 일부만 보고 메인넷·테스트넷과 금액을 추측하지 마세요.
payment hash는 수신자가 결제 성공 시 공개할 preimage와 연결됩니다. 같은 인보이스의 상태를 조회할 때 중요한 식별자지만 상점 주문 번호와 자동으로 같은 것은 아닙니다. 운영 시스템은 주문 ID, payment hash, invoice 문자열, 생성·만료 시각을 함께 보관해야 재시도와 환불 문의를 정확히 처리할 수 있습니다.
라이트닝 결제의 재시도 기준은 새 QR이 보였는지가 아니라 기존 payment hash가 최종적으로 성공했는지입니다.
JOBCOIN 해설

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.
- 인보이스는 주소가 아니라 조건이 서명된 결제 요청입니다
BOLT11 문자열에는 네트워크와 선택적 금액을 나타내는 human-readable part, 생성 timestamp, payment hash, 설명 또는 설명 해시, 수신 노드 서명이 들어갑니다.
- 만료 시각은 생성 timestamp에 상대값을 더합니다
BOLT11은 `x` 태그로 expiry를 초 단위 지정하며 생략 시 기본 3,600초를 사용합니다.
- 금액 필드가 없는 인보이스는 사용자가 값을 정할 수 있습니다
BOLT11 human-readable part의 금액은 선택 사항입니다.
AI로 제작한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.
만료 시각은 생성 timestamp에 상대값을 더합니다
BOLT11은 `x` 태그로 expiry를 초 단위 지정하며 생략 시 기본 3,600초를 사용합니다. 예를 들어 생성 timestamp가 14시 00분 00초이고 expiry가 600초라면 14시 10분 00초가 경계입니다. 사용자가 14시 08분에 QR을 열었다고 해서 그때부터 10분이 새로 시작되는 것은 아닙니다.
휴대전화 시계가 크게 틀리거나 결제 페이지가 오래된 QR을 캐시하면 지갑이 만료를 즉시 표시할 수 있습니다. 이때 만료를 무시해 전송하도록 우회하지 말고 판매자에게 같은 주문의 새 인보이스를 요청하세요. 새 인보이스의 payment hash와 주문 연결이 갱신됐는지도 확인해야 합니다.
| 필드 | 뜻 | 결제 전 점검 |
|---|---|---|
| prefix | 메인넷·테스트넷과 선택 금액 | 사용하려는 네트워크인지 |
| timestamp | 인보이스 생성 기준 시각 | 현재 시각과 차이 |
| expiry | 생성 뒤 허용 초 | 남은 시간 충분한지 |
| payment hash | 결제별 preimage 약속 | 기존 시도와 중복 여부 |
| description | 지급 설명 또는 해시 | 주문 내용과 일치하는지 |
금액 필드가 없는 인보이스는 사용자가 값을 정할 수 있습니다
BOLT11 human-readable part의 금액은 선택 사항입니다. 금액이 없으면 기부처럼 지급자가 액수를 입력하는 결제일 수 있습니다. 지갑이 0원 결제로 해석해서는 안 되며 사용자가 입력한 금액을 최종 승인 화면에 분명히 보여줘야 합니다.
금액이 들어 있는 인보이스는 그 값을 임의로 바꾸지 않습니다. 단위 접미사는 milli, micro, nano, pico bitcoin 배율을 사용하므로 문자열을 눈으로 환산하기보다 신뢰할 수 있는 지갑 디코더로 확인하세요. 상점 화면의 법정화폐 환산과 인보이스 msat 금액이 맞는지도 발급 시점 환율 규칙에 따라 점검합니다.
- prefix로 메인넷과 테스트넷을 구분합니다.
- 지갑이 표시한 sat 또는 msat 금액을 주문서와 대조합니다.
- 생성 timestamp와 expiry로 실제 만료 시각을 계산합니다.
- 설명과 수신 노드 정보를 가능한 범위에서 확인합니다.
- payment hash로 기존 시도의 성공·pending·failed를 조회합니다.
경로 힌트와 기능 비트는 지갑 호환성에 영향을 줍니다
인보이스에는 사설 채널로 수신자에게 도달하는 route hint가 들어갈 수 있고, payment secret이나 기본 최소 최종 CLTV 같은 태그도 포함됩니다. 송신 지갑은 알 수 없는 필수 feature bit가 있으면 안전하게 결제를 중단해야 합니다. 디코딩 성공과 실제 경로 발견 성공은 서로 다른 단계입니다.
인보이스가 유효해도 송신 측 아웃바운드 유동성, 수신 측 인바운드 유동성, 중간 홉의 정책 때문에 결제가 실패할 수 있습니다. 반대로 경로 탐색 실패를 인보이스 위조로 단정해서도 안 됩니다. 오류 코드와 시도 경로 노출 범위는 지갑 구현별로 달라 공식 지원 문서를 함께 봐야 합니다.
만료 직전 결제는 성공 여부가 늦게 보일 수 있습니다
결제 시도를 만료 전에 시작했어도 여러 홉의 HTLC가 진행되는 동안 UI가 pending으로 남을 수 있습니다. 새 인보이스를 즉시 받아 다시 결제하면 첫 시도가 성공하면서 이중 지급이 생길 수 있습니다. 먼저 지갑에서 기존 payment hash 상태와 preimage 수신 여부를 확인하세요.
수신 서비스는 만료된 인보이스를 결제 완료로 새로 받아들이는 방식에 의존하지 말고 새 payment hash를 발급해야 합니다. 주문 시스템은 인보이스 만료와 주문 취소를 같은 시각으로 강제하지 않을 수도 있으므로 `invoice expired`, `payment settled`, `order fulfilled` 상태를 분리해야 합니다.
스크린샷보다 디코딩 값과 상태 기록을 남깁니다
지원 문의에 QR 스크린샷만 남기면 카메라 화질과 앱 표시 때문에 정확한 필드를 재현하기 어렵습니다. 비밀 preimage를 공개하지 않는 범위에서 invoice 문자열 또는 payment hash, 생성·만료 시각, 금액, 지갑 오류 문구를 보관하세요. 인보이스 자체에도 수신 정보가 있으므로 공개 게시판 공유는 피합니다.
사업자는 서버 시각을 UTC로 기록하고 사용자에게 현지 시간과 남은 시간을 함께 보여주는 편이 좋습니다. 만료가 가까우면 결제 버튼을 비활성화하고 새 인보이스를 명시적으로 발급하세요. 기존 시도 조회가 끝나기 전 새 결제를 강제하지 않는 것이 중복 결제 예방의 핵심입니다.
자주 묻는 질문
expiry가 없으면 인보이스는 영구 유효한가요?
아닙니다. BOLT11 기본 expiry는 3,600초이며 생성 timestamp부터 계산합니다.
금액 없는 인보이스는 0 sat 결제인가요?
아닙니다. 지급자가 금액을 입력하는 인보이스일 수 있으므로 최종 입력액을 확인해야 합니다.
만료 오류가 나면 새 QR을 바로 결제해도 되나요?
기존 시도가 pending이었다면 payment hash 상태부터 확인하세요. 첫 결제가 나중에 성공하면 중복 지급이 될 수 있습니다.
더 깊이 읽기
본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.



