티스토리 뷰

추가적인 이슈로 인해 가상계좌 결제방식도 추가하게 되었다. 가상계좌 결제와 카드 결제의 대표적인 차이점은 결제완료시점에 있다. 카드결제의 경우 이용자의 결제 요청 후 과정 완료와 함께 결제도 완료가 된다.

반면 가상계좌의 경우 결제 요청 과정이 완료되어도 이용자가 입금할 때 까지 해당 결제는 완료되지 않는다는 것이다. 따라서 비동기적으로 이뤄지는 결제 절차에 대응하기 위해서 입금 또는 취소되는 결제 상태 변화가 발생 할 때 바로 알 수 있도록 토스페이먼츠에서 등록된 콜백 URL로 알림을 보내준다. 가맹점은 콜백 URL로 입금 완료 알림이 오면 최종적으로 결제 완료를 하게된다.

 

가상계좌 결제 흐름도

https://docs.tosspayments.com/guides/windows/virtual-account

  • 기존의 카드결제와 비교해보면 아래에 가상계좌 입금 -> 입금 완료 통보 -> 결제 결과 안내 로직이 추가된 것을 볼 수 있다. 구매자의 입금 시점을 알 수 없으므로 토스페이먼츠 측에서 입금이 되면 콜백 URL로 알림을 주게 되고 백엔드에서 해당 요청을 받으면 그때 결제가 완료되었음을 확인하고 처리하게 된다.

가상계좌 결제 방식 테스트

1. 가상계좌 결제 요청을 보내기 위한 프론트 창을 생성한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <title>결제하기</title>
    <meta charset="utf-8">
    <script src="https://js.tosspayments.com/v1"></script>
</head>
<body>
<section>
    <!-- ... -->
    <span>총 주문금액</span>
    <span>3000 원</span>
    <button id="payment-virtual-account-button">3000원 가상계좌 결제하기</button>
</section>
<script>
    var clientKey = 'test_ck_클라이언트_키'
    var tossPayments = TossPayments(clientKey)
    var button = document.getElementById('payment-virtual-account-button') // 결제하기 버튼
    button.addEventListener('click', function () {
        tossPayments.requestPayment('가상계좌', {
            amount: 3000,
            orderId: 'dd198241-3ceb-47c2-b1a8-b494b7ceddce',
            orderName: --상품명--
            customerName: '김바보',
            customerEmail: 'test1234@test.com',
            successUrl: 'http://localhost:9090/v1/api/payment/virtual/success',
            failUrl: 'http://localhost:9090/v1/api/payment/virtual/fail',
            validHours: 12,
            cashReceipt: {
                type: '소득공제',
            },
            useEscrow: false,
        })
    })
</script>
</body>
</html>
  • 카드결제와 다른 성공 시 콜백 & 실패 시 콜백 주소를 갖게 하였다.
  • requestPayemt를 보낼 때 {'가상계좌'}로 보내야 한다.
  • validHours는 입금이 유효한 제한시간을 의미하고 useEscrow는 에스크로 사용여부를 결정한다.

2. 가상계좌 결제 버튼 클릭 후 결제 진행

가상계좌 결제 버튼이 추가되었다.
일련의 결제 과정

  • 위와 같이 결제를 진행할 수 있다.

3. 결제 완료 후 성공 / 실패 시 콜백 주소로 응답 옴

성공 시 콜백

  • 카드와 구분하기 위해서 virtual을 추가해주었다.
  • 전달받는 값은 orderId, paymentKey, amount 3개로 이전 카드결제와 동일하다.

4. 전달받은 값을 이용해서 토스페이먼츠에 결제 승인 요청

요청

https://api.tosspayments.com/v1/payments/{paymentKey}

응답

응답 전문

