Skip to content

Commit

Permalink
Merge pull request #21 from 9oormthon-univ/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
HyunWoo9930 authored Nov 18, 2024
2 parents ba8331b + 0a5b3f0 commit 4b95a7a
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 133 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package com.jangburich.domain.payment.application;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import com.jangburich.domain.payment.domain.PaymentChargeStatus;
import com.jangburich.domain.payment.domain.TeamChargeHistory;
import com.jangburich.domain.payment.domain.repository.TeamChargeHistoryRepository;
Expand All @@ -9,116 +20,114 @@
import com.jangburich.domain.payment.exception.TeamNotFoundException;
import com.jangburich.domain.team.domain.Team;
import com.jangburich.domain.team.domain.repository.TeamRepository;
import java.util.HashMap;
import java.util.Map;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

@Service
@RequiredArgsConstructor
public class KakaopayService implements PaymentService {

private final TeamChargeHistoryRepository teamChargeHistoryRepository;
@Value("${kakaopay.secretKey}")
private String secretKey;
private final TeamChargeHistoryRepository teamChargeHistoryRepository;
@Value("${kakaopay.secretKey}")
private String secretKey;

@Value("${kakaopay.approve-url}")
private String approvalUrl;

@Value("${kakaopay.cancel-url}")
private String cancelUrl;

@Value("${kakaopay.approve-url}")
private String approvalUrl;
@Value("${kakaopay.fail-url}")
private String failUrl;

@Value("${kakaopay.cancel-url}")
private String cancelUrl;
private final TeamRepository teamRepository;

@Value("${kakaopay.fail-url}")
private String failUrl;
private ResponseEntity<ReadyResponse> readyResponseResponseEntity;
private String userId;

private final TeamRepository teamRepository;
@Override
public String getType() {
return "kakao";
}

@Override
public String getType() {
return "kakao";
}
@Transactional
@Override
public ReadyResponse payReady(Long userId, PayRequest payRequest) {
this.userId = String.valueOf(userId);

@Transactional
@Override
public ReadyResponse payReady(Long userId, PayRequest payRequest) {
Map<String, String> parameters = new HashMap<>();
Map<String, String> parameters = new HashMap<>();

parameters.put("cid", "TC0ONETIME"); // ๊ฐ€๋งน์  ์ฝ”๋“œ(ํ…Œ์ŠคํŠธ์šฉ)
parameters.put("partner_order_id", "1234567890"); // ์ฃผ๋ฌธ๋ฒˆํ˜ธ
parameters.put("partner_user_id", String.valueOf(userId)); // ํšŒ์› ์•„์ด๋””
parameters.put("item_name", "ITEM_NAME"); // ์ƒํ’ˆ๋ช…
parameters.put("quantity", "1"); // ์ƒํ’ˆ ์ˆ˜๋Ÿ‰
parameters.put("total_amount", payRequest.totalAmount()); // ์ƒํ’ˆ ์ด์•ก
parameters.put("tax_free_amount", "0"); // ์ƒํ’ˆ ๋น„๊ณผ์„ธ ๊ธˆ์•ก
parameters.put("approval_url", approvalUrl); // ๊ฒฐ์ œ ์„ฑ๊ณต ์‹œ URL
parameters.put("cancel_url", cancelUrl); // ๊ฒฐ์ œ ์ทจ์†Œ ์‹œ URL
parameters.put("fail_url", failUrl); // ๊ฒฐ์ œ ์‹คํŒจ ์‹œ URL
parameters.put("cid", "TC0ONETIME"); // ๊ฐ€๋งน์  ์ฝ”๋“œ(ํ…Œ์ŠคํŠธ์šฉ)
parameters.put("partner_order_id", "1234567890"); // ์ฃผ๋ฌธ๋ฒˆํ˜ธ
parameters.put("partner_user_id", String.valueOf(userId)); // ํšŒ์› ์•„์ด๋””
parameters.put("item_name", "ITEM_NAME"); // ์ƒํ’ˆ๋ช…
parameters.put("quantity", "1"); // ์ƒํ’ˆ ์ˆ˜๋Ÿ‰
parameters.put("total_amount", payRequest.totalAmount()); // ์ƒํ’ˆ ์ด์•ก
parameters.put("tax_free_amount", "0"); // ์ƒํ’ˆ ๋น„๊ณผ์„ธ ๊ธˆ์•ก
parameters.put("approval_url", approvalUrl); // ๊ฒฐ์ œ ์„ฑ๊ณต ์‹œ URL
parameters.put("cancel_url", cancelUrl); // ๊ฒฐ์ œ ์ทจ์†Œ ์‹œ URL
parameters.put("fail_url", failUrl); // ๊ฒฐ์ œ ์‹คํŒจ ์‹œ URL

HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(parameters, this.getHeaders());
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(parameters, this.getHeaders());

RestTemplate template = new RestTemplate();
String url = "https://open-api.kakaopay.com/online/v1/payment/ready";
RestTemplate template = new RestTemplate();
String url = "https://open-api.kakaopay.com/online/v1/payment/ready";

ResponseEntity<ReadyResponse> readyResponseResponseEntity = template.postForEntity(url, requestEntity,
ReadyResponse.class);
readyResponseResponseEntity = template.postForEntity(url, requestEntity,
ReadyResponse.class);

Team team = teamRepository.findById(payRequest.teamId())
.orElseThrow(() -> new TeamNotFoundException());
Team team = teamRepository.findById(payRequest.teamId())
.orElseThrow(() -> new TeamNotFoundException());

TeamChargeHistory teamChargeHistory = TeamChargeHistory.builder()
.transactionId(readyResponseResponseEntity.getBody().tid())
.paymentAmount(Integer.valueOf(payRequest.totalAmount()))
.paymentChargeStatus(PaymentChargeStatus.PENDING)
.team(team)
.build();
TeamChargeHistory teamChargeHistory = TeamChargeHistory.builder()
.transactionId(readyResponseResponseEntity.getBody().tid())
.paymentAmount(Integer.valueOf(payRequest.totalAmount()))
.paymentChargeStatus(PaymentChargeStatus.PENDING)
.team(team)
.build();

teamChargeHistoryRepository.save(teamChargeHistory);
teamChargeHistoryRepository.save(teamChargeHistory);

return readyResponseResponseEntity.getBody();
}
return readyResponseResponseEntity.getBody();
}

@Transactional
@Override
public ApproveResponse payApprove(Long userId, String tid, String pgToken) {
Map<String, String> parameters = new HashMap<>();
parameters.put("cid", "TC0ONETIME"); // ๊ฐ€๋งน์  ์ฝ”๋“œ(ํ…Œ์ŠคํŠธ์šฉ)
parameters.put("tid", tid); // ๊ฒฐ์ œ ๊ณ ์œ ๋ฒˆํ˜ธ
parameters.put("partner_order_id", "1234567890"); // ์ฃผ๋ฌธ๋ฒˆํ˜ธ
parameters.put("partner_user_id", String.valueOf(userId)); // ํšŒ์› ์•„์ด๋””
parameters.put("pg_token", pgToken); // ๊ฒฐ์ œ์Šน์ธ ์š”์ฒญ์„ ์ธ์ฆํ•˜๋Š” ํ† ํฐ
@Transactional
@Override
public ApproveResponse payApprove(String pgToken) {
Map<String, String> parameters = new HashMap<>();
parameters.put("cid", "TC0ONETIME"); // ๊ฐ€๋งน์  ์ฝ”๋“œ(ํ…Œ์ŠคํŠธ์šฉ)
parameters.put("tid", readyResponseResponseEntity.getBody().tid()); // ๊ฒฐ์ œ ๊ณ ์œ ๋ฒˆํ˜ธ
parameters.put("partner_order_id", "1234567890"); // ์ฃผ๋ฌธ๋ฒˆํ˜ธ
parameters.put("partner_user_id", String.valueOf(userId)); // ํšŒ์› ์•„์ด๋””
parameters.put("pg_token", pgToken); // ๊ฒฐ์ œ์Šน์ธ ์š”์ฒญ์„ ์ธ์ฆํ•˜๋Š” ํ† ํฐ

HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(parameters, this.getHeaders());
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(parameters, this.getHeaders());

RestTemplate template = new RestTemplate();
RestTemplate template = new RestTemplate();

String url = "https://open-api.kakaopay.com/online/v1/payment/approve";
ApproveResponse approveResponse = template.postForObject(url, requestEntity, ApproveResponse.class);
String url = "https://open-api.kakaopay.com/online/v1/payment/approve";
ApproveResponse approveResponse = template.postForObject(url, requestEntity, ApproveResponse.class);

TeamChargeHistory teamChargeHistory = teamChargeHistoryRepository.findByTransactionId(tid)
.orElseThrow(() -> new NullPointerException());
TeamChargeHistory teamChargeHistory = teamChargeHistoryRepository.findByTransactionId(
readyResponseResponseEntity.getBody().tid())
.orElseThrow(() -> new NullPointerException());

teamChargeHistory.completePaymentChargeStatus();
teamChargeHistory.completePaymentChargeStatus();

Team team = teamRepository.findById(teamChargeHistory.getTeam().getId())
.orElseThrow(() -> new TeamNotFoundException());
Team team = teamRepository.findById(teamChargeHistory.getTeam().getId())
.orElseThrow(() -> new TeamNotFoundException());

team.updatePoint(teamChargeHistory.getPaymentAmount());
team.updatePoint(teamChargeHistory.getPaymentAmount());

return approveResponse;
}
return approveResponse;
}

private HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
String auth = "SECRET_KEY " + secretKey;
headers.set("Authorization", auth);
headers.set("Content-type", "application/json");
private HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
String auth = "SECRET_KEY " + secretKey;
headers.set("Authorization", auth);
headers.set("Content-type", "application/json");

return headers;
}
return headers;
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package com.jangburich.domain.payment.application;

