Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

๐Ÿ’ณ ๊ฒฐ์ œ ์„œ๋น„์Šค #10

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
9 commits
Select commit Hold shift + click to select a range
773d105
fix: log4j2 ๋ฒ„์ „ ์—…๋ฐ์ดํŠธ
AnneMayor Jan 1, 2022
a7ad360
feature: ๊ฒฐ์ œ API๋ฅผ ํ™œ์šฉํ•œ ๊ฒฐ์ œ ๊ธฐ๋Šฅ ๊ตฌํ˜„
AnneMayor Jan 1, 2022
dd5722d
chore: ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ ์ดํ›„์—๋„์กด์žฌํ•˜๋Š” log4j2 ๋ณด์•ˆ ์ทจ์•ฝ์  ์ด์Šˆ๋กœ ์ธํ•œ logging ๋ชจ๋“ˆ ๊ต์ฒด(log4j2 ->โ€ฆ
AnneMayor Feb 6, 2022
3e03967
chore: ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ์œ„ํ•œ method naming ๋ฆฌํŒฉํ† ๋ง ๋ฐ @Value ์–ด๋…ธํ…Œ์ด์…˜ final ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์œ„ํ•œ โ€ฆ
AnneMayor Feb 6, 2022
9daedfc
Merge branch 'develop' of github.com:f-lab-edu/sago into feature-auctโ€ฆ
AnneMayor Feb 6, 2022
6a3a9ba
refactor: ๋ถˆํ•„์š”ํ•œ @Setter ์–ด๋…ธํ…Œ์ด์…˜ ์‚ญ์ œ ๋ฐ final ๋ถˆ๋ณ€ ๊ฐ์ฒด ํ•„๋“œ ์„ ์–ธ
AnneMayor Feb 6, 2022
5f95e59
chore: ์ž˜๋ชป commit๋œ ์ฝ”๋“œ ์‚ญ์ œ(ํ…Œ์ŠคํŠธ ์ „์šฉ ์†Œ์Šค์ฝ”๋“œ ์‚ญ์ œ)
AnneMayor Feb 6, 2022
bd37cc1
Merge branch 'develop' of github.com:f-lab-edu/sago into feature-auctโ€ฆ
AnneMayor Feb 6, 2022
8bb8286
Merge branch 'develop' of github.com:f-lab-edu/sago into feature-auctโ€ฆ
AnneMayor Feb 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies {
implementation 'org.webjars.bower:vue:2.5.16'
implementation 'org.webjars.bower:axios:0.17.1'
implementation 'org.webjars:sockjs-client:1.1.2'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-mail'
Expand All @@ -47,7 +48,7 @@ dependencies {
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2', 'io.jsonwebtoken:jjwt-jackson:0.11.2'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'org.springframework.boot:spring-boot-starter-log4j2:2.6.0'
implementation 'org.springframework.boot:spring-boot-starter-log4j2:2.6.2'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logback๋„ ์žˆ๋Š”๋ฐ log4j2๋ฅผ ์‚ฌ์šฉ ํ•˜์‹  ์ด์œ ๊ฐ€ ์žˆ์œผ์‹ค๊นŒ์š”?? ์ตœ๊ทผ log4j2 ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด ์žˆ์–ด์„œ ํ•ด๋‹น ๋‚ด์šฉ๋„ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š” :)

ref:

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ๊ทธ ๋ถ€๋ถ„์€ ์ œ๊ฐ€ ์‚ฌ์‹ค ํฌ๊ฒŒ ๊ณ ๋ฏผํ•˜๊ณ  ์“ด๊ฑด ์•„๋‹ˆ๋ผ์„œ ์ด๋ฒˆ์— ๊ณ ๋ฏผํ•ด๋ณผ๊ฒŒ์š” ์ฝ”๋ฉ˜ํŠธ ๊ฐ์†จํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜„

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ทผ๋ฐ ์ด๊ฑฐ ์ €๋„ ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ ์‹œ์ผœ์ค˜์„œ ๋ณด์•ˆ ์ทจ์•ฝ์  ๋Œ€์‘ํ•œ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ ๊ทธ๋Ÿผ์—๋„ ์ทจ์•ฝํ•˜๋‹ค๊ณ  Maven Repository์—๋Š” ๋œจ๋„ค์š”... ๐Ÿ™„ ์•„์˜ˆ ๋ฐ”๊ฟ”์•ผ๊ฒ ์–ด์š” ์ด์ฐธ์—

runtimeOnly 'mysql:mysql-connector-java:8.0.22'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/dhmall/auction/dto/AuctionWinnerDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.dhmall.auction.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class AuctionWinnerDto {

private String userId;

private String productCode;

private String amount;

}
32 changes: 32 additions & 0 deletions src/main/java/com/dhmall/auction/dto/ProductDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.dhmall.auction.dto;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import java.math.BigInteger;

@Getter
@Setter
@RequiredArgsConstructor
Copy link

@f-lab-hubert f-lab-hubert Jan 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final์ธ ํ•„๋“œ๊ฐ€ ์—†์–ด์„œ ์›ํ•˜์‹œ๋Š”๋Œ€๋กœ ์ฝ”๋“œ๊ฐ€ generate๋˜์ง€ ์•Š๊ณ  ๊ธฐ๋ณธ์ƒ์„ฑ์ž๋กœ ์ƒ์„ฑ๋  ๊ฒƒ ๊ฐ™์•„์š”. dto๋Š” ๋ณดํ†ต ๋ถˆ๋ณ€๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•ด final ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ framework์—์„œ setter๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋•Œ๋ฌธ์— ์–ด์ฉ”์ˆ˜ ์—†์ด setter๋ฅผ ์ •์˜ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ์š”. ํ•ด๋‹น ๊ฒฝ์šฐ๋งŒ ์ œ์™ธํ•˜๊ณ  final ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•˜์—ฌ ๋ถˆ๋ณ€๊ฐ์ฒด๋กœ ์ด์šฉํ•˜์‹œ๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.

immutable object ref:

spring framework setter ref:

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ๋„ต๋„ต ํ•ด๋‹น ๋ถ€๋ถ„ ์ฐธ๊ณ ํ•ด์„œ ๋ฆฌํŒฉํ† ๋ง ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

public class ProductDto {

private BigInteger id;

private String code;

private String name;

private String category;

private String owner;

private int auctionStatus;

private String description;

private String createdAt;

private String updatedAt;

}
8 changes: 8 additions & 0 deletions src/main/java/com/dhmall/auction/mapper/AuctionMapper.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package com.dhmall.auction.mapper;

import com.dhmall.auction.dto.ChatMessageDto;
import com.dhmall.auction.dto.ProductDto;
import com.dhmall.user.dto.UserDto;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.math.BigInteger;

@Mapper
@Repository
public interface AuctionMapper {
void insertChatMessage(ChatMessageDto chatMessage);

UserDto selectUserById(BigInteger id);

ProductDto selectProductByCode(String productCode);
}
11 changes: 11 additions & 0 deletions src/main/java/com/dhmall/auction/service/AuctionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.dhmall.auction.dto.ChatMessageDto;
import com.dhmall.auction.dto.ChatRoomDto;
import com.dhmall.auction.dto.ProductDto;
import com.dhmall.auction.mapper.AuctionMapper;
import com.dhmall.auction.pubsub.RedisSubscriber;
import com.dhmall.user.dto.UserDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
Expand All @@ -14,6 +16,7 @@
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.math.BigInteger;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
Expand Down Expand Up @@ -65,4 +68,12 @@ public void enterChatRoom(String roomId) {
public ChannelTopic getTopic(String roomId) {
return topics.get(roomId);
}

public UserDto infoAuctionWinner(BigInteger id) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

method naming์— ์ผ๊ด€์„ฑ์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”. ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” getXX์ด๊ณ  ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ๋•Œ๋Š” infoXX์ธ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์—ฌ์„œ์š”. ์ฝ”๋“œ์˜ ์ผ๊ด€์„ฑ๋„ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์— ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋ผ์„œ์š” ใ…Žใ…Ž

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ๋„ต๋„ต ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋„ค์ด๋ฐ ๊ฐ€์ ธ๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค...ใ…Žใ…Žใ…Ž โ˜บ๏ธ

return auctionMapper.selectUserById(id);
}

public ProductDto infoAuctionProduct(String productCode) {
return auctionMapper.selectProductByCode(productCode);
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/dhmall/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ protected void configure(HttpSecurity http) throws Exception {
.antMatchers("/users/isAlreadyUsed").permitAll()
.antMatchers("/css/**", "/js/**", "/webjars/**").permitAll()
// TODO: Spring Security + JWT ์ธ์ฆ ๋กœ์ง ์ถ”๊ฐ€
.antMatchers("/**").permitAll()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ด ์„ค์ •์€ ์ „์ฒด api๋ฅผ permit์‹œ์ผœ์ฃผ๊ฒŒ ๋˜๋Š” ๊ฒƒ ์•„๋‹Œ๊ฐ€์š”??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์–ด๋จธ ์ €๊ฑฐ ์ž˜๋ชป ์˜ฌ๋ผ๊ฐ”์–ด์š”;; ๐Ÿ‘€ ์ด๊ฑฐ ์•ˆ๊ทธ๋ž˜๋„ ์ˆ˜์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค;;

.antMatchers("/auctions/**").permitAll()
.antMatchers("/chat/**").permitAll()
.antMatchers("/ws-stomp/**").permitAll()
.antMatchers("/payments/**").permitAll()
.anyRequest().authenticated()

.and()
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/dhmall/config/SpringWebEngineConfig.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.dhmall.config;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

Expand All @@ -14,4 +16,9 @@ public FreeMarkerConfigurer freemarkerConfig() {
freeMarkerConfigurer.setTemplateLoaderPath("classpath:templates/");
return freeMarkerConfigurer;
}

@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ง€๊ธˆ์€ restTemplate ์ƒ์„ฑ์‹œ default๊ฐ’์œผ๋กœ ์„ค์ •์„ ์ดˆ๊ธฐํ™” ํ•˜์ง€๋งŒ ์‹ค์ œ ์šด์˜์— ์‚ฌ์šฉ๋ ๋•Œ๋Š” ์ค‘์š” ์„ค์ •๊ฐ’์„ ์ž˜ ์‚ดํŽด๋ณด๊ณ  ์„ค์ •ํ•ด์ฃผ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด connectionPoolSize, connectionTimeout, readTimeout ๊ฐ™์€ ๊ฐ’๋“ค์ด ๊ทธ ์ค‘ ํ•˜๋‚˜ ์ผ ๊ฒƒ ๊ฐ™์•„์š” :)

ref: https://e2e2e2.tistory.com/15

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ๋„ต๋„ต ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค ์ผ๋‹จ ์ด ๋ถ€๋ถ„์€ ์ œ๊ฐ€ ์ด์Šˆ๋กœ ๋“ฑ๋กํ•ด๋†“๊ณ  ์šด์˜์—์„œ ๋Œ๋ฆด ์ ์— ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€์ ธ๊ฐ€๋ณผ๊ฒŒ์š”

}
}
54 changes: 54 additions & 0 deletions src/main/java/com/dhmall/payment/controller/PaymentController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.dhmall.payment.controller;

import com.dhmall.auction.dto.AuctionDto;
import com.dhmall.payment.dto.PaymentDto;
import com.dhmall.payment.dto.TossPayDto;
import com.dhmall.payment.service.PaymentService;
import com.dhmall.util.SagoApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.net.URI;

@RestController
@RequiredArgsConstructor
@RequestMapping("/payments/")
public class PaymentController {

private final PaymentService paymentService;
@Value("${redirect.url}")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lombok config ํŒŒ์ผ์„ ์ด์šฉํ•˜๋ฉด final ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ›„์—๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. lombok์ด ํ•ด๋‹น ์• ๋„ˆํ…Œ์ด์…˜์„ ์ƒ์„ฑ์ž์—๋„ ์ ์šฉํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ์š”. lombok.config ํŒŒ์ผ์„ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”.

ref: https://stackoverflow.com/questions/52321988/best-practice-for-value-fields-lombok-and-constructor-injection

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ๋„ต๋„ต ํ•ด๋‹น ๋งํฌ ์ฐธ๊ณ ํ•ด์„œ ๋‹ค๋ฅธ ๋ถ€๋ถ„๋“ค๋„ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค!

private String serverUrl;

@GetMapping("")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty string์„ ๊ผญ ์„ค์ •ํ•ด์ฃผ์–ด์•ผํ•˜๋‚˜์š”~?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ด๊ฑธ ์™œ ๋„ฃ์–ด์คฌ์„๊นŒ์š”...ใ…‡ใ……ใ…‡์ œ๊ฐ€ ๋ดค์„ ๋• ๊ฑ ๋‹ค๋ฅธ ํ˜ธ์ถœ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค ์žˆ๋Š”๋ฐ ์ €๊ฑฐ๋งŒ ์—†์–ด์„œ ์•„์‰ฌ์šด(?) ๋งˆ์Œ์— ์ถ”๊ฐ€ํ–ˆ๋˜๊ฑฐ ๊ฐ™์€๋ฐ...๊ฑ ์ง€์šฐ๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€์ ธ๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค;;

Copy link
Collaborator Author

@AnneMayor AnneMayor Feb 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GetMapping("request") ์ด๋ ‡๊ฒŒ ๊ฐ€์ ธ๊ฐˆ๊ฒŒ์š”!

public SagoApiResponse<AuctionDto> requestPayment(@RequestParam String chatRoomId) {
// TODO: Auction ์ฑ„ํŒ…๋ฐฉ์—์„œ Redis์—๋‹ค๊ฐ€ userId, productCode, amount ์ €์žฅํ•˜๊ธฐ
AuctionDto auctionResult = paymentService.confirmAuction(chatRoomId);
return new SagoApiResponse<>(HttpStatus.ACCEPTED, auctionResult);
}

@PostMapping("/redirect")
@ResponseBody
public String paySuccess(TossPayDto payResult) {
// TODO: API ๊ฒฐ๊ณผ๊ฐ’ redirect ์ฒ˜๋ฆฌ
return "Success!";
}

@GetMapping("success")
public ResponseEntity<TossPayDto> confirmPayment(@RequestParam String paymentKey, @RequestParam String orderId, @RequestParam BigDecimal amount) throws Exception {
TossPayDto payResult = paymentService.approvePayment(paymentKey, amount, orderId);
URI redirectUri = new URI( serverUrl + "payments/redirect");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(redirectUri);
return new ResponseEntity<>(payResult, httpHeaders, HttpStatus.OK);
}

@GetMapping("fail")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fail์‹œ์—๋Š” ๋ณ„๋„์˜ ๋กœ์ง ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”์—†๋Š”๊ฑธ๊นŒ์š”?? ๊ฒฐ์ œ์ƒํƒœ๋ฅผ ์‹คํŒจ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค๋˜์ง€ ๋“ฑ์˜ ๋กœ์ง์ด์š” ์•„๋ฌด์ฒ˜๋ฆฌ๋„ ์•ˆํ•˜๊ณ  ์‘๋‹ต๋งŒ ๋‚ด๋ ค์ฃผ๋Š” api๊ฐ€ ํ•„์š”ํ•œ๊ฑด๊ฐ€ ๊ถ๊ธˆํ•ด์„œ์š” :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ์ œ๊ฐ€ ๋กœ์ง ์ˆ˜์ •ํ•˜๋ฉด์„œ ์ € fail ์ฒ˜๋ฆฌ๋‚ฌ์„ ์ ์— ํ•ด์ค˜์•ผ ํ•˜๋Š” ์ž‘์—…์ด ์ƒˆ๋กœ ์ƒ๊ธฐ๊ธด ํ–ˆ์Šต๋‹ˆ๋‹ค ํ•ด๋‹น ๋ถ€๋ถ„ ์ˆ˜์ •ํ•ด์„œ ๊ฐ€์ ธ๊ฐ€๋ณด๋„๋ก ํ• ๊ฒŒ์š”!

public SagoApiResponse<String> failRequestPayment() {
return new SagoApiResponse<>(HttpStatus.BAD_REQUEST, "๊ฒฐ์ œ์š”์ฒญ์ด ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.");
}
}
34 changes: 34 additions & 0 deletions src/main/java/com/dhmall/payment/dto/PaymentDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.dhmall.payment.dto;

import lombok.Getter;
import lombok.Setter;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.ZonedDateTime;

@Getter
@Setter
public class PaymentDto {
private BigInteger id;

private BigInteger userId;

private String nickname;

private String productCode;

private String productName;

private BigDecimal amount;

private BigDecimal taxFreeAmount;

private BigDecimal vatAmount;

private String paymentCode;

private ZonedDateTime createdAt;

private ZonedDateTime updatedAt;
}
23 changes: 23 additions & 0 deletions src/main/java/com/dhmall/payment/dto/TossPayDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.dhmall.payment.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.math.BigDecimal;

@Getter
@Setter
@Builder
public class TossPayDto {

private String paymentKey;

private BigDecimal amount;

private BigDecimal taxFreeAmount;

private BigDecimal vatAmount;

private String message;
}
11 changes: 11 additions & 0 deletions src/main/java/com/dhmall/payment/mapper/PaymentMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.dhmall.payment.mapper;

import com.dhmall.payment.dto.PaymentDto;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface PaymentMapper {
void insertPayment(PaymentDto paymentDto);
}
99 changes: 99 additions & 0 deletions src/main/java/com/dhmall/payment/service/PaymentService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.dhmall.payment.service;

import com.dhmall.auction.dto.AuctionDto;
import com.dhmall.auction.dto.AuctionWinnerDto;
import com.dhmall.auction.dto.ProductDto;
import com.dhmall.auction.service.AuctionService;
import com.dhmall.payment.dto.TossPayDto;
import com.dhmall.payment.mapper.PaymentMapper;
import com.dhmall.user.dto.UserDto;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class PaymentService {

private final PaymentMapper paymentMapper;
private final AuctionService auctionService;
private final RedisTemplate redisTemplate;
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;

@Value("${toss.secret}")
private String TOSS_SECRET_KEY;

public TossPayDto approvePayment(String paymentKey, BigDecimal amount, String orderId) throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(TOSS_SECRET_KEY, ""); // spring framework 5.2 ์ด์ƒ ๋ฒ„์ „์—์„œ ์ง€์›
headers.setContentType(MediaType.APPLICATION_JSON);

Map<String, String> payloadMap = new HashMap<>();
payloadMap.put("orderId", orderId);
payloadMap.put("amount", String.valueOf(amount));

HttpEntity<String> request = new HttpEntity<>(objectMapper.writeValueAsString(payloadMap), headers);

ResponseEntity<JsonNode> responseEntity = restTemplate.postForEntity(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ „์— ๋ง์”€๋“œ๋ ธ๋“ฏ์ด ์™ธ๋ถ€ ์—ฐ๋™์€ ๋ณ„๋„์˜ adapter๋‚˜ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฒ˜๋ฆฌํ•˜๋Š”๊ฒŒ ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”. ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๋‹ค๋ณด๋‹ˆ PaymentService๋Š” Toss ๊ฒฐ์ œ๋งŒ์„ ์œ„ํ•œ ๊ฐ์ฒด๊ฐ€ ๋˜์–ด๋ฒ„๋ ธ๋Š”๋ฐ์š”. PaymentService ์š”๊ตฌ์กฐ๊ฑด์— ์นด์นด์˜คํŽ˜์ด ๊ฒฐ์ œ, ์นด๋“œ ๊ฒฐ์ œ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ์ˆ˜๋‹จ์ด ์ถ”๊ฐ€๋˜๋Š” ์š”๊ตฌ ์‚ฌํ•ญ์ด ์ถ”๊ฐ€๋˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋‹ค ๋œฏ์–ด๊ณ ์ณ์•ผํ•  ๊ฒƒ ๊ฐ™์•„์„œ์š”. TossPaymentClient, KakaoPaymentClient ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์™ธ๋ถ€์—ฐ๋™์„ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”. ๊ฒฐ์ œ๋ผ๋Š” ๊ฐœ๋…์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ์ฝ”๋“œ์— ๋…น์—ฌ๋‚ด๋ฉด ๋” ์ข‹์€ ์ฝ”๋“œ๊ฐ€ ๋  ๊ฒƒ ๊ฐ™์•„์š”

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ๋„ต๋„ต ํ•ด๋‹น ๋ถ€๋ถ„ ์•ˆ๊ทธ๋ž˜๋„ ์ž‘์—…ํ–ˆ๋Š”๋ฐ ์—ฌ๊ธฐ ๋ถ€๋ถ„์—๋‹ค ๊ฐ™์ด ๋จธ์ง€ํ•ด์„œ ์˜ฌ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค~

"https://api.tosspayments.com/v1/payments/" + paymentKey, request, JsonNode.class);

if(responseEntity.getStatusCode() == HttpStatus.OK) {

JsonNode body = responseEntity.getBody();

TossPayDto payResult = TossPayDto.builder()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์ฑ…์ž„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์•„์š”.

  1. header setting
  2. payload๋ฅผ json serialize
  3. toss ๊ฒฐ์ œ ์—ฐ๋™
  4. response๋ฅผ dto๋กœ parsing

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด ์œ„์˜ ๋‚ด์šฉ๋“ค์ด ๋‹ค ํ…Œ์ŠคํŠธํ•ด์•ผํ•˜๋Š”๋ฐ ํ…Œ์ŠคํŠธํ•˜๊ธฐ๊ฐ€ ์‰ฌ์›Œ๋ณด์ด์ง„ ์•Š์•„์„œ์š”. 2๋ฒˆ์€ JsonUtils ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ json handling์˜ ์ฑ…์ž„์„ ์˜ฎ๊ฒจ์ค„์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”. json handling์„ jackson์˜ ObjectMapper๊ฐ€ ์•„๋‹ˆ๋ผ Gson์œผ๋กœ๋„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ json handling์ด ํ•˜๋‚˜์˜ ๊ตฌํ˜„์ฒด์™€ ๋„ˆ๋ฌด ๊ฐ•๊ฒฐํ•ฉ ๋˜์–ด์žˆ๋Š” ๊ฒƒ ๊ฐ™์•„์š”. json๋„ ๊ตฌํ˜„์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฐ์ดํ„ฐ ํฌ๋งท์˜ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜„์ฒด๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š” jackson์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ObjectMapper๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ๋‹ค ๋ฐ”๊ฟ”์ค˜์•ผํ•˜๋Š”๋ฐ ๊ฐ€๋Šฅํ• ๊นŒ์š”?? JsonUtils ์—์„œ json์„ handlingํ•ด์ค€๋‹ค๋ฉด JsonUtils๋งŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด ์ฃผ๋ฉด ๋˜์–ด์„œ ์ฝ”๋“œ๊ฐ€ ์ข€ ๋” ์œ ์—ฐํ•ด์งˆ ์ˆ˜ ์žˆ์–ด์š”. ์ด์™€๊ฐ™์ด Toss ์—ฐ๋™๋„ PaymentClient๋ฅผ interface๋กœ ๋งŒ๋“ค์–ด๋‘๊ณ  ๊ฒฐ์ œ ๊ฐœ๋…์„ ์ถ”์ƒํ™”ํ•˜๊ณ  ๊ตฌํ˜„์ฒด๋Š” ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉด ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„ ๋„ต๋„ต!์•ˆ๊ทธ๋ž˜๋„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๋Š”๋ฐ ๋ฆฌํŒฉํ† ๋ง ํ•ด์•ผํ•  ๊ฒƒ์œผ๋กœ ํŒ๋‹จ์ด ๋˜๋”๋ผ๊ตฌ์š” ์ฐธ๊ณ ํ•ด์„œ ์ž‘์—…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค~!

.paymentKey(body.get("paymentKey").asText())
.amount(new BigDecimal(body.get("totalAmount").asText()))
// TEST api key๋กœ๋Š” ํ•ด๋‹น index json response ๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š์Œ(null).
// .taxFreeAmount(new BigDecimal(body.get("suppliedAmount").asText()))
// .vatAmount(new BigDecimal(body.get("vat").asText()))
.message("๊ฒฐ์ œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.")
.build();

return payResult;
}

TossPayDto payResult = TossPayDto.builder()
.paymentKey("")
.amount(new BigDecimal(0))
.taxFreeAmount(new BigDecimal(0))
.vatAmount(new BigDecimal(0))
.message("๊ฒฐ์ œ ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.")
.build();

return payResult;
}

public AuctionDto confirmAuction(String chatRoomId) {
// TODO: Auction ์ฑ„ํŒ…๋ฐฉ์—์„œ Redis์—๋‹ค๊ฐ€ userId, productCode, amount ์ €์žฅํ•˜๊ธฐ
AuctionWinnerDto winner = (AuctionWinnerDto) redisTemplate.opsForValue().get(chatRoomId);

UserDto user = auctionService.infoAuctionWinner(new BigInteger(winner.getUserId()));
ProductDto product = auctionService.infoAuctionProduct(winner.getProductCode());

AuctionDto auctionInfo = new AuctionDto();
auctionInfo.setUserId(user.getId());
auctionInfo.setNickname(user.getNickname());
auctionInfo.setProductCode(product.getCode());
auctionInfo.setProductName(product.getName());
auctionInfo.setAmount(new BigDecimal(winner.getAmount()));
auctionInfo.setDescription(product.getDescription());
auctionInfo.setCreatedAt(ZonedDateTime.now(ZoneId.of("UTC")));
auctionInfo.setUpdatedAt(ZonedDateTime.now(ZoneId.of("UTC")));

return auctionInfo;
}
}
Loading