Skip to content

Commit

Permalink
Merge pull request #10 from marinesnow34/tossPay
Browse files Browse the repository at this point in the history
Feat: 결제 로직 구현
  • Loading branch information
marinesnow34 authored Nov 13, 2023
2 parents 4403a89 + 033d7b1 commit c748fee
Show file tree
Hide file tree
Showing 24 changed files with 338 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@EnableJpaAuditing
@SpringBootApplication
public class ReadyverydemoApplication {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.readyvery.readyverydemo.src.payment;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.readyvery.readyverydemo.src.payment.dto.PaymentReq;
import com.readyvery.readyverydemo.src.payment.dto.TossPaymentRes;
import com.readyvery.readyverydemo.src.payment.dto.TossPaymentSuccessRes;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api/v1/payments")
@RequiredArgsConstructor
public class PaymentController {
private final PaymentService paymentService;

@PostMapping("/toss") // 토스 결제 요청
public ResponseEntity<TossPaymentRes> requestTossPayment(@RequestBody PaymentReq paymentReq) {
TossPaymentRes tossPaymentRes = paymentService.requestTossPayment(paymentReq);
return new ResponseEntity<>(tossPaymentRes, HttpStatus.OK);
}

@GetMapping("/toss/success") // 토스 결제 성공
public ResponseEntity<TossPaymentSuccessRes> successTossPayment(
@RequestParam String paymentKey,
@RequestParam String orderId,
@RequestParam Long amount) {

return new ResponseEntity<>(
paymentService.tossPaymentSuccess(paymentKey, orderId, amount).toTossPaymentSuccessRes(),
HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.readyvery.readyverydemo.src.payment;

import com.readyvery.readyverydemo.src.payment.dto.PaymentReq;
import com.readyvery.readyverydemo.src.payment.dto.TossPaymentRes;
import com.readyvery.readyverydemo.src.payment.dto.toss.Payments;

public interface PaymentService {
TossPaymentRes requestTossPayment(PaymentReq paymentReq);

Payments tossPaymentSuccess(String paymentKey, String orderId, Long amount);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.readyvery.readyverydemo.src.payment;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Collections;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import net.minidev.json.JSONObject;

import com.readyvery.readyverydemo.src.payment.config.TossPaymentConfig;
import com.readyvery.readyverydemo.src.payment.dto.PaymentReq;
import com.readyvery.readyverydemo.src.payment.dto.TossPaymentRes;
import com.readyvery.readyverydemo.src.payment.dto.toss.Payments;

@Service
public class PaymentServiceImpl implements PaymentService {
@Autowired
TossPaymentConfig tosspaymentConfig;

@Override
public TossPaymentRes requestTossPayment(PaymentReq paymentReq) {
Long amount = calculateTotalAmount();

return null;
}

private Long calculateTotalAmount() {
//TODO: 장바구니, 장바구니 상세에서 총 금액 계산
return 0L;
}

@Override
public Payments tossPaymentSuccess(String paymentKey, String orderId, Long amount) {
// TODO: 검증, 결제 완료 처리
Payments result = requestTossPaymentAccept(paymentKey, orderId, amount);

return null;
}

private Payments requestTossPaymentAccept(String paymentKey, String orderId, Long amount) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = makeTossHeader();
JSONObject params = new JSONObject();

params.put("amount", amount);
params.put("orderId", orderId);
params.put("paymentKey", paymentKey);

Payments result = null;
try {
result = restTemplate.postForObject(TossPaymentConfig.CONFIRM_URL,
new HttpEntity<>(params, headers),
Payments.class);
} catch (Exception e) {
throw new RuntimeException(); // 추후에 오류 수정 (이미 승인 됨)
}

return result;
}

private HttpHeaders makeTossHeader() {
HttpHeaders headers = new HttpHeaders();
String encodedAuthKey = new String(
Base64.getEncoder().encode((tosspaymentConfig.getTossSecretKey() + ":").getBytes(StandardCharsets.UTF_8)));
headers.setBasicAuth(encodedAuthKey);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
return headers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.readyvery.readyverydemo.src.payment.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import lombok.Getter;

@Configuration
@Getter
public class TossPaymentConfig {
public static final String CONFIRM_URL = "https://api.tosspayments.com/v1/payments/confirm";

@Value("${payment.toss.client_key}")
private String tossClientKey;

@Value("${payment.toss.secret_key}")
private String tossSecretKey;

@Value("${payment.toss.success_url}")
private String tossSuccessUrl;

@Value("${payment.toss.fail_url}")
private String tossFailUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.readyvery.readyverydemo.src.payment.dto;

public class PaymentReq {
private Long storeId;
private Long coupon;
//TODO: 장바구니, 장바구니 상세 추가
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.readyvery.readyverydemo.src.payment.dto;

public class TossPaymentRes {
private String payType;
private Long amount;
private String orderId;
private String orderName;
private String customerName;
private String customerEmail;
private String successUrl;
private String failUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.readyvery.readyverydemo.src.payment.dto;

public class TossPaymentSuccessDto {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.readyvery.readyverydemo.src.payment.dto;

import java.time.LocalDateTime;

import lombok.Builder;

@Builder
public class TossPaymentSuccessRes {
private String orderId;
private String orderName;
private String method;
private Long totalAmount;
private String status;
private LocalDateTime requestedAt;
private LocalDateTime approvedAt;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

import java.time.LocalDateTime;

public class Cancels {
private Long cancelAmount;
private String cancelReason;
private Long taxFreeAmount;
private Long taxExemptionAmount;
private Long refundableAmount;
private Long easyPayDiscountAmount;
private LocalDateTime canceledAt;
private String transactionKey;
private String receiptKey;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class Card {
private Long amount;
private String issuerCode;
private String acquireCode;
private String number;
private Long installmentPlanMonths;
private String approveNo;
private Boolean useCardPoint;
private String cardType;
private String ownerType;
private String aquireStatus;
private Boolean isInterestFree;
private String interestPayer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class CashReceipt {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class CashReceipts {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class Checkout {
private String url;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class Discount {
private Long amount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class EasyPay {
private String provider;
private Long amount;
private Long discountAmount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class Failure {
private String code;
private String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class GiftCertificate {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class MobliePhone {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

import java.time.LocalDateTime;

import com.readyvery.readyverydemo.src.payment.dto.TossPaymentSuccessRes;

public class Payments {
private String version;
private String paymentKey;
private String type;
private String orderId;
private String orderName;
private String mid;
private String currency;
private String method;
private Long totalAmount;
private Long balanceAmount;
private String status;
private LocalDateTime requestedAt;
private LocalDateTime approvedAt;
private Boolean useEscrow;
private String lastTransactionKey; // nullable
private Long suppliedAmount;
private Long vat;
private Boolean cultureExpense;
private Long taxFreeAmount;
private Long taxExemptedAmount;
private Cancels cancels;
private Boolean isPartialCancel;
private Card card;
private VirtualAccount virtualAccount;
private String secret;
private MobliePhone mobilePhone;
private GiftCertificate giftCertificate;
private Transfer transfer;
private Receipt receipt;
private Checkout checkout;
private EasyPay easyPay;
private String country;
private Failure failure;
private CashReceipt cashReceipt;
private CashReceipts cashReceipts;
private Discount discount;

public TossPaymentSuccessRes toTossPaymentSuccessRes() {
return TossPaymentSuccessRes.builder()
.orderId(orderId)
.orderName(orderName)
.method(method)
.totalAmount(totalAmount)
.status(status)
.requestedAt(requestedAt)
.approvedAt(approvedAt)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class Receipt {
private String url;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class Transfer {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.readyvery.readyverydemo.src.payment.dto.toss;

public class VirtualAccount {
}
6 changes: 6 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ spring.security.oauth2.client.provider.kakao.authorization-uri=https://kauth.kak
spring.security.oauth2.client.provider.kakao.token-uri=https://kauth.kakao.com/oauth/token
spring.security.oauth2.client.provider.kakao.user-info-uri=https://kapi.kakao.com/v2/user/me
spring.security.oauth2.client.provider.kakao.user-name-attribute=id
#payment
##tosspay
payment.toss.client_key=test_ck_pP2YxJ4K87By0b4RZeo0rRGZwXLO
payment.toss.secret_key=test_sk_pP2YxJ4K87BbBaQPDwEJrRGZwXLO
payment.toss.success_url=http://localhost:8080/api/v1/payment/toss/success
payment.toss.fail_url=http://localhost:8080/api/v1/payment/toss/fail

0 comments on commit c748fee

Please sign in to comment.