Skip to content

Commit

Permalink
Merge pull request #3 from lotteon2/LF1-302-single-payment
Browse files Browse the repository at this point in the history
Jacoco 설정 및 카카오페이 결제준비 Service, Repository Test 생성
  • Loading branch information
qwerty1434 authored Nov 23, 2023
2 parents 2bf339e + c0586e0 commit 5d5f295
Show file tree
Hide file tree
Showing 17 changed files with 416 additions and 23 deletions.
58 changes: 57 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id 'java'
id 'org.springframework.boot' version '2.7.17'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'jacoco'
}

group = 'kr.bb'
Expand Down Expand Up @@ -30,13 +31,15 @@ dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
testImplementation 'junit:junit:4.13.1'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation "org.springframework.cloud:spring-cloud-starter-bus-kafka"
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'io.github.lotteon-maven', name: 'blooming-blooms-utils', version: '0.1.0-alpha1'
implementation group: 'io.github.lotteon-maven', name: 'blooming-blooms-utils', version: '0.1.0-alpha2'
runtimeOnly 'com.h2database:h2'
}

dependencyManagement {
Expand All @@ -52,3 +55,56 @@ tasks.named('bootBuildImage') {
tasks.named('test') {
useJUnitPlatform()
}

// jacoco
jacoco {
toolVersion = '0.8.5'
}

jacocoTestCoverageVerification {
violationRules {
rule {
enabled = true
element = 'CLASS'

limit {
counter = 'BRANCH'
value = 'COVEREDRATIO'
minimum = 0.80
}
excludes = ["*.mapper*"]
}
}
}

test {
jacoco {
destinationFile = file("$buildDir/jacoco/jacoco.exec")
}
useJUnitPlatform()
finalizedBy 'jacocoTestReport'
}

jacocoTestReport {
reports {
html.required = true
}
def Qdomains = []
for (qPattern in '**/QA'..'**/QZ') {
Qdomains.add(qPattern + '*')
}
afterEvaluate {
classDirectories.setFrom(
files(classDirectories.files.collect {
fileTree(dir: it, excludes: [
"**/*Application*",
"**/*generated*",
"**/*mapper*",
"**/*Config*",
"**/*Dto*",
] + Qdomains)
})
)
}
finalizedBy 'jacocoTestCoverageVerification'
}
1 change: 1 addition & 0 deletions lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lombok.addLombokGeneratedAnnotation = true
6 changes: 2 additions & 4 deletions src/main/java/kr/bb/payment/PaymentServiceApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
@EnableEurekaClient
public class PaymentServiceApplication {

public static void main(String[] args) {
public static void main(String[] args) {
SpringApplication.run(PaymentServiceApplication.class, args);
}
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package kr.bb.payment.controller.clientcontroller;

import bloomingblooms.response.SuccessResponse;
import kr.bb.payment.dto.request.KakaopayReadyRequestDto;
import kr.bb.payment.dto.response.KakaopayReadyResponseDto;
import kr.bb.payment.service.KakaopayReadyService;
import kr.bb.payment.service.PaymentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class OrderClientController {

private final PaymentService paymentService;
private final KakaopayReadyService kakaopayReadyService;

@PostMapping("/ready")
public ResponseEntity<SuccessResponse<KakaopayReadyResponseDto>> payReady(
@RequestBody KakaopayReadyRequestDto readyRequestDto) {

KakaopayReadyResponseDto responseDto = kakaopayReadyService.kakaoPayReady(readyRequestDto);

return ResponseEntity.ok()
.body(
SuccessResponse.<KakaopayReadyResponseDto>builder()
.code(String.valueOf(HttpStatus.OK.value()))
.message(HttpStatus.OK.name())
.data(responseDto)
.build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kr.bb.payment.controller.restcontroller;

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class PaymentRestController {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package kr.bb.payment.dto.request;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class KakaopayReadyRequestDto {
private String userId;
private String orderId;
private String orderType;
private String itemName;
private int quantity;
private int totalAmount;
private int taxFreeAMount;
private boolean isSubscriptionPay;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package kr.bb.payment.dto.response;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Builder
@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class KakaopayReadyResponseDto {
private String tid;
@JsonProperty("next_redirect_pc_url")
private String nextRedirectPcUrl;
}
15 changes: 10 additions & 5 deletions src/main/java/kr/bb/payment/entity/Payment.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,30 @@
import kr.bb.payment.entity.common.BaseEntity;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "payment")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
public class Payment extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "payment_id")
private Long paymentId;

@Column(name = "user_id", unique = true, nullable = false)
@Column(name = "user_id", nullable = false)
private Long userId;

@Column(name = "order_id", unique = true, nullable = false)
private Long orderId;

@Enumerated(EnumType.STRING)
@Column(name = "orderType", nullable = false)
private String orderType;
private OrderType orderType;

@Column(name = "payment_cid", nullable = false)
private String paymentCid;
Expand All @@ -41,11 +43,14 @@ public class Payment extends BaseEntity {
private String paymentTid;

@Column(name = "payment_actual_amount", nullable = false)
private String paymentActualAmount;
private Long paymentActualAmount;

@Builder.Default
@Column(name = "payment_type", nullable = false)
private String paymentType;
private String paymentType = "MONEY";

@Builder.Default
@Enumerated(EnumType.STRING)
@Column(name = "payment_status", nullable = false)
private String paymentStatus;
private PaymentStatus paymentStatus = PaymentStatus.PENDING;
}
13 changes: 13 additions & 0 deletions src/main/java/kr/bb/payment/entity/PaymentStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package kr.bb.payment.entity;

public enum PaymentStatus {
PENDING("주문 중"),
COMPLETED("주문 완료"),
CANCELED("주문 취소");

private final String message;

PaymentStatus(String message) {
this.message = message;
}
}
19 changes: 8 additions & 11 deletions src/main/java/kr/bb/payment/entity/common/BaseEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,21 @@
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;
@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;

@LastModifiedDate
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@LastModifiedDate
@Column(name = "updated_at")
private LocalDateTime updatedAt;

@Column(name = "is_deleted")
private Boolean isDeleted;
@Column(name = "is_deleted")
private Boolean isDeleted;
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
import kr.bb.payment.entity.Payment;
import org.springframework.data.jpa.repository.JpaRepository;

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

import kr.bb.payment.dto.request.KakaopayReadyRequestDto;
import kr.bb.payment.dto.response.KakaopayReadyResponseDto;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@RequiredArgsConstructor
@Component
public class KakaopayReadyService {
private final PaymentService paymentService;

@Value("${kakao.admin}")
private String ADMIN_KEY;

@Value("${host.fronturl}")
private String FRONT_URL;

public KakaopayReadyResponseDto kakaoPayReady(KakaopayReadyRequestDto requestDto) {
String cid = requestDto.isSubscriptionPay() ? "TC0ONETIME" : "TCSUBSCRIP";

MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();

parameters.add("cid", cid);
parameters.add("partner_order_id", requestDto.getOrderId());
parameters.add("partner_user_id", requestDto.getUserId());
parameters.add("item_name", requestDto.getItemName());
parameters.add("quantity", String.valueOf(requestDto.getQuantity()));
parameters.add("total_amount", String.valueOf(requestDto.getTotalAmount()));
parameters.add("tax_free_amount", String.valueOf(requestDto.getTaxFreeAMount()));

parameters.add(
"approval_url",
FRONT_URL + "/payments/approve/" + requestDto.getOrderId() + "/" + requestDto.getUserId());
parameters.add("cancel_url", FRONT_URL + "/payments/cancel");
parameters.add("fail_url", FRONT_URL + "/payments/fail");

HttpEntity<MultiValueMap<String, String>> requestEntity =
new HttpEntity<>(parameters, this.getHeaders());

RestTemplate template = new RestTemplate();
String url = "https://kapi.kakao.com/v1/payment/ready";
KakaopayReadyResponseDto responseDto =
template.postForObject(url, requestEntity, KakaopayReadyResponseDto.class);

paymentService.savePayReadyInfo(requestDto, responseDto, cid);

return responseDto;
}

@NotNull
private HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();

String auth = "KakaoAK " + ADMIN_KEY;
headers.set("Authorization", auth);
headers.set("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
return headers;
}
}
Loading

0 comments on commit 5d5f295

Please sign in to comment.