Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file modified .DS_Store
Binary file not shown.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ configurations {

repositories {
mavenCentral()
maven { url 'https://jitpack.io' } // 깃허브에 있는 오픈소스 프로젝트를 직접 의존성으로 가져와 사용할 수 있게 해주는 설정입니다.
}

dependencies {
Expand Down Expand Up @@ -50,6 +51,9 @@ dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation platform('software.amazon.awssdk:bom:2.20.56')
implementation 'software.amazon.awssdk:s3'
//portone
implementation 'com.github.iamport:iamport-rest-client-java:0.2.21'


}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,15 @@ public enum ErrorStatus implements BaseErrorCode {


// 공지사항 관련 응답
NOTICE_NOT_FOUND(HttpStatus.NOT_FOUND, "NOTICE4001", "공지사항이 없습니다.");
NOTICE_NOT_FOUND(HttpStatus.NOT_FOUND, "NOTICE4001", "공지사항이 없습니다."),

// 결제 관련 응답
ORDER_NOT_FOUND(HttpStatus.NOT_FOUND, "PAYMENT4001", "주문건을 찾을 수 없습니다"),
ORDER_ID_NOT_FOUND(HttpStatus.NOT_FOUND, "PAYMENT4002", "해당 주문 번호가 존재하지 않습니다"),
ORDER_PRODUCT_NOT_FOUND(HttpStatus.NOT_FOUND, "PAYMENT4003", "해당 상품을 찾을 수 없습니다."),
PRICE_NOT_OK(HttpStatus.CONFLICT, "PAYMENT4004", "결제 금액이 실제 결제 금액과 불일치합니다.(결제 금액 위변조 의심)"),
PAYMENT_NOT_PAID(HttpStatus.PAYMENT_REQUIRED, "PAYMENT4005", "결제 미완료 에러입니다.");


private final HttpStatus httpStatus;
private final String code;
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/friend/spring/apiPayload/handler/PaymentHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package friend.spring.apiPayload.handler;

import friend.spring.apiPayload.GeneralException;
import friend.spring.apiPayload.code.BaseErrorCode;

public class PaymentHandler extends GeneralException {
public PaymentHandler(BaseErrorCode code) {
super(code);
}
}
22 changes: 22 additions & 0 deletions src/main/java/friend/spring/config/IamportConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package friend.spring.config;

import com.siot.IamportRestClient.IamportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class IamportConfig {
// iamportclient를 빈으로 등록해줍니다.

@Value("${iamport.api_key}")
private String apiKey;

@Value("${iamport.api_secret}")
private String apiSecret;

@Bean
public IamportClient iamportClient() {
return new IamportClient(apiKey, apiSecret);
}
}
38 changes: 38 additions & 0 deletions src/main/java/friend/spring/domain/Order.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package friend.spring.domain;

import friend.spring.domain.common.BaseEntity;
import friend.spring.domain.enums.Product;
import lombok.*;

import javax.persistence.*;
import java.math.BigDecimal;

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)

public class Order extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Enumerated(EnumType.STRING)
private Product product; // POINT_1000, POINT_2000 일단 두개 설정해놨습니다.

@Column(nullable = false)
private BigDecimal price;
Copy link
Member

Choose a reason for hiding this comment

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

BigDecimal 타입을 처음 봐서 찾아봤는데 돈을 나타내는 자료형으로는 BigDecimal 타입이 미세한 숫자의 변동을 허용하지 않아서 더 안전하군요. 덕분에 배워갑니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

😃


@Column(nullable = false)
private String orderUid;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "payment_id")
private Payment payment;
}
73 changes: 38 additions & 35 deletions src/main/java/friend/spring/domain/Payment.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
//package friend.spring.domain;
//
//import friend.spring.domain.common.BaseEntity;
//import friend.spring.domain.enums.PaymentState;
//import lombok.*;
//
//import javax.persistence.*;
//import java.math.BigDecimal;
//
//@Entity
//@Getter
//@Builder
//@AllArgsConstructor
//@NoArgsConstructor(access = AccessLevel.PROTECTED)
//public class Payment extends BaseEntity {
//
// @Id
// @GeneratedValue(strategy = GenerationType.IDENTITY)
// private Long id;
//
// @Column(nullable = false)
// private BigDecimal amount;
//
// //주문 고유 번호
// private String merchantUid;
//
// //결제 상태
// @Enumerated(EnumType.STRING)
//
// private PaymentState paymentState;
//
//
//
//
//}
package friend.spring.domain;

import friend.spring.domain.common.BaseEntity;
import friend.spring.domain.enums.PaymentState;
import lombok.*;

import javax.persistence.*;
import java.math.BigDecimal;

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Payment extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false)
private BigDecimal price;

//결제 상태
@Enumerated(EnumType.STRING)
private PaymentState paymentState;

//주문 고유 번호
private String paymentUid;


// 상태 변경 메서드
public void changePaymentBySuccess(PaymentState paymentState, String paymentUid) {
this.paymentState = paymentState;
this.paymentUid = paymentUid;
}

}
10 changes: 5 additions & 5 deletions src/main/java/friend/spring/domain/enums/PaymentState.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//package friend.spring.domain.enums;
//
//public enum PaymentState {
// READY, PAID, FAILED, CANCEL
//}
package friend.spring.domain.enums;