{
    "mId": "tvivarepublica",
    "version": "1.3",
    "transactionKey": "{트랜잭션_키}",
    "paymentKey": "{페이먼트_키}",
    "orderId": "dd198241-3ceb-47c2-b1a8-b494b7ceddce",
    "orderName": --상품명--
    "method": "가상계좌",
    "status": "WAITING_FOR_DEPOSIT",
    "requestedAt": "2022-03-22T15:51:25+09:00",
    "approvedAt": null,
    "useEscrow": false,
    "cultureExpense": false,
    "card": null,
    "virtualAccount": {
        "accountNumber": "X65659014474172",
        "accountType": "일반",
        "bank": "국민",
        "customerName": "김바보",
        "dueDate": "2022-03-23T03:51:25+09:00",
        "expired": false,
        "settlementStatus": "INCOMPLETED",
        "refundStatus": "NONE"
    },
    "transfer": null,
    "mobilePhone": null,
    "giftCertificate": null,
    "cashReceipt": {
        "type": "소득공제",
        "issueNumber": "",
        "receiptUrl": "https://dashboard.tosspayments.com/receipts/cash-receipt/dd198241-3ceb-47c2-b1a8-b494b7ceddce/tvivarepublica?ref=PX",
        "amount": 3000,
        "taxFreeAmount": 0
    },
    "discount": null,
    "cancels": null,
    "secret": "ps_시크릿_값",
    "type": "NORMAL",
    "easyPay": null,
    "currency": "KRW",
    "totalAmount": 3000,
    "balanceAmount": 3000,
    "suppliedAmount": 2727,
    "vat": 273,
    "taxFreeAmount": 0
}
  • 이렇게 토스페이먼츠에게서 결제 승인 요청에 대한 응답이 오게 된다.
  • 구매자는 전달받은 VirtualAccount의 bank와 account_number를 확인해서 입급을 하면된다.

  • 전달받은 은행은 국민은행, 계좌번호는 X65659014474172 인데 X는 비활성 계좌를 의미하는듯 하다.
  • 전달받은 계좌번호로 돈을 보내려고 시도하면 "입금할 수 있는 상태의 계좌가 아니에요."라는 경고문이 뜬다.
  • 라이브 계정에서만 실제로 돈을 입금받을 수 있는 가상계좌를 알려주는방식으로 추측된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

5. 입금을 확인하고 내부적으로 결제 완료 처리를 진행한다.

  • 이 부분은 토스페이먼츠이 콜백 처리를 통해 진행된다. 가상계좌를 통해 입금이 완료되면 토스페이먼츠는 등록된 URL로 알림을 보내준다. 해당 URL은 개발정보의 기본설정에서 세팅해줄 수 있다.

입금이 완료되면

{
  "secret": "ps_ZORzdMaqN3weJkOmRgNr5AkYXQGw",
  "status": "DONE",
  "orderId": "am2hDav3qdN1Gj7dSHkoV"
}
  • 토스페이먼츠가 위 형태의 JSON 본문HTTP POST 방식으로 등록된 URL로 보내준다. 이때 status는 다양한 값을 가질 수 있으므로 해당 값에 맞는 적절한 조치를 취해야한다.
  • secret 값은 결제 승인 요청 시 반환받은 응답 데이터와 비교해서 동일하다면 해당 결제에 대한 입금임이 증명 된 것이다.

status

  • DONE : 가상계좌 입금 완료
  • CANCELED : 가상계좌 입금 취소
  • PARTIAL_CANCELED : 가상계좌 입금 부분 취소

Webhook 요청의 경우 위 형태와 조금 다르다.

{
  "eventType": "PAYMENT_STATUS_CHANGED",
  "data": {
    "paymentKey": --페이먼트_키--
    "status": "DONE",
    "orderId": "GfOBATmOF5fePBzOgPupx"
  }
}
  • webhook은 모든 결제 과정에 대해 통보해주는 역할을 한다. 따라서 결제완료 / 결제취소 / 결제 부분 취소 / 가상 계좌 입금 대기 에 대한 모든 과정을 알려준다.
    딱 입금만 위 방식으로 다른 URL에 따로 알려주는 것이다.

실제로 입금을 해보고 전달받은 응답을 처리하면 좋겠지만 아쉽게도 테스트 계정에서는 가상계좌로 입금을 진행할 수가 없다. 하지만 실제로 입금 및 취소를 한것처럼 동작하는 입금 / 취소 이벤트를 제공한다.

 

테스트 거래 내역에 들어가보면 직접 진행했던 결제 내역들이 존재한다. 이때 카드 / 가상계좌 별로 액션을 취해줄 수 가 있다. 카드의 결제 취소, 가상계좌의 입금 / 취소 처리 액션을 줘서 테스트를 진행해보자.

가상계좌 입금 알림과 이벤트 Webhook 요청은 POST 방식으로 온다. 이에 맞춰서 열어놓도록 하자. 또한 9090포트를 인바운드 규칙에 추가해줘야 요청을 받을 수 있으므로 이부분도 잊지말자.

9090 포트 인바운드 규칙 추가

요청 URL 등록

 

여기까지 가상결제를 통한 결제에 대한 일련의 과정들을 모두 정리해보았다.
이렇게 정리한 내용을 기반으로 실제 코드를 작성하면 되겠다. 다음 포스팅에서 실제로 코드를 통해 구현해보도록 하겠다.

 

 


Reference

https://docs.tosspayments.com/guides/windows/virtual-account

반응형
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday