-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
484 additions
and
0 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
src/main/java/poomasi/domain/member/dto/response/MemberProfileResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/poomasi/domain/order/_payment/entity/PaymentState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
} |
149 changes: 149 additions & 0 deletions
149
src/main/java/poomasi/domain/order/_payment/service/PaymentService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
20
src/main/java/poomasi/domain/order/_refund/entity/Refund.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/poomasi/domain/order/_refund/entity/RefundStatus.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
33
src/main/java/poomasi/domain/order/entity/AbstractOrder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
38
src/main/java/poomasi/domain/order/entity/OrderDetails.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.