public enum PaymentState {
READY, ING, PAID, CANCEL
}
6 changes: 6 additions & 0 deletions src/main/java/friend/spring/domain/enums/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package friend.spring.domain.enums;

public enum Product {
// 물건 가격 임시로 설정 ( 추후에 pm 님과 상의 후 fix )
POINT_1000, POINT_2000
}
17 changes: 17 additions & 0 deletions src/main/java/friend/spring/repository/OrderRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package friend.spring.repository;

import friend.spring.domain.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.Optional;

public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("SELECT o FROM Order o " + "LEFT JOIN FETCH o.payment p " + "LEFT JOIN FETCH o.user m " + "WHERE o.orderUid = :orderUid")
Optional<Order> findOrderAndPaymentAndMember(@Param("orderUid") String orderUid);
Comment on lines +11 to +12
Copy link
Member

Choose a reason for hiding this comment

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

중요한 건 아니고 그냥 궁금한 건데 여쭤봅니다!
jpql문을 한 라인에서 표현하는데 " " + " " 으로 분리해서 나타내신 것은 특별히 의도하신 걸까요??

제 생각에는 한 라인으로 표현한다면 그냥 하나의 " " 안에 담고,
여러 줄로 나타낼 때 분리하는 것도 좋을 것 같습니다!

Copy link
Collaborator Author

@kimdavid0521 kimdavid0521 Sep 17, 2024

Choose a reason for hiding this comment

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

복잡해서 보기 쉽게 끊어서 작성하였는데 수정하겠습니다!!


@Query("SELECT o FROM Order o " + "LEFT JOIN FETCH o.payment p " + "WHERE o.orderUid = :orderUid")
Optional<Order> findOrderAndPayment(@Param("orderUid") String orderUid);
}

7 changes: 7 additions & 0 deletions src/main/java/friend/spring/repository/PaymentRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package friend.spring.repository;

import friend.spring.domain.Payment;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PaymentRepository extends JpaRepository<Payment, Long> {
}
13 changes: 13 additions & 0 deletions src/main/java/friend/spring/service/OrderService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package friend.spring.service;

import friend.spring.domain.Order;
import friend.spring.web.dto.OrderRequestDTO;

import javax.servlet.http.HttpServletRequest;

public interface OrderService {

Long createOrder(OrderRequestDTO orderRequestDTO, HttpServletRequest request);

Order checkOrder(Long orderId);
}
81 changes: 81 additions & 0 deletions src/main/java/friend/spring/service/OrderServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package friend.spring.service;

import friend.spring.apiPayload.code.status.ErrorStatus;
import friend.spring.apiPayload.handler.PaymentHandler;
import friend.spring.apiPayload.handler.UserHandler;
import friend.spring.domain.Order;
import friend.spring.domain.Payment;
import friend.spring.domain.User;
import friend.spring.domain.enums.PaymentState;
import friend.spring.domain.enums.Product;
import friend.spring.repository.OrderRepository;
import friend.spring.repository.PaymentRepository;
import friend.spring.repository.UserRepository;
import friend.spring.security.JwtTokenProvider;
import friend.spring.web.dto.OrderRequestDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{

private final JwtTokenProvider jwtTokenProvider;
private final UserRepository userRepository;
private final PaymentRepository paymentRepository;
private final OrderRepository orderRepository;


public Long createOrder(OrderRequestDTO orderRequestDTO, HttpServletRequest request) {
Product product = null;
long price = 0L;

if(orderRequestDTO.getItemName().equals("POINT_1000")) {
product = Product.POINT_1000;
price = 1000L;
} else if (orderRequestDTO.getItemName().equals("POINT_2000")) {
product = Product.POINT_2000;
price = 2000L;
}
else {
throw new PaymentHandler(ErrorStatus.ORDER_PRODUCT_NOT_FOUND);
}

Long userId = jwtTokenProvider.getCurrentUser(request);
User user = userRepository.findById(userId).orElseThrow(() -> {
throw new UserHandler(ErrorStatus.USER_NOT_FOUND);
});

Payment payment = Payment.builder()
.price(BigDecimal.valueOf(price))
.paymentState(PaymentState.ING)
.build();

paymentRepository.save(payment);

Order order = Order.builder()
.user(user)
.price(BigDecimal.valueOf(price))
.product(product)
.orderUid(UUID.randomUUID().toString())
.payment(payment)
.build();

Order result = orderRepository.save(order);

return result.getId();
}

// 주문 체크 및 조회
@Override
public Order checkOrder(Long orderId) {
return orderRepository.findById(orderId).orElseThrow(() -> {
throw new PaymentHandler(ErrorStatus.ORDER_NOT_FOUND);
});
}

}
16 changes: 16 additions & 0 deletions src/main/java/friend/spring/service/PaymentService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package friend.spring.service;

import com.siot.IamportRestClient.response.IamportResponse;

import com.siot.IamportRestClient.response.Payment;
import friend.spring.web.dto.PaymentCallback;
import friend.spring.web.dto.PaymentResponseDTO;

public interface PaymentService {

String previewOrderUid(Long orderId);

PaymentResponseDTO previewOrderResponse(String orderUid);

IamportResponse<Payment> paymentByCallBack(PaymentCallback paymentCallback);
}
Loading