tgpay cryptoAPI
crypto-payinvoicesapiwebhook

청구서로 결제 받기

읽는 데 2분마지막 수정 2026년 8월 11일

청구서는 Telegram 사용자에게 대금을 청구하는 방법이에요. API로 하나 만들어 결제할 사람에게 링크를 보내면, 상대가 확인을 누르는 순간 앱 잔액으로 들어와요.

흐름

  1. 청구서를 만들어요. createInvoice에 자산과 금액을 넘겨요. 법정화폐로 값을 매겨도 되고요(아래 참고).
  2. 결제할 사람에게 링크를 보내요. 응답에 들어 있는 링크예요. 열면 앱의 결제 화면으로 이동해요.
  3. 상대가 확인해요. 잔액에서 바로 결제되고 네트워크 수수료도 없어요. 잔액이 부족하면 외부 지갑에서 입금해 결제해도 돼요. 입금이 도착하면 알아서 결제되고, 내 쪽에서 보기에는 똑같아요.
  4. 알림이 와요. invoice_paid webhook이 오고, 금액이 앱 잔액으로 들어와요.
  5. 주문을 처리하세요. 더 기다릴 건 없어요. 그 시점에 결제는 끝이에요.

webhook 대신 직접 조회하고 싶다면 getInvoices로 청구서와 현재 상태를 가져올 수 있어요. 빠른 쪽은 webhook이고, 조회는 보조 수단이에요.

법정화폐로 값 매기기

청구서 금액은 코인으로 매길 수도 있고, 법정화폐로 매기면서 받을 자산 목록을 정해 둘 수도 있어요. 그러면 내는 사람이 가진 자산 중에서 골라 결제하고, 결제 시점 시세로 환산돼요. 카탈로그 가격이 실제 통화로 적혀 있는 상점이라면 보통 이쪽을 골라요.

가격을 딱 고정해서 보여 주고 싶다면 rate_lock_seconds로 만들 때의 환산 시세를 정해진 시간 동안 묶어 둘 수 있어요. 내는 사람은 묶인 금액 그대로 보고, 그동안의 시세 변동은 내가 떠안아요. 자세한 건 청구서 레퍼런스에 있어요.

swap_to를 넣으면 들어온 결제를 하나의 자산으로 바꿔서 받을 수도 있어요. 직접 교환하지 않고도 잔액을 스테이블코인으로 유지할 때 편해요.

알아 두면 좋은 옵션

  • description — 결제 화면에서 내는 사람에게 보여요.
  • hidden_message — 결제한 뒤에만 보여요. 코드나 키, 링크를 따로 보내는 채널 없이 전달할 때 써요.
  • payload — 내가 넣는 아무 문자열이고, webhook에 그대로 되돌아와요. 주문 번호를 여기 넣으면 돼요.
  • expires_in — 이 시간이 지나면 더 이상 결제할 수 없어요.
  • paid_btn_name / paid_btn_url — 결제한 사람에게 보여 줄 버튼이에요. 내 봇이나 채널, 상품 페이지로 돌려보낼 때 써요.
  • open_amount — 금액을 정해 두지 않고, 내는 사람이 결제할 때 직접 넣어요. 후원이나 팁에 어울려요.

아직 결제되지 않은 청구서는 deleteInvoice로 취소할 수 있어요.

환불

refundInvoice는 결제된 청구서의 액면 금액을, 또는 그중 일부만 앱 잔액에서 결제한 사람에게 돌려줘요. 익명으로 결제한 사람에게도 보낼 수 있고, 그 사람이 누구인지는 드러나지 않아요. 부분 환불은 액면 금액까지 쌓이고, 청구서의 refunded_amount에 기록돼요. spend_id를 넘기면 응답이 늦어 다시 보내도 두 번 환불되지 않고 원래 결과가 그대로 돌아와요. 서비스 수수료는 환불되지 않아요.

⚠️ 주문을 처리하기 전에 webhook 서명을 확인하세요

내 webhook 주소로는 누구나 POST를 보낼 수 있어요. TgCryptoPay-API-Signature 헤더부터 확인하세요. 원본 요청 본문을 HMAC-SHA256으로 서명한 값이고, 키는 API 토큰의 SHA-256이에요. 서명이 맞을 때만 결제를 진짜로 받아들이고, update_id로 중복을 걸러서 재전송 때문에 주문이 두 번 나가지 않게 해 주세요.