메인 콘텐츠로 건너뛰기
인보이스를 확정해도 결제는 자동으로 시작되지 않습니다. 확정한 뒤 인보이스마다 결제를 요청해야 합니다.
첫 결제는 콘솔의 고객별 수납 화면에서 요청하거나, admin 권한 API 키로 POST /v1/invoices/{id}/payment-attempts를 부릅니다. 인보이스가 자동으로 확정된 경우에도 같습니다. MeterEngine이 스스로 하는 결제 작업은 도입사가 한 번 요청한 결제를 이어서 처리하는 것뿐입니다. 결제 연동 한눈에 보기

시작하기 전에

지금 업무 환경에 토스페이먼츠 키를 저장했습니다. 토스페이먼츠 상점 준비와 키 저장
결제할 고객이 지금 결제 모드로 카드를 등록했습니다. 고객 카드 등록 링크
결제할 달의 인보이스를 확정했습니다. 인보이스 수동 확정
결제 금액은 인보이스의 total_amount(세금 포함)입니다. 청구 예정액은 세금을 뺀 공급가액이고, 결제는 세금을 포함한 확정 금액으로 합니다. 예정액, 확정액, 수납액

인보이스 id 찾기

결제는 인보이스 단위로 요청합니다. read 권한 API 키로 GET /v1/invoices?month=YYYY-MM을 부르면 그 청구 월의 확정 인보이스가 고객마다 한 줄씩 나오고, 각 항목의 id가 인보이스 id입니다. customer_id를 함께 주면 그 고객의 인보이스만 나옵니다.

결제 요청

1

수납과 취소 화면을 연다

왼쪽 메뉴 ‘사용량에서 수납까지’에서 ‘수납과 취소’를 열고, 결제할 달을 고릅니다.
2

고객을 고른다

고객 이름을 누르면 그 인보이스의 수납 화면이 열립니다. ‘현재 결제 상태’에 결제 모드와 수납 상태가 보입니다.
3

결제를 요청한다

‘등록 카드로 결제’를 누르고, 열린 창에서 결제 모드와 금액, 카드를 확인한 뒤 ‘등록 카드로 결제’를 한 번 더 누릅니다. 이전 결제가 실패한 인보이스에는 같은 자리에 ‘결제 다시 시도’가 나옵니다. admin(전체 관리) 권한이 필요합니다.
결제 버튼은 수납 상태가 ‘결제 전’이거나 ‘결제 실패’일 때만 나옵니다. 등록 카드가 없으면 버튼 대신 ‘카드 등록 링크 만들기’가, 토스페이먼츠 키가 없으면 ‘설정에서 토스페이먼츠 키 저장’ 링크가 나옵니다.
결제 요청에는 멱등 키(Idempotency-Key)가 없습니다. 응답을 받지 못했거나 시간이 초과됐으면 같은 요청을 바로 다시 보내지 말고, 먼저 GET /v1/invoices/{id}/payment-attempts로 결제 시도가 생겼는지 확인하세요. MeterEngine은 결제 중이거나 결제된 시도가 있는 인보이스의 새 결제를 409 invoice_already_paid로 막지만, 결과를 확인하는 것이 먼저입니다.
결제 요청은 토스페이먼츠의 승인 응답을 기다렸다가 답하므로 길게는 1분이 넘게 걸릴 수 있습니다. HTTP 클라이언트의 대기 시간을 넉넉히 잡으세요. 위 예시는 90초입니다. 대기 시간이 지나거나 연결이 끊기면 위 경고대로 결제 시도 목록부터 확인합니다.

응답 읽기

