givepro

Paypal 연동 (2) - REST API JAVA (Spring boot) 본문

백엔드/SpringBoot

Paypal 연동 (2) - REST API JAVA (Spring boot)

givepro 2021. 11. 3. 16:32
반응형

개발환경

  • Spring boot gradle
  • jdk 1.8

1. build.gradle compile add

paypal sdk 를 compile 하도록 dependencies에 추가 한다.

compile group: 'com.paypal.sdk', name: 'rest-api-sdk', version: '1.14.0'

2. Paypal 환경 변수 추가

Paypal Developer에서 App을 생성 후 해당 App의 상세 페이지에서 아래 항목을 확인 가능하다.

  • Client ID
  • Secret ID

application.properties에 아래와 같이 추가 하도록 한다.

# Paypal
paypal.client.app={Client ID}
paypal.client.secret={Secret ID}
paypal.mode=sandbox // sandbox or live

 

3. PaypalConfig.java

@Configuration 어노테이션으로 페이팔 기본 환경을 셋팅하도록 한다.

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

import java.util.HashMap;
import java.util.Map;

import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.OAuthTokenCredential;
import com.paypal.base.rest.PayPalRESTException;

@Configuration
public class PaypalConfig {

    @Value("${paypal.client.app}")
    private String clientId;
    @Value("${paypal.client.secret}")
    private String clientSecret;
    @Value("${paypal.mode}")
    private String mode;

    @Bean
    public Map<String, String> paypalSdkConfig() {
        Map<String, String> configMap = new HashMap<>();
        configMap.put("mode", mode);
        return configMap;
    }

    @Bean
    public OAuthTokenCredential oAuthTokenCredential() {
        return new OAuthTokenCredential(clientId, clientSecret, paypalSdkConfig());
    }

    @Bean
    public APIContext apiContext() throws PayPalRESTException {
        APIContext context = new APIContext(oAuthTokenCredential().getAccessToken());
        context.setConfigurationMap(paypalSdkConfig());
        return context;
    }

}

 

4. PaypalService.java

결제 생성 및 실행에 대한 메소드가 있는 클래스를 생성

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.paypal.api.payments.Amount;
import com.paypal.api.payments.Payer;
import com.paypal.api.payments.Payment;
import com.paypal.api.payments.PaymentExecution;
import com.paypal.api.payments.RedirectUrls;
import com.paypal.api.payments.Transaction;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;

@Service
public class PaypalService {

    @Autowired
    private APIContext apiContext;

    // 결제 생성
    public Payment createPayment(
            Double total,
            String currency,
            String method,
            String intent,
            String description,
            String cancelUrl,
            String successUrl) throws PayPalRESTException{
        Amount amount = new Amount();
        amount.setCurrency(currency);
        total = new BigDecimal(total).setScale(2, RoundingMode.HALF_UP).doubleValue();
        amount.setTotal(String.format("%.2f", total));

        Transaction transaction = new Transaction();
        transaction.setDescription(description);
        transaction.setAmount(amount);

        List<Transaction> transactions = new ArrayList<>();
        transactions.add(transaction);

        Payer payer = new Payer();
        payer.setPaymentMethod(method.toString());

        Payment payment = new Payment();
        payment.setIntent(intent.toString());
        payment.setPayer(payer);
        payment.setTransactions(transactions);
        RedirectUrls redirectUrls = new RedirectUrls();
        redirectUrls.setCancelUrl(cancelUrl);
        redirectUrls.setReturnUrl(successUrl);
        payment.setRedirectUrls(redirectUrls);

        return payment.create(apiContext);
    }

    // 결제 실행
    public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException{
        Payment payment = new Payment();
        payment.setId(paymentId);
        PaymentExecution paymentExecute = new PaymentExecution();
        paymentExecute.setPayerId(payerId);
        return payment.execute(apiContext, paymentExecute);
    }

}

 

5. PaypalController

결제~완료, 환불에 대한 컨트롤러를 생성

import com.paypal.base.rest.PayPalRESTException;
import com.peopulley.qpicker.service.PaypalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class PaypalController {

    @Autowired
    PaypalService service;

    @Autowired
    PaypalConfig paypalConfig;

    public static final String SUCCESS_URL = "paypal/success";
    public static final String CANCEL_URL = "paypal/cancel";

    @GetMapping("/paypal")
    public String home() {
        return "paypal/paypal_form";
    }

    @PostMapping("/paypal/submit")
    public String payment() {
        try {
            Payment payment = service.createPayment(
                    4.00,
                    "USD",
                    "paypal", // credit_card, paypal
                    "sale", // sale (즉시 결제 완료됨), authorize (판매자가 결제 승인하는 방식), order (주문 대기중 - 이후 동작 확인 불가)
                    "payment description", // product name
                    "http://localhost:8081/" + CANCEL_URL,
                    "http://localhost:8081/" + SUCCESS_URL);
            for (Links link : payment.getLinks()) {
                if (link.getRel().equals("approval_url")) {
                    return "redirect:" + link.getHref();
                }
            }

        } catch (PayPalRESTException e) {
            e.printStackTrace();
        }
        return "redirect:/";
    }

    @GetMapping(value = CANCEL_URL)
    public String cancelPay() {
        return "paypal/cancel";
    }

    @GetMapping(value = SUCCESS_URL)
    public String successPay(@RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId) {
        try {
            Payment payment = service.executePayment(paymentId, payerId);
            System.out.println(payment.toJSON());
            if (payment.getState().equals("approved")) {
                return "paypal/success";
            }
        } catch (PayPalRESTException e) {
            System.out.println(e.getMessage());
        }
        return "redirect:/";
    }

    @GetMapping("/paypal/refund")
    public String refund() {
        try {
            Amount amount = new Amount();
            amount.setTotal("4.00");
            amount.setCurrency("USD");

            String id = "{sale_id}";
            Sale sale = new Sale();
            sale.setId(id);

            RefundRequest refund = new RefundRequest();
            refund.setAmount(amount);

            Refund returnRefund = sale.refund(paypalConfig.apiContext(), refund);
            System.out.println(returnRefund);
        } catch (PayPalRESTException e) {
            System.out.println(e.getMessage());
        }
        return "paypal/paypal_form";
    }

}
Comments