Skip to content

Commit

Permalink
master -> review conflict 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
amm0124 committed Nov 11, 2024
2 parents 8021bea + c6864fb commit b13b1c6
Show file tree
Hide file tree
Showing 12 changed files with 484 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package poomasi.domain.member.dto.response;

import poomasi.domain.member.entity.MemberProfile;

import java.time.LocalDateTime;

public record MemberProfileResponse(
String name,
String phoneNumber,
String address,
String addressDetail,
Long coordinateX,
Long coordinateY,
boolean isBanned,
LocalDateTime createdAt
) {
public static MemberProfileResponse fromEntity(MemberProfile profile) {
return new MemberProfileResponse(
profile.getName(),
profile.getPhoneNumber(),
profile.getAddress(),
profile.getAddressDetail(),
profile.getCoordinateX(),
profile.getCoordinateY(),
profile.isBanned(),
profile.getCreatedAt()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package poomasi.domain.order._payment.entity;

public enum PaymentState {
PENDING, // 결제 대기 중
COMPLETED, // 결제 완료
FAILED, // 결제 실패
CANCELLED, // 결제 취소됨
REFUNDED, // 환불 완료
DECLINED; // 결제 거부됨

@Override
public String toString() {
// 사용자 친화적인 문자열로 반환할 수 있도록 오버라이딩
switch (this) {
case PENDING:
return "Payment Pending";
case COMPLETED:
return "Payment Completed";
case FAILED:
return "Payment Failed";
case CANCELLED:
return "Payment Cancelled";
case REFUNDED:
return "Payment Refunded";
case DECLINED:
return "Payment Declined";
default:
return super.toString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package poomasi.domain.order._payment.service;

import com.siot.IamportRestClient.IamportClient;
import com.siot.IamportRestClient.exception.IamportResponseException;
import com.siot.IamportRestClient.request.CancelData;
import com.siot.IamportRestClient.request.PrepareData;
import com.siot.IamportRestClient.response.AccessToken;
import com.siot.IamportRestClient.response.IamportResponse;
import com.siot.IamportRestClient.response.Prepare;
import jdk.jfr.Description;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import poomasi.domain.auth.security.userdetail.UserDetailsImpl;
import poomasi.domain.member.entity.Member;
import poomasi.domain.order._payment.dto.request.PaymentPreRegisterRequest;
import poomasi.domain.order._payment.dto.request.PaymentWebHookRequest;
import poomasi.domain.order._payment.dto.response.PaymentPreRegisterResponse;
import poomasi.domain.order._payment.dto.response.PaymentResponse;
import poomasi.domain.order._payment.entity.Payment;
import poomasi.domain.order._payment.repository.PaymentRepository;
import poomasi.domain.order.entity.Order;
import poomasi.domain.order.repository.OrderRepository;
import poomasi.domain.product._cart.service.CartService;
import poomasi.global.error.BusinessError;
import poomasi.global.error.BusinessException;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

import static poomasi.domain.order.entity.OrderStatus.AWAITING_SELLER_CONFIRMATION;
import static poomasi.domain.order.entity.OrderStatus.PENDING;
import static poomasi.global.error.BusinessError.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class PaymentService {

@Autowired
private final PaymentRepository paymentRepository;
private final IamportClient iamportClient;
private final OrderRepository orderRepository;
private final CartService cartService;

@Description("포트원 api 호출을 위한 accessToken 발급 메서드")
private String getPortOneAccessToken() throws IOException, IamportResponseException {
IamportResponse<AccessToken> authResponse = iamportClient.getAuth();
String accessToken = authResponse.getResponse().getToken();
return accessToken;
}

@Description("사전 결제 등록")
public PaymentPreRegisterResponse portonePrePaymentRegister(PaymentPreRegisterRequest paymentPreRegisterRequest) throws IOException, IamportResponseException {
PrepareData prepareData = new PrepareData(paymentPreRegisterRequest.merchantUid(),
paymentPreRegisterRequest.amount()
);
iamportClient.postPrepare(prepareData);
return PaymentPreRegisterResponse.from(
paymentPreRegisterRequest.merchantUid()
);
}

@Transactional
@Description("프론트에서 받아온 결과를 validate하는 메서드")
public void portoneVerifyPostPayment(PaymentWebHookRequest paymentWebHookRequest) throws IOException, IamportResponseException {
String impUid = paymentWebHookRequest.imp_uid();
String merchantUid = paymentWebHookRequest.merchant_uid();
IamportResponse<com.siot.IamportRestClient.response.Payment> iamportResponse = iamportClient.paymentByImpUid(impUid);
BigDecimal amount = iamportResponse.getResponse()
.getAmount();

Order order = orderRepository.findByMerchantUid(merchantUid)
.orElseThrow(() -> new BusinessException(ORDER_NOT_FOUND));

if(order.getOrderStatus()!=PENDING){ //이미 처리한 주문이라면
throw new BusinessException(ORDER_ALREADY_PROCESSED);
}

if(validatePaymentConsistency(order.getTotalAmount(), amount)){ //결제 금액이 맞지 않다면 -> 주문 취소 api 호출
cancelPayment(iamportResponse);
throw new BusinessException(PAYMENT_AMOUNT_MISMATCH);
}
order.setOrderStatus(AWAITING_SELLER_CONFIRMATION); // 상태 변경
cartService.removeSelected(); //장바구니 삭제
}

private boolean validatePaymentConsistency(BigDecimal prepaymentAmount, BigDecimal postPaymentAmount){
if (prepaymentAmount.compareTo(postPaymentAmount) != 0) {
return false;
}
return true;
}

@Description("payment 상세 내역 조회를 위한 단건 api 호출")
public void getPaymentDetails(String merchantUid, Long orderId) throws IOException, IamportResponseException {

}

@Description("결제 취소 api")
public void cancelPayment(IamportResponse<com.siot.IamportRestClient.response.Payment> response) throws IOException, IamportResponseException{
//true면 Uid, false면 merchantUid로 판단
CancelData cancelData = new CancelData(response.getResponse().getMerchantUid(), false);
iamportClient.cancelPaymentByImpUid(cancelData);
}

@Description("결제 환불 api")
public void processRefund() throws IOException, IamportResponseException{

}


@Description("결제 부분 환불 api 호출")
public void partialRefund() throws IOException, IamportResponseException {

}

public PaymentResponse getPayment(Long paymentId) {
Payment payment = paymentRepository.findById(paymentId)
.orElseThrow(() -> new BusinessException(PAYMENT_NOT_FOUND));
return PaymentResponse.fromEntity(payment);
}

@Description("orderID로 결제 방법 찾는 메서드")
public PaymentResponse getPaymentByOrderId(Long orderId) {
Member member = getMember();
Payment payment = paymentRepository.findById(orderId)
.orElseThrow(() -> new BusinessException(PAYMENT_NOT_FOUND));
return PaymentResponse.fromEntity(payment);
}


private Member getMember() {
Authentication authentication = SecurityContextHolder
.getContext().getAuthentication();
Object impl = authentication.getPrincipal();
Member member = ((UserDetailsImpl) impl).getMember();
return member;
}

}


20 changes: 20 additions & 0 deletions src/main/java/poomasi/domain/order/_refund/entity/Refund.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package poomasi.domain.order._refund.entity;


import jakarta.persistence.*;
import poomasi.domain.order.entity.OrderProductDetails;

@Entity
@Table(name="refund")
public class Refund {

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

/* @OneToOne(fetch = FetchType.LAZY)
private OrderProductDetails orderProductDetails;*/

private String refundReason;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package poomasi.domain.order._refund.entity;

public enum RefundStatus {
REQUESTED("환불 요청됨"),
PROCESSING("환불 처리 중"),
COMPLETED("환불 완료됨"),
REJECTED("환불 거절됨");

private final String description;

RefundStatus(String description) {
this.description = description;
}

public String getDescription() {
return description;
}
}

/*
* REQUESTED, // 반품 요청됨
APPROVED, // 반품 승인됨
REJECTED, // 반품 거부됨
RETURNED, // 상품이 반품됨
REFUNDED, // 환불 완료됨
CANCELLED, // 반품 요청이 취소됨
IN_TRANSIT // 반품이 배송 중
;
* */
33 changes: 33 additions & 0 deletions src/main/java/poomasi/domain/order/entity/AbstractOrder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package poomasi.domain.order.entity;

import jakarta.persistence.*;
import jdk.jfr.Description;
import jdk.jfr.Timestamp;
import lombok.Getter;
import org.hibernate.annotations.UpdateTimestamp;
import poomasi.domain.member.entity.Member;

import java.time.LocalDateTime;
import java.util.Date;

@MappedSuperclass
@Getter
public abstract class AbstractOrder {

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

@JoinColumn(name = "member_id")
@ManyToOne(fetch = FetchType.LAZY)
private Member member;

@Column(name = "merchant_uid")
@Description("상품당 결제 id(아임포트 id)")
private String merchantUid = "p" + new Date().getTime();

@Column(name = "created_at")
@Timestamp
private LocalDateTime createdAt = LocalDateTime.now();

}
49 changes: 49 additions & 0 deletions src/main/java/poomasi/domain/order/entity/Order.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package poomasi.domain.order.entity;


import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.List;

import static poomasi.domain.order.entity.OrderStatus.PENDING;

@Entity
@Table(name = "orders")
@Getter
@NoArgsConstructor
public class Order extends AbstractOrder{

@Column(name = "order_product_details_id")
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderProductDetails> orderProductDetails;

@OneToOne
@JoinColumn(name = "order_details_id") // 여기서 JoinColumn 사용
private OrderDetails orderDetails;

@Column(name = "total_amount")
private BigDecimal totalAmount;

@Enumerated(EnumType.STRING)
private OrderStatus orderStatus = OrderStatus.PENDING;

public Order(OrderDetails orderDetails) {
this.orderDetails = orderDetails;
}

public void addOrderDetail(OrderProductDetails orderProductDetails) {
this.orderProductDetails.add(orderProductDetails);
}
public void setOrderStatus(OrderStatus orderStatus) {
this.orderStatus = orderStatus;
}

public void setTotalAmount(BigDecimal totalAmount) {
this.totalAmount = totalAmount;
}


}
38 changes: 38 additions & 0 deletions src/main/java/poomasi/domain/order/entity/OrderDetails.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package poomasi.domain.order.entity;

import jakarta.persistence.*;
import jdk.jfr.Description;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name="order_details")
@Getter
@NoArgsConstructor
public class OrderDetails {

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

@OneToOne(mappedBy = "orderDetails")
private Order order;

@Column(name = "address")
private String address;

@Column(name = "address_detail")
private String addressDetail;

@Description("배송 요청 사항")
@Column(name = "delivery_request", length = 255)
private String deliveryRequest;

public OrderDetails(String address, String addressDetail, String deliveryRequest) {
this.address = address;
this.addressDetail = addressDetail;
this.deliveryRequest = deliveryRequest;
}


}
Loading

0 comments on commit b13b1c6

Please sign in to comment.