메인 콘텐츠로 건너뛰기
네트워크 오류나 시간 초과로 응답을 받지 못하면 요청이 처리됐는지 알 수 없습니다. 이럴 때 같은 요청을 다시 보내도 결과가 한 번만 반영되는 성질을 멱등이라고 합니다. MeterEngine은 요청마다 같은 요청을 알아보는 방법이 다르니, 다시 보내기 전에 아래 표에서 그 요청의 규칙을 확인하세요.

요청별 규칙

아래 요청은 같은 요청을 알아보는 장치가 없습니다. 다시 보내기 전에 먼저 조회하세요.

이벤트: transaction_id

이벤트는 transaction_id로 같은 이벤트를 알아봅니다. 이미 저장된 transaction_id로 다시 보내면 저장하지 않고, 단건 요청은 200과 "duplicate": true로, 배치는 그 원소의 "result": "duplicate"로 답합니다.
응답을 받지 못했으면 같은 transaction_id로 다시 보내면 됩니다. 두 번 청구되지 않습니다.
같은 transaction_id로 내용을 바꿔 다시 보내도 처음 저장한 이벤트가 남습니다. type, properties, timestamp가 다르거나 customer_id를 다른 고객으로 바꿔도 오류 없이 "duplicate": true로 답하므로, 값을 고치려고 다시 보낸 이벤트는 반영되지 않습니다. customer_id가 없는 고객을 가리키면 중복 판정 전에 404 customer_not_found로 거절됩니다. 보낸 이벤트는 고치거나 지울 수 없습니다. 바로잡는 방법은 사용량 이벤트 보내기를 보세요.
transaction_id를 정할 때 알아 둘 규칙입니다.
  • 범위는 도입사와 업무 환경입니다. 고객과 관계없이 한 업무 환경 안에서 유일해야 합니다. 서로 다른 고객의 이벤트에 같은 transaction_id를 쓰면 나중 것은 중복으로 보고 버립니다. 테스트 환경과 실제 환경은 따로 셉니다.
  • 사용량이 생긴 순간에 한 번 정하고 다시 보낼 때도 같은 값을 씁니다. 다시 보낼 때마다 새로 만들면 같은 사용량이 두 번 저장됩니다. 1자에서 255자까지 받습니다.
  • 이미 저장된 이벤트는 받는 기간과 고객 보관보다 중복 판정이 먼저입니다. 이미 저장된 transaction_id라면 timestamp가 35일보다 오래됐거나 그 사이 고객을 보관했어도 거절하지 않고 중복으로 답합니다. 그래서 오래 쌓아 둔 이벤트를 다시 보내도 이미 저장된 것은 거절로 바뀌지 않습니다.
  • 한 배치 안에 같은 transaction_id가 두 번 있으면 먼저 받아들인 원소를 저장하고 뒤의 원소는 duplicate로 답합니다.
다시 보낼지 멈출지, 보내지 못한 이벤트를 쌓아 두는 방법은 재전송 설계를 보세요.

고객과 미터 등록: Idempotency-Key

고객 등록(POST /v1/customers)과 미터 등록(POST /v1/billable-metrics)은 Idempotency-Key 헤더를 받습니다. 헤더는 선택이지만, 응답을 받지 못했을 때 안전하게 다시 보내려면 넣으세요.
1

요청마다 키를 만든다

등록할 때마다 새 키를 만들어 요청과 함께 연동 쪽에 저장합니다. 1자에서 255자까지 받습니다. UUID를 쓰면 편합니다.
2

키를 넣어 보낸다

3

응답을 받지 못했으면 같은 키와 같은 본문으로 다시 보낸다

첫 요청이 처리됐다면 MeterEngine은 처리하지 않고 첫 응답을 HTTP 상태까지 그대로 돌려주고 Idempotency-Replayed: true 헤더를 붙입니다. 첫 요청이 처리되지 않았다면 이번 요청을 처리합니다.
키의 규칙은 아래와 같습니다.
  • 범위는 도입사, 업무 환경, 요청 종류입니다. 고객 등록과 미터 등록은 같은 키를 써도 서로 영향이 없습니다. 테스트 환경과 실제 환경도 따로입니다.
  • 같은 키에 다른 본문을 보내면 409 idempotency_conflict입니다. 본문을 고쳐 새로 등록하려면 새 키를 쓰세요. 공백이나 필드 순서만 다른 본문은 같은 본문으로 봅니다.
  • 첫 응답은 기한 없이 보관합니다. 그 뒤에 고객이나 미터를 고치거나 보관해도, 같은 키로 다시 보내면 등록 당시의 첫 응답이 옵니다. 지금 상태는 조회 요청으로 확인하세요.
  • 비었거나 공백뿐인 키, 255자를 넘는 키는 400 validation_error입니다. errors[].field가 Idempotency-Key입니다.
  • 같은 키로 동시에 두 번 보내도 한 번만 등록되고 두 요청 모두 같은 응답을 받습니다.
고객 등록은 external_id로도 같은 고객을 알아봅니다. 같은 external_id로 다시 보내면 새로 만들지 않고 기존 고객을 200으로 돌려주며 이름과 이메일은 바꾸지 않습니다. external_id를 빼고 Idempotency-Key도 없이 다시 보내면 고객이 하나 더 만들어집니다. read 권한이 없는 키로 받은 200 응답에는 id, external_id, version만 채워져 있습니다. 고객 id를 잃었을 때 찾는 방법은 고객 등록과 ID 대응을 보세요.

결제 취소: Idempotency-Key

결제 취소 요청(POST /v1/payment-attempts/{id}/cancellations)의 Idempotency-Key는 고객과 미터 등록의 키와 규칙이 다릅니다. 결제 취소는 응답을 받지 못했을 때 같은 키로 다시 보내야 같은 취소가 두 번 일어나지 않습니다. 취소 절차는 결제 취소를 보세요.

단가와 요금제: 같은 자리 덮어쓰기

단가 등록과 요금제 등록은 키 없이도 다시 보내도 됩니다. 같은 자리(단가는 미터, 차원 값 조합, 고객 범위, 시작 월이 같은 것, 요금제는 고객 범위와 시작 월이 같은 것)에 다시 보내면 새로 만들지 않고 요청 값으로 덮어쓰고 201로 답합니다.
effective_from을 빼면 이번 달(KST)이 시작 월이 됩니다. 달이 바뀐 뒤에 같은 요청을 다시 보내면 지난 단가를 덮어쓰지 않고 새 달의 단가가 하나 더 생깁니다. 다시 보낼 수 있는 요청에는 effective_from을 적어 두세요. 다만 시작 월이 지난달 이전이면 409 price_rate_history_immutable(요금제는 409 price_plan_history_immutable)로 거절됩니다.
덮어쓰기는 마지막 요청이 이깁니다. 다른 사람이 콘솔에서 그 사이에 바꾼 값도 덮어쓰니, 오래전에 실패한 요청을 나중에 다시 보내지 마세요. 단가와 요금제의 시작 월과 이력 규칙은 단가 모델과 버전과 기본료와 최소 사용료를 보세요.

인보이스 확정

POST /v1/invoices?month=YYYY-MM은 그 달이 이미 확정된 고객을 건너뛰므로 같은 달로 다시 불러도 인보이스가 겹치지 않습니다. 확정하지 못한 고객은 다시 부르면 다시 시도합니다. 자세한 내용은 인보이스 수동 확정을 보세요.