웹 프로그래밍/아임포트 연동

아임포트- 카카오 정기결제 예제코드

bysnow 2021. 7. 19. 22:37
728x90
반응형
SMALL

로컬 환경에서 실습을 진행했기 때문에, 컴퓨터를 끄면 서버도 꺼진다. 따로 서비스 서버를 구축하지 않았기 때문에 자바 스케줄러를 활용하여 자동으로 정기 결제 요청을 보낸다.

 

import java.sql.Date;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;

import com.kosta.KOSTA_3_final.logic.subscribe.GetDate;

@Component
public class ReqPaymentScheduler {
	//스케줄러
    private ThreadPoolTaskScheduler scheduler;
	@Autowired
	SchedulePayment setSchedulePay;
	@Autowired 
	DeliveryService deliService;
	@Autowired
	GetDate getDate;
    public void stopScheduler() {
    	//구독 취소 시 scheduler shutdown을 통해 결제 요청 멈춤
        scheduler.shutdown();
    }
 
    public void startScheduler(long customer_uid, int price, long packageId) {
        scheduler = new ThreadPoolTaskScheduler();
        scheduler.initialize();
        // 스케쥴러가 시작되는 부분 
        scheduler.schedule(getRunnable(customer_uid, price, packageId), getTrigger());
    }
    
    public static java.sql.Date convertFromJAVADateToSQLDate(
            java.util.Date javaDate) {
        java.sql.Date sqlDate = null;
        if (javaDate != null) {
            sqlDate = new Date(javaDate.getTime());
        }
        return sqlDate;
    }
 
    private Runnable getRunnable(long customer_uid, int price, long packageId){
    	Date date = getDate.getDate();
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(date);
    	cal.add(Calendar.MONTH, 1);
    	cal.add(Calendar.DATE, 1);
    	Date s = convertFromJAVADateToSQLDate(cal.getTime());
        return () -> {
        	setSchedulePay.schedulePay(customer_uid, price);
        	deliService.deliveryInsert(packageId,customer_uid,s);
        };
    }
 
    private Trigger getTrigger() {
        // 작업 주기 설정 
        return new PeriodicTrigger(1, TimeUnit.MINUTES);
    }
}

이전에 사용하던 Date 값은 java.util.date의 값이었는데 결제를 진행하며 데이터베이스에 결제 관련 정보를 삽입하기 위해서는 sql.date 형식의 값으로 변환해야 했다. 따라서 관련 메서드를 구현하였다.

 

스케줄러의 사용은 매우 간단하여 금방 알아볼 수 있다. 위의 코드에선 1분마다 스케줄러가 schedulePay 메소드, 즉 아임포트 서버로 예약 요청을 보내는 메소드를 호출하고 있다. 결제가 한 번 이루어질 때마다 새로운 배송 일정이 생기므로 deliveryInsert 또한 같은 주기로 실행된다.

 

 

 

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

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 com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.kosta.KOSTA_3_final.model.subscribe.GetTokenVO;
import lombok.Setter;

@Service
public class SchedulePayment {
	
	@Setter(onMethod_ = @Autowired)
	private ImportPay pay;
	
	public String schedulePay(long customer_uid, int price) {
		String token = pay.getToken();
		long timestamp = 0;
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm", Locale.KOREA);
		cal.add(Calendar.MINUTE, +1);
		String date = sdf.format(cal.getTime());
		try {
			Date stp = sdf.parse(date);
			timestamp = stp.getTime()/1000;
			System.out.println(timestamp);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		 Gson str = new Gson(); 
		 token = token.substring(token.indexOf("response") +10); 
		 token = token.substring(0, token.length() - 1);
		 GetTokenVO vo = str.fromJson(token, GetTokenVO.class);
		 String access_token = vo.getAccess_token();
		 
		 
		 RestTemplate restTemplate = new RestTemplate();
		 HttpHeaders headers = new HttpHeaders();
		 headers.setContentType(MediaType.APPLICATION_JSON);
		 headers.setBearerAuth(access_token);
		 
		 JsonObject jsonObject = new JsonObject();
		 jsonObject.addProperty("merchant_uid", timestamp);
		 jsonObject.addProperty("schedule_at", timestamp);
		 jsonObject.addProperty("amount", price);
		 
		 JsonArray jsonArr = new JsonArray();
		 
		 jsonArr.add(jsonObject); JsonObject reqJson = new JsonObject();
		 
		 reqJson.addProperty("customer_uid", customer_uid); 
		 reqJson.add("schedules",jsonArr);
		 String json = str.toJson(reqJson); 
		 System.out.println(json);
		 HttpEntity<String> entity = new HttpEntity<>(json, headers);
		 return restTemplate.postForObject("https://api.iamport.kr/subscribe/payments/schedule", entity, String.class);
		 
		 
		
	
	}
}

위의 코드가 이미 한번 등록한 결제 건에 대해서 재결제 일정을 예약하는 코드이다. 이번 실습에서는 1분마다 결제가 이루어진다. timestamp 형식으로 schedule_at 데이터를 보내야 한다는 점, 그리고 merchant_uid는 각 결제가 이루어질 때마다 고유의 값이 부여되어야 한다는 점을 이해해야 한다. 

JsonArray, JsonObject, Gson 등의 사용법에 대해서는 따로 포스팅할 예정이다.

 

 

아임포트 관련 포스팅을 많이 검색했지만 자바를 이용하여 정기 결제 구독을 구현한 포스팅이 없어 프로젝트를 하는데 시간이 걸렸다. 구체적인 코드를 찾는 사람들에게 많은 도움이 되었으면 좋겠다.

 

 

 

https://tjdqlscjswp.tistory.com/78

 

아임포트 스프링 연동 코드 링크

예제 코드를 리뷰도 하고 공부하며 나눠서 올려보려 했는데 시간과 의지 부족으로 인해 일단 코드 링크를 올려둡니다.  https://github.com/tjdqlscjswp/IMPORT_EXAMPLE GitHub - tjdqlscjswp/IMPORT_EXAMPLEContribute to

tjdqlscjswp.tistory.com

 

728x90
반응형
LIST