일단 토스 페이먼트 개발자 센터에서 회원가입을 하고, Toss PG 와 통신할 때 필요한 두가지의 key를 발급받는다.
클라이언트 → 서버
POST /api/v1/pays/{orderId}
클라이언트는 서버에게 결제 요청을 보낸다.
서버 → 클라이언트
서버는 주문의 유효성을 검증한 후, 클라이언트에게 Toss 와 통신할 때 필요한 데이터를 가공해서 응답한다.
→ 필요한 데이터는 다음과 같다.
{
orderId: "hcA0EkL6e0IRhmwjEHpta", // 주문 ID(직접 만들어주세요)
orderName: "토스 티셔츠 외 2건", // 주문명
successUrl: "<https://my-store.com/success>", // 결제에 성공하면 이동하는 페이지(직접 만들어주세요)
failUrl: "<https://my-store.com/fail>", // 결제에 실패하면 이동하는 페이지(직접 만들어주세요)
customerEmail: "[email protected]",
customerName: "김토스"
}
orderId : 주문을 구분할 수 있는 식별자
(우리프로젝트에서는 현재 uuid를 사용)
orderName : 주문의 대표 이름 ex) “신라면 외 7개”
successUrl : 결제가 성공했을 때 해당 url로 리다이렉트 된다. 추가적으로 Toss PG는 결제가 관련된 데이터를 네 가지의 파라미터를 넘겨준다.
{successUrl}?paymentKey={PAYMENT_KEY}&orderId={ORDER_ID}&amount={AMOUNT}&paymentType={PAYMENT_TYPE}
failUrl : 결제가 실패했을 때 해당 url로 리다이렉트 된다.
{failUrl}?code={ERROR_CODE}&message={ERROR_MESSAGE}&orderId={ORDER_ID}
그 다음은 클라이언트와 toss PG 둘만의 쿵짝 통신 타임~
클라이언트는 서버에서 받은 데이터와 toss에서 발급받은 client key를 사용해서 toss PG에게 결제 요청을 한다.

결제가 성공했을 경우, 서버에서 응답해줬던 successUrl로 리다이렉트 된다.
(즉, successUrl 로 GET 요청이 온다)

이제 서버는 GET요청과 함께 넘어온 파라미터를 통해 결제가 성공한게 맞는 지, Toss PG에 요청을 보내 결제를 승인해야한다.
(클라이언트와 PG사가 둘이 쿵짝한거라 서버는 무슨일이 벌어졌는지 전혀 알 수 없다)
서버에서도 마찬가지로 파라미터로 넘어온 값과 아까 toss에서 발급받은 secret Key를 사용해서 toss PG에게 승인 요청을 한다.
POST <https://api.tosspayments.com/v1/payments/confirm>
주의할 점 : secretKey 뒤에 “:” 를 추가한 후, base64로 인코딩을 해야함
(”:” 를 빠트릴 경우 결제승인 요청이 정상적으로 되지 않음!!)
결제 승인 요청을 간단히 나타내면 다음과 같다.
(실제 프로젝트에서는 RestTemplate을 사용)
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("<https://api.tosspayments.com/v1/payments/confirm>"))
.header("Authorization", "Basic BASE64로 인코딩한 secretKey")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\\"paymentKey\\":\\"{PAYMENT_KEY}\\",\\"amount\\":15000,\\"orderId\\":\\"hcA0EkL6e0IRhmwjEHpta\\"}"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
결제 완료 후 응답 확인한다.
위의 과정에서 Toss PG에 결제 승인 요청을 하면 다음과 같은 응답이 도착한다.
서버는 이 응답 데이터를 확인하여 결제가 정상적으로 진행되었는지 한번 더 확인한다.
{
"mId": "tosspayments",
"version": "2022-11-16",
"paymentKey": "OYij_0X3xrWLe8rs9fmvQ",
"status": "DONE",
"lastTransactionKey": "v1mXt99QBy3oBJRCV0fZX",
"orderId": "hcA0EkL6e0IRhmwjEHpta",
"orderName": "토스 티셔츠 외 2건",
"requestedAt": "2022-06-08T15:40:09+09:00",
"approvedAt": "2022-06-08T15:40:49+09:00",
"useEscrow": false,
"cultureExpense": false,
...
"currency": "KRW",
"totalAmount": 15000,
"balanceAmount": 15000,
"suppliedAmount": 13636,
"vat": 1364,
"taxFreeAmount": 0,
"method": "카드"
}