๐ ์ฐ๋ฆฌ ํ๋ก์ ํธ์์ ํ ์คํ์ด๋จผ์ธ ๋ฅผ ์ด์ฉํ ๊ฒฐ์ ํํธ๋ฅผ ์ด๋ป๊ฒ ๊ตฌํํ์๋์ง ์ดํด๋ณด๋ ค๊ณ ํ๋ค !
๐ <๊ฒฐ์ ํ๋ฆ ์ญํ ๋ณ ์ ๋ฆฌ>์์ 1~3๋ฒ์ ํด๋นํ๋ ๋ด์ฉ์ ๋๋ค.
๋จผ์ , ํ ์คํ์ด๋จผ์ธ ์ ๊ฐ๋ฐ์ ํ ์คํธ์ฉ API ํค๋ฅผ ๋ฐ์ ์ฌ์ฉํด์ผํ๊ธฐ ๋๋ฌธ์
ํ ์คํ์ด๋จผ์ธ ์ ๊ฐ์ ํ, ๊ฐ๋ฐ์์ฉ ํ ์คํธ์์ ์์ API ํค๋ฅผ ๋ฐ์ ์ ์๋ค.
[ํ ์คํ์ด๋จผ์ธ API ํค ๋ฐ๊ธฐ ์ฐธ๊ณ ]
์ด API ํค๋ ํ๋ฉด์ ๊ตฌ์ฑํ ๋ ํ ์คํ์ด๋จผ์ธ ๊ฒฐ์ ์ฐฝ API์ ์ฐ๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉํ ๊ฒ์ด๋ฏ๋ก
appliaction.yml
์ ์์์ ๋ฐ๊ธ๋ฐ์ ํ
์คํธ ํด๋ผ์ด์ธํธ ํค์ ํ
์คํธ ์ํฌ๋ฆฟ ํค๋ฅผ ์๋์ ๊ฐ์ด ์ ์ด์ค ํ,
TossPaymentConfig
ํด๋์ค์ @Value
์ ๋ํ
์ด์
์ ์ฌ์ฉํ์ฌ API ํค์ URL๋ค์ ๋ณ์๋ก ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ค์ด ์ค ๊ฒ์ด๋ค.
์๋ฒ์์ ๊ฒฐ์ ์ ํ์ํ ์ ๋ณด๋ฅผ ์
๋ ฅ๋ฐ์ ์ ์๋๋ก ํ๋ Controller,
์ ๋ฌ๋ฐ์ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ๊ฒ์ฆ / ํ์ํ ๊ฐ๋ค์ ์์ฑํ๋ Service,
์์ฒญ ๊ฐ๋ค์ ๊ฐ์ง๊ณ ์๋ Dto,
๊ฒฐ์ ์์ฒญ ๋ด์ญ์ผ๋ก์จ DB์ ์ ์ฅ๋ Entity,
์ ์ฅ ์ฅ์์ธ Repository๋ฅผ ๊ตฌํํ ๊ฒ์ด๋ค.
๊ฒฐ์ ํธ์ถ ์์ฒญ์ ํ๋ PaymentDto
@Setter @Getter @Builder @AllArgsConstructor @NoArgsConstructor public class PaymentDto { @NonNull private PayType payType; // ๊ฒฐ์ ํ์ - ์นด๋/ํ๊ธ/ํฌ์ธํธ @NonNull private Long amount; // ๊ฐ๊ฒฉ ์ ๋ณด @NonNull private String orderName; // ์ฃผ๋ฌธ๋ช โ private String yourSuccessUrl; // ์ฑ๊ณต ์ ๋ฆฌ๋ค์ด๋ ํธ ๋ URL private String yourFailUrl; // ์คํจ ์ ๋ฆฌ๋ค์ด๋ ํธ ๋ URL โ public Payment toEntity() { return Payment.builder() .payType(payType) .amount(amount) .orderName(orderName) .orderId(UUID.randomUUID().toString()) .paySuccessYN(false) .build(); } }
โ ์ ๊ฐ๋ค์ ํ๋ก ํธ์์ ์ ๋ ฅ๋ฐ์
์๋ต์ผ๋ก ์ฌ PaymentResDto
@Setter @Getter @Builder @AllArgsConstructor @NoArgsConstructor public class PaymentResDto { private String payType; // ๊ฒฐ์ ํ์ - ์นด๋/ํ๊ธ/ํฌ์ธํธ private Long amount; // ๊ฐ๊ฒฉ ์ ๋ณด private String orderName; // ์ฃผ๋ฌธ๋ช private String orderId; // ์ฃผ๋ฌธ Id private String customerEmail; // ๊ณ ๊ฐ ์ด๋ฉ์ผ private String customerName; // ๊ณ ๊ฐ ์ด๋ฆ private String successUrl; // ์ฑ๊ณต ์ ๋ฆฌ๋ค์ด๋ ํธ ๋ URL private String failUrl; // ์คํจ ์ ๋ฆฌ๋ค์ด๋ ํธ ๋ URL โ private String failReason; // ์คํจ ์ด์ private boolean cancelYN; // ์ทจ์ YN private String cancelReason; // ์ทจ์ ์ด์ private String createdAt; // ๊ฒฐ์ ๊ฐ ์ด๋ฃจ์ด์ง ์๊ฐ }
โ
PaymentDto
๋ก ๋ฐ์ ์ ๋ณด๋ค์ ๊ฒ์ฆ ํ, ์ค์ ํ ์คํ์ด๋จผ์ธ ์์ ๊ฒฐ์ ์์ฒญ์ ํ๊ธฐ ์ํด ํ์ํ ๊ฐ๋ค์ ํฌํจํ์ฌPaymentResDto
๋ก ๋ฐํ
Payment
@Entity @Getter @Builder @AllArgsConstructor @NoArgsConstructor @Setter @Table(indexes = { @Index(name = "idx_payment_member", columnList = "customer"), @Index(name = "idx_payment_paymentKey", columnList = "paymentKey" ), }) public class Payment extends Auditable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "payment_id", nullable = false, unique = true) private Long paymentId; @Column(nullable = false , name = "pay_type") @Enumerated(EnumType.STRING) private PayType payType; @Column(nullable = false , name = "pay_amount") private Long amount; @Column(nullable = false , name = "pay_name") private String orderName; @Column(nullable = false , name = "order_id") private String orderId; โ private boolean paySuccessYN; @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "customer") private Member customer; @Column private String paymentKey; @Column private String failReason; โ @Column private boolean cancelYN; @Column private String cancelReason; public PaymentResDto toPaymentResDto() { // DB์ ์ ์ฅํ๊ฒ ๋ ๊ฒฐ์ ๊ด๋ จ ์ ๋ณด๋ค return PaymentResDto.builder() .payType(payType.getDescription()) .amount(amount) .orderName(orderName) .orderId(orderId) .customerEmail(customer.getEmail()) .customerName(customer.getName()) .createdAt(String.valueOf(getCreatedAt())) .cancelYN(cancelYN) .failReason(failReason) .build(); } }
โ ์ค์ DB์ ์ ์ฅํ๊ฒ ๋ ๊ฒฐ์ ๊ด๋ จ ์ ๋ณด๋ค
โ ์๋ต ๊ฒฐ๊ณผ๋ก๋ ์ํฐํฐ๊ฐ ์๋ PaymentResDto ๊ฐ์ฒด๋ก ๋ฐํํจ
JpaPaymentRepository
requestTossPayment
โ ํ๋ก ํธ์์ ๊ฒฐ์ ๋ฅผ ์์ฒญํ๊ธฐ ์ํด 1์ฐจ์ ์ผ๋ก ์์ฒญํ๋ API
โ
โ ์ฌ๊ธฐ์ Service ๋ก์ง์ ํ๊ณ ๋ค์ด๊ฐ ๊ฒ์ฆ ๊ณผ์ ์ ๋ง์น๊ณ ์ ์์ ์ผ๋ก ์งํ์ด ๋๋ค๋ฉด ํ ์คํ์ด๋จผ์ธ ์ ์ค์ ๊ฒฐ์ ์์ฒญ์ ๋ณด๋
requestTossPayment
โ ๊ฒฐ์ ๋ฅผ ์ํด ์์ฒญํ ๊ฐ๋ค์ Controller๋ก๋ถํฐ ์ ๋ฌ ๋ฐ์ ๊ฒ์ฆ์ ํจ
โ
โ ์กฐ๊ฑด๋ค์ด ๋ง๋์ง ํ์ธํ๊ณ , ๋ชจ๋ ์กฐ๊ฑด๋ค์ด ๋ง๋ค๋ฉด Entity ๊ฐ์ฒด๋ก ๋ง๋ ํ DB์ ์ ์ฅํ๊ณ ๋ฐํํด์ค
๐ฉ ์ฌ๊ธฐ๊น์ง ํ๋ค๋ฉด,
ํ๋ก ํธ์์ ๊ฒฐ์ ๋ฅผ ์์ฒญํ๊ณ ๋ฐฑ์๋์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆ ํ, ๊ฒฐ์ ์์ฒญ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ฃผ๋ ๋ถ๋ถ์ด ์์ฑ๋ ๊ฒ์ด๋ค.
๊ฐ๋จํ๊ฒ h2 DB๋ก ํ์ธํด๋ณด์๋๋ฐ, ์์ฒ๋ผ ์ ๋ณด๋ค์ด ์ ๋ค์ด๊ฐ ๊ฒ์ ์ ์ ์๋ค.
์ด์ ์๋์ ๊ฐ์ ์๋ต ๊ฐ์ด ์ ์ ๋ฌ๋์์ ๋,
๊ทธ ๊ฐ๋ค์ ๊ฐ์ง๊ณ ํ ์คํ์ด๋จผ์ธ ์ ๊ฒฐ์ ์์ฒญ์ ๋ณด๋ผ ๊ฒ์ด๋ค.
{ "data": { "payType": "์นด๋", "amount": 58500, "orderName": "ํฌ์ธํธ ์ถฉ์ ", "orderId": "bec1d544-2a34-4f44-ada0-c5213d8fd8dd", "customerEmail": "test1@gmail.com", "customerName": "์ฒซ๋ฒ์งธ", "successUrl": "http://localhost:8080/api/v1/payments/toss/success", "failUrl": "http://localhost:8080/api/v1/payments/toss/fail", "failReason": null, "cancelYN": false, "cancelReason": null, "createdAt": "2023-06-06T19:25:04.432591600" } }
<!DOCTYPE html> <html lang="ha"> <head> <meta charset="utf-8" /> <title>๊ฒฐ์ ํ๊ธฐ</title> <!-- ํ ์คํ์ด๋จผ์ธ ๊ฒฐ์ ์ฐฝ SDK ์ถ๊ฐ --> <script src="https://js.tosspayments.com/v1/payment"></script> </head> <body> <section> <!-- ์ถฉ์ ํ๊ธฐ ๋ฒํผ ๋ง๋ค๊ธฐ --> <span>์ด ํฌ์ธํธ ์ถฉ์ ๊ธ์ก :</span> <span>58500์</span> <button id="payment-button">58500์ ์ถฉ์ ํ๊ธฐ</button> </section> <script> // ------ ํด๋ผ์ด์ธํธ ํค๋ก ๊ฐ์ฒด ์ด๊ธฐํ ------ var clientKey = 'ํ ์คํธ_ํด๋ผ์ด์ธํธ_ํค' var tossPayments = TossPayments(clientKey) โ // ------ ์ถฉ์ ํ๊ธฐ ๋ฒํผ์ ๊ธฐ๋ฅ ์ถ๊ฐ ------ var button = document.getElementById('payment-button') // ์ถฉ์ ํ๊ธฐ ๋ฒํผ button.addEventListener('click', function () { โ // ------ ๊ฒฐ์ ์ฐฝ ๋์ฐ๊ธฐ ------ tossPayments.requestPayment('CARD', { amount: 58500, orderId: 'bec1d544-2a34-4f44-ada0-c5213d8fd8dd', orderName: 'ํฌ์ธํธ ์ถฉ์ ', customerName: '์ฒซ๋ฒ์งธ', customerEmail: 'test1@gmail.com', successUrl: 'http://localhost:8081/api/v1/payments/toss/success', failUrl: 'http://localhost:8081/api/v1/payments/toss/fail' }) }) </script> </body> </html>
โ ์ง๊ธ์ ์ ์ ์ผ๋ก ๊ฐ์ ๋ฃ์ด์คฌ์ง๋ง, ์ค์ ๋ก๋ ์๋ฒ์ ์๋ต ๊ฐ์ ๊ฐ์ง๊ณ ํ์ฑํ๊ฒ ๋ ๊ฒ
โ
- 'ํ ์คํธ ํด๋ผ์ด์ธํธ ํค'
โ ํ ์คํธ๋ฅผ ์ํด ์ ๊ณต๋ฐ์ API ํค
โ ์ด๋ฅผ ์ด์ฉํ์ฌ TossPayments ๊ฐ์ฒด๋ฅผ ์์ฑํ์๊ณ , ์ด ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณrequestPayment()
,requestBillingAuth()
๋ฑ์ ๋ฉ์๋ค์ ํธ์ถํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅ
requestPayment(๊ฒฐ์ ์๋จ,{๊ฒฐ์ ์ ๋ณด})
- ๊ฒฐ์ ์ฐฝ์ ํธ์ถํ๋ ๋ฉ์๋requestBillingAuth(๊ฒฐ์ ์๋จ,{๊ฒฐ์ ์ ๋ณด})
- ์๋ ๊ฒฐ์ ๋ฑ๋ก์ฐฝ์ ํธ์ถํ๋ ๋ฉ์๋
์๋ฅผ ์ ์ฉํ๋ฉด ์๋์ ๊ฐ์ ํ๋ฉด์ด ๋ํ๋๊ณ ,
๊ฒฐ์ ํ๊ธฐ ๋ฒํผ์ ๋๋ฌ ๊ฒฐ์ ์์ฒญ์ ํ๊ฒ๋๋ฉด ์๋์ ๊ฐ์ด ํ ์ค์์ ์ ๊ณตํ๋ ๊ฒฐ์ ์์คํ ์ด ๋จ๊ฒ ๋๋ค.
์์ ๊ฒฐ์ ์ฐฝ์ ํ์ธํด๋ณด๋ฉด ๊ฒฐ์ ๊ธ์ก / ์ํ๋ช ์ด ์์ฒญ ์์ ์์ฑํ ๋ด์ฉ๋ค๊ณผ ๋์ผํ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๐ ๋ค์ ํฌ์คํ ์ ๊ฒฐ์ ์ฑ๊ณต / ์คํจ์ ๋ํ ๋ด์ฉ์ ๋๋ค.
โ
๐ ๐ณ ํ ์คํ์ด๋จผ์ธ ์ฐ๋ํ๊ธฐ (3) _๊ฒฐ์ ์ฑ๊ณต/์คํจ