paymark

매칭은 어떻게 되나

입금자명 · 금액 · 마감 · 보류 · 늦게 온 주문 · 되돌리기

입금 통지가 오면 같은 계좌의 열린 주문 가운데 금액과 입금자명이 맞는 것을 찾습니다. 하나면 확정, 여럿이거나 애매하면 보류, 없으면 미매칭입니다. 판매자 화면과 API 가 같은 판정을 씁니다.

짝짓는 기준

기준설명
계좌주문의 bank_account_id 계좌로 들어온 입금만 봅니다
금액원 단위로 정확히 같아야 합니다. 부분 입금 · 합산 입금은 맞추지 않습니다
입금자명주문의 payer_name 과 은행 통지의 입금자명. 앞뒤 공백은 우리가 지웁니다. 은행이 이름을 자르거나 괄호 · 숫자를 붙이는 경우는 판매자가 켠 알고리즘 매칭 규칙이 맞춥니다
시각ordered_at 보다 앞선 입금과는 짝짓지 않습니다 — 주문 전에 들어온 돈은 그 주문의 것이 아닙니다
마감expires_at(없으면 등록 뒤 14일)이 지나면 expired 가 되고 자동 확정 대상에서 빠집니다

주문 객체의 payment.reason 이 어떤 기준으로 맞았는지 말합니다 — exact(그대로 같음) 또는 rule:…(규칙으로 맞춤).

결과 세 가지

입금 status뜻이벤트다음
confirmed주문 하나와 맞아 확정transaction.deposited → order.paid할 일 없음
held후보가 여럿이거나 애매함transaction.deposited → transaction.held(data.candidate_order_ids)판매자가 화면에서 고르거나, 서버가 match 로 알려 줌
unmatched맞는 주문이 없음transaction.deposited 만나중에 주문이 들어오면 다시 봄(아래)

transaction.deposited 는 입금마다 한 번, 첫 판정이 끝난 뒤에 납니다. status 에 결과가 있으니 order.paid 를 따로 기다리지 않아도 됩니다.

보류를 푸는 법

보류된 입금은 판매자 화면의 확인할 입금에 뜹니다. 서버가 어느 주문인지 안다면 직접 풉니다.

curl -s -X POST "$API/v1/transactions/txn_…/match" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{ "order_id": "ord_…" }'
  • 주문은 입금과 같은 계좌 · 같은 금액이어야 합니다 — 아니면 409 transaction_not_matchable
  • 그 사이 자동 매칭이나 화면에서 먼저 확정했으면 409 order_taken — 주문을 다시 읽으면 paid 입니다
  • 우리 손님 돈이 아니면 exclude 로 뺍니다. 같은 금액의 열린 주문이 있으면 뺄 수 없습니다(409) — 먼저 주문을 정리합니다. restore 로 되돌릴 수 있습니다

늦게 온 주문

입금이 먼저 들어오고 주문이 나중에 등록되는 일이 있습니다(결제 뒤 주문 전송이 늦은 쇼핑몰, 재시도). ordered_at 이 입금 시각보다 앞이면 그 미매칭 입금을 다시 봅니다. 기본은 보류(transaction.held)입니다 — 판매자가 설정 > 자동 처리 규칙에서 "늦게 온 주문 자동 확정"을 켜면 바로 확정합니다. ordered_at 을 실제 주문 시각으로 보내는 것이 이 판정의 전부입니다. 지금보다 5분 넘게 미래면 400 입니다.

되돌리기

잘못 확정한 것은 24시간 안에 POST /v1/orders/{id}/reverse 로 되돌립니다. 주문은 open, 입금은 unmatched 가 되고 order.payment_reversed(data.previous_payment 에 되돌린 매칭)가 납니다. 24시간이 지나면 API 로는 안 되고(409 reverse_window_passed) 판매자 화면에서만 됩니다. 판매자가 화면에서 되돌려도 같은 이벤트가 오니, 받는 쪽은 order.paid 뒤에 다시 열릴 수 있다고 보고 만듭니다.

주문을 고치면

PATCH /v1/orders/{id} 로 금액 · 입금자명을 바꿔도 이미 들어온 입금을 다시 보지 않습니다. 다음 입금부터 적용됩니다. metadata 는 보내면 통째로 바뀝니다(merge 가 아닙니다) — 지우려면 {}.

주문 상태

status뜻
open입금을 기다림
paid입금으로 결제 확정 — payment 에 어떤 입금인지
paid_outside현장 결제 · 다른 수단 — mark-paid 또는 쇼핑몰이 알림. payment.transaction_id 는 null
canceled취소. open · expired 에서만 갈 수 있고, paid 는 먼저 되돌려야 합니다
expired마감이 지남. 입금이 오면 보류 후보로는 뜹니다(자동 확정은 안 함). 취소할 수 있습니다

closed_at 은 open 을 떠난 시각입니다. 쇼핑몰(카페24 등)에서 들어온 주문(source: "shop")은 몰이 정본이라 API 로 고치거나 취소할 수 없습니다(409 order_not_open).

적지 말 것

  • metadata 에 전화번호 · 주소 같은 개인정보를 넣지 마세요. 우리는 읽지 않지만 30일 동안 이벤트에 남습니다
  • payer_name 은 매칭에 필요한 입금자명만 — 구매자 연락처는 받지 않습니다