결제 시도가 만들어지면 결과와 관계없이 201입니다. 결과는 본문의 status로 구분합니다.
응답 201 (승인)
string
결제 시도 id(UUID)입니다. 토스페이먼츠에는 이 값이 주문번호(orderId)로 기록됩니다.
string
done(승인), failed(거절), pending(결과 확인 중) 중 하나입니다.
integer
청구한 금액(원)입니다. 인보이스의 total_amount와 같습니다.
string
토스페이먼츠가 승인한 결제의 키입니다. done일 때만 있습니다.
string
failed일 때만 있습니다. 토스페이먼츠의 승인 거절 코드, 주문 조회로 확인한 토스페이먼츠 결제 상태(ABORTED, EXPIRED), 또는 MeterEngine이 정한 값입니다.
string
failed일 때만 있습니다. 토스페이먼츠의 거절 문구이거나 MeterEngine 오류 문구입니다.
string
요청 시각(KST)입니다. completed_at은 결과가 정해진 시각이며 pending이면 null입니다.
토스페이먼츠 상점관리자에서 이 결제를 찾을 때는 주문번호(결제 시도 id), 주문명(<청구 월> 사용료, 예: 2026-10 사용료), 고객 식별값(고객 id)으로 찾습니다.

pending은 실패가 아니다

pending은 토스페이먼츠가 승인했는지 아직 모르는 상태입니다. 승인됐을 수도 있으므로 실패로 보고 다시 결제하면 이중 청구가 될 수 있습니다.
  • MeterEngine은 요청하고 2분이 지난 pending 시도를 1분마다 토스페이먼츠에 다시 조회해 done이나 failed로 바꿉니다. 토스페이먼츠 웹훅을 등록했다면 그보다 먼저 반영될 수 있습니다.
  • 요청하고 10분이 지나도 토스페이먼츠에 그 주문이 없으면 failed(failure_code가 NOT_FOUND_PAYMENT)로 끝냅니다.
  • 주기적으로 다시 조회하는 것은 요청하고 7일까지입니다. 7일이 지나도 pending이면 MeterEngine은 더 조회하지 않습니다. 토스페이먼츠 상점관리자에서 주문번호로 결제 여부를 확인하세요. 처리가 필요하면 MeterEngine 소개의 문의 방법으로 결제 시도 id를 알려 주세요.
pending 시도가 있는 동안 같은 인보이스에 새 결제를 요청하면 409 invoice_already_paid로 거절됩니다. 콘솔에서는 “요청을 접수했습니다. 결과를 확인 중이므로 다시 청구하지 말고 상태를 새로고침하세요.”라는 안내가 나오고, 수납 상태가 ‘결과 확인 중’으로 보입니다.

거절되는 요청

결제 시도를 만들지 않고 거절하면 code와 message가 담긴 오류 응답이 옵니다. code로 분기하세요. 오류 형식은 오류 응답과 X-Request-ID에 있습니다.
응답 409

결과 확인

결제 결과는 아래 방법으로 확인합니다. 결제 시도 목록. read 권한 API 키로 GET /v1/invoices/{id}/payment-attempts를 부르면 그 인보이스의 결제 시도가 요청 시각이 늦은 것부터 나옵니다. 모든 결제 모드의 시도가 함께 나오니 mode를 같이 보세요.
응답 200
수납 상태. read 권한 API 키로 GET /v1/invoice-payments?month=YYYY-MM을 부르면 인보이스마다 지금 결제 모드의 수납 상태가 한 줄씩 나옵니다. customer_id로 좁힐 수 있습니다. 콘솔 ‘수납과 취소’ 화면의 ‘수납 상태’ 열과 같은 값입니다.
응답 200
수납 상태(status)는 지금 결제 모드에서 가장 늦게 요청한 시도로 정합니다. 승인됐으면 paid(수납 완료), 실패했으면 failed(결제 실패)이고, 이때 last_failure_code에 실패 코드가, 자동 재시도 예정이면 next_retry_at에 그 시각이 있습니다. 상태 값 전체와 콘솔 표기는 수납 상태와 대사 확인에 있습니다. 결제 결과는 MeterEngine 통보(payment_succeeded, payment_failed)로도 받을 수 있습니다. 통보는 type으로 분기하고 모르는 필드는 무시하세요. 실패 사유는 통보에 실리지 않으니 결제 시도 목록이나 수납 상태로 확인합니다. 웹훅 이벤트 유형과 data

다음 단계

결제 실패와 재시도

자동 재시도 조건과 다시 하지 않는 실패

결제 취소

승인된 결제의 전부 또는 일부 취소

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

인보이스 조회 링크 만들기와 전달

수납 상태와 대사 확인

토스페이먼츠 기록과 맞춰 보기