import org.springframework.stereotype.Service;

import com.jangburich.domain.payment.application.strategy.PaymentServiceStrategy;
import com.jangburich.domain.payment.dto.request.PayRequest;
import com.jangburich.domain.payment.dto.response.ApproveResponse;
import com.jangburich.domain.payment.dto.response.ReadyResponse;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class PaymentProcessingService {

private final PaymentServiceStrategy paymentServiceStrategy;
private final PaymentServiceStrategy paymentServiceStrategy;

public ReadyResponse processPayment(Long userId, PayRequest payRequest) {
PaymentService paymentService = paymentServiceStrategy.getPaymentService(payRequest.paymentType());
return paymentService.payReady(userId, payRequest);
}
public ReadyResponse processPayment(Long userId, PayRequest payRequest) {
PaymentService paymentService = paymentServiceStrategy.getPaymentService(payRequest.paymentType());
return paymentService.payReady(userId, payRequest);
}

public ApproveResponse processSuccess(Long userId, String tid, String pgToken) {
PaymentService paymentService = paymentServiceStrategy.getPaymentService("kakao");
return paymentService.payApprove(userId, tid, pgToken);
}
public ApproveResponse processSuccess(String pgToken) {
PaymentService paymentService = paymentServiceStrategy.getPaymentService("kakao");
return paymentService.payApprove(pgToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import com.jangburich.domain.payment.dto.response.ReadyResponse;

public interface PaymentService {
String getType();
ReadyResponse payReady(Long userId, PayRequest payRequest);
ApproveResponse payApprove(Long userId, String tid, String pgToken);
String getType();

ReadyResponse payReady(Long userId, PayRequest payRequest);

ApproveResponse payApprove(String pgToken);
}
Original file line number Diff line number Diff line change
@@ -1,60 +1,57 @@
package com.jangburich.domain.payment.presentation;

import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.jangburich.domain.payment.application.PaymentProcessingService;
import com.jangburich.domain.payment.application.PaymentService;
import com.jangburich.domain.payment.dto.request.PayRequest;
import com.jangburich.domain.payment.dto.response.ApproveResponse;
import com.jangburich.domain.payment.dto.response.ReadyResponse;
import com.jangburich.domain.payment.exception.PaymentCancellationException;
import com.jangburich.domain.payment.exception.PaymentFailedException;
import com.jangburich.global.payload.ResponseCustom;
import com.jangburich.utils.parser.AuthenticationParser;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "Payment", description = "Payments API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/payments")
public class PaymentController {

private final PaymentProcessingService paymentProcessingService;

@Operation(summary = "๊ฒฐ์ œ ์ค€๋น„", description = "์นด์นด์˜คํŽ˜์ด ๋“ฑ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ์ค€๋น„ํ•œ๋‹ค.")
@PostMapping("/ready")
public ResponseCustom<ReadyResponse> payReady(
Authentication authentication,
@RequestBody PayRequest payRequest
) {
return ResponseCustom.OK(paymentProcessingService.processPayment(AuthenticationParser.parseUserId(authentication), payRequest));
}

@Operation(summary = "๊ฒฐ์ œ ์„ฑ๊ณต", description = "๊ฒฐ์ œ ์„ฑ๊ณต")
@PostMapping("/success")
public ResponseCustom<ApproveResponse> afterPayRequest(
Authentication authentication,
@RequestParam("tid") String tid,
@RequestParam("pg_token") String pgToken) {
return ResponseCustom.OK(paymentProcessingService.processSuccess(AuthenticationParser.parseUserId(authentication), tid, pgToken));
}

@Operation(summary = "๊ฒฐ์ œ ์ทจ์†Œ", description = "๊ฒฐ์ œ ์ง„ํ–‰ ์ค‘์— ์ทจ์†Œ๋˜๋Š” ๊ฒฝ์šฐ")
@GetMapping("/cancel")
public void cancel() {
throw new PaymentCancellationException();
}

@Operation(summary = "๊ฒฐ์ œ ์‹คํŒจ", description = "๊ฒฐ์ œ์— ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ")
@GetMapping("/fail")
public void fail() {
throw new PaymentFailedException();
}
private final PaymentProcessingService paymentProcessingService;

@Operation(summary = "๊ฒฐ์ œ ์ค€๋น„", description = "์นด์นด์˜คํŽ˜์ด ๋“ฑ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ์ค€๋น„ํ•œ๋‹ค.")
@PostMapping("/ready")
public ResponseCustom<ReadyResponse> payReady(Authentication authentication, @RequestBody PayRequest payRequest) {
return ResponseCustom.OK(
paymentProcessingService.processPayment(AuthenticationParser.parseUserId(authentication), payRequest));
}

@Operation(summary = "๊ฒฐ์ œ ์„ฑ๊ณต", description = "๊ฒฐ์ œ ์„ฑ๊ณต")
@GetMapping("/success")
public ResponseCustom<ApproveResponse> afterPayRequest(@RequestParam("pg_token") String pgToken) {
return ResponseCustom.OK(
paymentProcessingService.processSuccess(pgToken));
}

@Operation(summary = "๊ฒฐ์ œ ์ทจ์†Œ", description = "๊ฒฐ์ œ ์ง„ํ–‰ ์ค‘์— ์ทจ์†Œ๋˜๋Š” ๊ฒฝ์šฐ")
@GetMapping("/cancel")
public void cancel() {
throw new PaymentCancellationException();
}

@Operation(summary = "๊ฒฐ์ œ ์‹คํŒจ", description = "๊ฒฐ์ œ์— ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ")
@GetMapping("/fail")
public void fail() {
throw new PaymentFailedException();
}
}

0 comments on commit 4b95a7a

Please sign in to comment.