Skip to content
Merged
3 changes: 1 addition & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ dependencies {
implementation group: 'com.google.maps', name: 'google-maps-services', version: '2.2.0'

// payment
implementation 'com.github.iamport:iamport-rest-client-java:0.2.23'
implementation 'com.siot:iamport-rest-client:1.2.0'
implementation 'io.portone:server-sdk:0.17.0'

compileOnly 'org.projectlombok:lombok'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class OrderRequestDTO {
private Long userId;
private Long productId;
private PayMethod payMethod;
private BigDecimal totalPrice;
private Long totalPrice;
private String merchantUid;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,35 @@

import com.gongspot.project.common.code.status.ErrorStatus;
import com.gongspot.project.common.exception.GeneralException;
import com.siot.IamportRestClient.IamportClient;
import com.siot.IamportRestClient.exception.IamportResponseException;
import com.siot.IamportRestClient.response.Payment;

import io.portone.sdk.server.payment.Payment;
import io.portone.sdk.server.payment.PaymentClient;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.concurrent.CompletionException;

@Slf4j
@Service
@RequiredArgsConstructor
public class PortoneApiService {

private IamportClient iamportClient;
private PaymentClient iamportClient;

@Value("${imp.api-key}")
private String apiKey;

@Value("${imp.store-id}")
private String storeId;

@Value("${imp.api.secretkey}")
private String secretKey;

@PostConstruct
public void init() {
this.iamportClient = new IamportClient(apiKey, secretKey);
this.iamportClient = new PaymentClient(secretKey,"https://api.portone.io", storeId);
}

/**
Expand All @@ -38,27 +39,30 @@ public void init() {
* @param impUid 클라이언트로부터 전달받은 결제 고유번호
* @param clientAmount 클라이언트가 요청한 결제 금액
*/
public void verifyPayment(String impUid, BigDecimal clientAmount) {
public void verifyPayment(String impUid, Long clientAmount) {
try {
Payment payment = iamportClient.paymentByImpUid(impUid).getResponse();
Payment payment = iamportClient.getPayment(impUid).join();

if (payment == null) {
log.error("Payment not found for impUid: {}", impUid);
if (payment instanceof Payment.Unrecognized) {
log.error("Unrecognized payment type for impUid: {}", impUid);
throw new GeneralException(ErrorStatus.PAYMENT_NOT_FOUND);
}

// 서버 DB에 저장된 금액(clientAmount)과 아임포트 서버의 실제 결제 금액(payment.getAmount()) 비교
BigDecimal portoneAmount = payment.getAmount();
if (portoneAmount.compareTo(clientAmount) != 0) {
log.error("Payment amount mismatch. Portone amount: {}, Client amount: {}", portoneAmount, clientAmount);
throw new GeneralException(ErrorStatus.PAYMENT_AMOUNT_MISMATCH);
}
if (payment instanceof Payment.Recognized recognized) {
Long portoneAmount = recognized.getAmount().getTotal();

log.info("Payment verification successful for impUid: {}", impUid);
if (portoneAmount.compareTo(clientAmount) != 0) {
log.error("Payment amount mismatch. Portone amount: {}, Client amount: {}", portoneAmount, clientAmount);
throw new GeneralException(ErrorStatus.PAYMENT_AMOUNT_MISMATCH);
}

} catch (IamportResponseException | IOException e) {
log.info("Payment verification successful for impUid: {}", impUid);
}

} catch (CompletionException e) {
log.error("Failed to verify payment with impUid: {}", impUid, e);
throw new GeneralException(ErrorStatus.PAYMENT_VERIFICATION_FAILED);
}
}
}

}
3 changes: 2 additions & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,5 @@ spring.servlet.multipart.max-request-size=10MB
# iamport payment
imp.api-key = ${IMP_API_KEY}
imp.api.secretkey = ${IMP_SECRET_KEY}
imp.imp_uid=${IMP_UID}
imp.imp_uid=${IMP_UID}
imp.store-id=${IMP_SID}