2023년 7월 14일 ・ 읽는 시간 13분
가상계좌를 연동한 뒤 웹훅이 꼭 필요한 이유와, 웹훅으로 입금 알림을 받을 수 있는 방법을 알아봅니다.
가상계좌는 결제 과정이 다른 결제수단과 다르기 때문이에요. 결제 요청과 동시에 결제가 시도되는 다른 결제수단과 달리, 가상계좌 결제는 구매자에게 먼저 가상계좌를 발급합니다. 구매자가 가상계좌 결제를 요청하면, 구매자 이름으로 계좌가 발급되고 직접 해당 계좌에 주문 금액을 정확히 입금하면 결제가 완료됩니다.
즉, 가상계좌는 구매자가 결제를 완료하는 시점을 직접 결정하는 결제수단입니다. 따라서 가맹점에서는 이 시점을 알기 위해 웹훅 연동을 해야합니다. 아래 흐름도로 살펴보면 가맹점이 7번 '입금 통보', 즉 토스페이먼츠 서버에 구매자가 입금을 했다는 통보를 받기 위함이죠. 입금 통보를 받고 나면 이어서 구매자에게 서비스와 제품을 제공할 수 있습니다. 더 자세한 내용은 가상계좌 용어사전에서 확인해보세요.
가상계좌 웹훅을 연동하고 ‘입금 완료’ 웹훅 이벤트를 받는 방법을 알아봅니다.
결제위젯 샘플 프로젝트를 사용해서 가상계좌를 연동할게요. 샘플 프로젝트를 클론하고 해당 폴더로 이동합니다.
사용하고 싶은 언어의 폴더로 들어가서 내 결제위젯 클라이언트 키, 시크릿 키를 입력하세요.
내 클라이언트 키, 시크릿 키는 개발자센터에서 확인할 수 있습니다. 이제 웹훅을 본격적으로 연동할 준비가 됐습니다.
웹훅 이벤트 본문을 받고 싶은 /hook
엔드포인트를 아래와 같이 만들어주세요.
성공 응답 코드는 반드시 보내줘야 합니다. 토스페이먼츠 서버는 가맹점에서 보내준 상태 코드가 HTTP 2xx
인지 확인하고 웹훅이 정상적으로 전송된 것을 판단하기 때문입니다. HTTP 2xx
상태 코드가 없다면 계속해서 웹훅이 재전송되고, 7회까지 재전송에 실패하면 웹훅 상태가 '실패'로 변경됩니다.
이제 샘플 프로젝트를 실행하세요. 로컬 환경에서 주문서 화면이 보이면 프로젝트가 잘 실행된 것입니다.
이제 내 로컬 프로젝트 주소를 웹훅으로 등록해서 테스트 해 볼 차례입니다. 웹훅은 로컬 개발 환경은 외부에서 접근할 수 없기 때문에 로컬 서버를 노출해주는 ngrok 같은 도구를 사용해야 합니다.
현재 환경에 맞게 ngrok을 설치합니다.
설치가 잘 되었다면 터미널에서 현재 로컬 개발 환경에 열린 포트번호를 포함해 ngrok http 8080
명령어를 실행하세요. 그러면 아래와 같은 화면이 나옵니다.
Forwarding 항목을 보겠습니다. https://{NGROK_TEST_DOMAIN}.ngrok.io
와 같은 링크가 생성된 것을 알 수 있습니다. 이 링크가 외부에서 http://localhost:8080
에 접근하는데 사용할 수 있도록 제공된 링크라는 것이 화살표로 표기되어 있습니다. 즉, 생성된 링크로 들어가면 내 로컬 환경과 똑같이 주문서 화면이 뜹니다.
이 링크 뒤에 /hook
을 추가하면 아까 서버에 등록한 웹훅의 엔드포인트와 연결됩니다. https://acd8-2001-2d8-ef3d-27b9-8886-a828-e1a9-99ea.ngrok.io/hook
과 같은 형태입니다.
이렇게 만든 웹훅 엔드포인트를 개발자센터에 등록합니다. 웹훅 엔드포인트를 가리키는 이름, 엔드포인트를 입력하고 가상계좌 입금 이벤트를 받을 수 있는 DEPOSIT_CALLBACK
이벤트를 등록하면 됩니다.
이제 테스트로 가상계좌 입금을 한 뒤 웹훅 이벤트를 받을 차례입니다. 샘플 프로젝트를 띄운 http://localhost:8080
로 이동하면 주문서 페이지가 나옵니다. 결제수단으로 가상계좌를 선택하고 임의 환불 계좌 정보를 넣어주세요. 결제하기 버튼을 누르고 결제창에서 가상계좌를 발급받을 은행을 선택하고 가상계좌를 발급 받으세요.
테스트 가상계좌 결제는 입금처리와 취소를 개발자센터에서 직접 테스트 해 볼 수 있습니다. 개발자센터 테스트 결제내역에서 입금처리를 할게요.
테스트 입금처리가 완료되면 아래와 같이 콘솔에 이벤트 본문이 찍히고 내 서버에서 성공 응답을 잘 보낸 것을 확인할 수 있습니다.
웹훅 이벤트가 토스페이먼츠에서 보낸 정상적인 이벤트인지 확인하기 위해 필요한 값이에요. 결제를 완료하면 돌아오는 응답에 secret
값이 있어요. 해당 시크릿 값과 웹훅 이벤트 본문의 secret
값을 비교해보세요. 두 값이 같다면 토스페이먼츠에서 보낸 이벤트가 맞고 믿을 수 있는 정보예요. 하지만 만약 두 값이 다르다면, 불분명한 제3자가 보낸 데이터이며 정확하지 않은 정보예요.
개발자센터에서도 웹훅 전송 기록에 성공 내역이 찍힌 것을 확인할 수 있습니다. 이벤트 발생 시간을 선택하면 이벤트 본문 기록도 볼 수 있습니다.
웹훅 전송에 실패했다면 "다시 시도" 버튼으로 웹훅을 다시 전송할 수 있습니다. 최대 7회까지 다시 시도할 수 있고, 7회 이후에도 실패한다면 웹훅 상태가 '실패'로 변경됩니다.
라이브 환경이라면 웹훅으로 가상계좌 입금 알림을 받은 뒤 구매자에게 상품을 발송하는 등 다음 단계를 진행하세요.
테스트를 끝냈다면 라이브 환경에서 웹훅을 연동해보세요. 라이브 환경에서는 아래 세 가지를 꼭 확인하세요.
✔️ 토스페이먼츠의 IP 주소를 방화벽에서 허용해주세요.
✔️ 웹훅 이벤트 전송에 실패하면 최대 7회까지 다시 전송을 시도해요.
✔️ 가상계좌 결제 상태가 DONE
에서 WAITING_FOR_DEPOSIT
으로 바뀌면 구매자에게 재입금 안내가 필요해요.
WAITING_FOR_DEPOSIT
상태에서는 구매자가 가상계좌에 입금을 완료하거나 입금할 때 오류가 발생한 경우, 입금 기한이 만료된 경우 세 가지 케이스로 이어질 수 있습니다. 각각의 상태 변화에 대해 자세히 알아봅니다.
WAITING_FOR_DEPOSIT
상태는 발급한 가상계좌에 구매자가 입금하기를 기다리고 있는 상태입니다. 이 상태에서 가능한 네 가지 케이스는 입금 완료, 입금 오류, 입금 기한 만료, 입금 전 취소입니다.
- 입금 완료: 첫 번째는 입금이 성공적으로 완료되어 상태가
DONE
으로 변경되는 경우입니다. 웹훅이 전송됩니다. - 입금 오류: 두 번째는
WAITING_FOR_DEPOSIT
으로 상태가 되돌아가는 경우로, 구매자가 입금할 때 오류가 발생했을 때의 상태 변화입니다. 웹훅이 전송됩니다. - 입금 기한 만료: 구매자가 가상계좌에 입금을 완료하지 않아 입금 기한이 만료되어
WAITING_FOR_DEPOSIT
상태가 유지되는 경우입니다. 웹훅이 전송되지 않습니다. - 입금 전 취소: 구매자가 가상계좌에 입금하기 전에 결제를 취소해서 상태가
CANCELED
가 되는 경우입니다. 웹훅이 전송됩니다.
입금 기한이 만료됐을 때는 상태 변경이 일어나지 않았기 때문에 웹훅이 전송되지 않습니다. 가상계좌를 발급할 때 설정한 기한을 저장해두고 기한이 만료되기 전에 구매자에게 재입금 안내를 해주세요.
구매자가 가상계좌에 입금을 아직 안 했다면, 결제를 취소해도 환불해야 되는 금액이 없기 때문에 refundReceiveAccount
를 추가할 필요가 없습니다. 입금 전에는 부분 취소를 할 수 없고 전체 금액 취소만 할 수 있습니다. 발급된 가상계좌의 입금 금액을 바꿀 수 없기 때문입니다. 구매자가 입금하기 전에 취소된 가상계좌는 더 이상 사용할 수 없습니다.
구매자가 가상계좌에 입금한 후에 결제를 취소하려면 환불을 위해 구매자의 환불계좌 정보가 필요합니다. 환불계좌의 은행명, 계좌번호, 예금주 정보를 직접 입력 받아야 합니다. refundReceiveAccount
에 환불받을 구매자의 계좌 정보를 포함해서 결제 취소를 요청하세요. 환불 계좌의 번호와 예금주의 유효성이 확인되면 해당 계좌로 취소 금액이 환불됩니다.
응답은 다른 취소 요청과 동일하게 Payment 객체의 cancels
로 돌아옵니다.
토스페이먼츠는 가상계좌 결제를 환불할 때 계좌의 유효성을 검사합니다. 은행명, 계좌번호, 예금주 정보가 일치해야만 환불이 정상적으로 됩니다. 정보가 일치하지 않으면 INVALID_REFUND_ACCOUNT_INFO
, INVALID_REFUND_ACCOUNT_NUMBER
와 같은 에러가 발생합니다. 환불이 실패했을 때는 구매자에게 환불 계좌 정보를 다시 입력 받아야 합니다.
Writer 한주연 Graphic 이은호, 이나눔
📍 함께 읽으면 좋을 콘텐츠