저번에 Django로 Iamport 결제기능을 구현해보는 포스트를 작성하였다. 

https://vicapor.tistory.com/62

장고에서는 view에서 정의하고 wagtail에서는 model에 정의하기 때문에 wagtail에 맞게 바꾸어 주었다. iamport 결제 기능 구현과 더불어 결제 페이지의 흐름 구현을 같이 기술하려고 한다.

 

1. 결제 페이지 구현

 

기존에 구현해 놓은 course page 이다. 여기서 결제 하기 버튼을 누르면 결제 page로 이동하게 하려고 한다. (기능 구현에 충실하였기 때문에 디자인은 '전혀' 신경쓰지 않았다.. 테스트하기 버튼도 보이는 것 같은데 신경쓰지말고 넘어가자)

 

course/models.py

    @route(r'^pay/$', name='go_payment')
    def go_payment(self, request):
        context = {
            "course": self
        }
        return render(request, 'billing/billing_page.html', context)

templates/course_page.html

<form action="{% pageurl page %}pay/" method="post">
  {% csrf_token %}
  <button class="button is-info" type="submit">결제하기</button>
</form>

결제하기 버튼을 form을 통해 구현했다. 현재 course의 정보를 담아서 결제 페이지로 보낼 것이기 때문에 post를 사용했다. 결제하기 버튼을 누르면 billing_page.html에 현재 course 페이지의 정보를 가지고 render하게 된다. 

 

2. 결제 페이지

billing/billing_page.html

{% extends 'base.html' %}
{% load wagtailcore_tags wagtailimages_tags %}

{% block content %}

<div class="section mt-6">
    <div class="container">
        {{ course.title }}
        {% image course.image fill-540x300 as photo %} <!--강의 이미지-->
            <img src="{{ photo.url }}" alt="">

        {{ course.price }} <!--강의 가격-->

        {{ user.field }}
        <input type="text" value="{{ user.email }}" id="user_email"> <!--구매자 이메일-->
        <input type="text" value="{{ user.username }}" id="user_name"> <!--구매자 이름-->
        <input type="tel" id="user_phonenumber"> <!--구매자 폰번호-->
        <button class="button is-primary mt-6" onclick="start_payment();">결제버튼</button> <!--결제 버튼-->
    </div>
</div>

<script src="http://code.jquery.com/jquery-1.12.4.min.js" ></script>
<script src="http://service.iamport.kr/js/iamport.payment-1.1.5.js"></script>
<script>
    function start_payment(){

        var im_email = document.getElementById('user_email').value;
        var im_name = document.getElementById('user_name').value;
        var im_phonenumber = document.getElementById('user_phonenumber').value;

        IMP.init('imp');
        let csrftoken = '{{ csrf_token }}'
        IMP.request_pay({
            pg: 'html5_inicis',
            pay_method: 'card',
            merchant_uid: 'merchant_' + new Date().getTime(),
            name: '{{ course.title }}',
            amount: '{{ course.price }}',
            buyer_email: im_email,
            buyer_name: im_name,
            buyer_tel: im_phonenumber,
            buyer_addr: '서울특별시 강남구 삼성동',
            buyer_postcode: '123-456'
        }, function (rsp) {
            if (rsp.success) {
                jQuery.ajax({
                    url: "{{ course.url }}check/", 
                    headers:{'X-CSRFToken':csrftoken},
                    type: 'POST',
                    dataType: 'json',
                    data: {
                        imp_uid: rsp.imp_uid
                    },
                }).done(function (data) {
                    if (data.status=='success') {
                        location.href = '{{ course.url }}complete/';
                    } else {
                        var msg = '아직 제대로 결제가 되지 않았습니다.';
                        alert(msg);
                    }
                }).fail(function () {
                    alert("ajax fail");
                }).always(function () {

                });
            } else {
                var msg = '결제에 실패하였습니다.';
                msg += '에러내용 : ' + rsp.error_msg;
                alert(msg);
            }
        });
    }
</script>
{% endblock %}

결제 페이지 이다. (script는 나중에 js파일로 따로 만들어서 정의해 놔야겠다.)

course 페이지의 정보를 가지고 와서 추가로 email과 핸드폰 번호, 결제 사용자 이름을 적을 수 있는 form을 간단하게 구현했다. 

 

(다시한번 디자인은 신경쓰지말도록하자..)

이제 결제 버튼을 누르면 import 가 실행 될 수 있게 함수로 만들어서 button과 연결하였다. 여기서 주의해야할 점은 Django에서 서버로 데이터를 전송하기 위해서는 csrf_token을 반드시 같이 보내야 한다는 점이다. 위에 코드를 보면 알겠지만 JSON에서 csrf_token을 보내는 방식을 확인할 수 있을 것이다. 

 

3.결제

course/models.py

    @route(r'^check/$', name='iamport_data')
    def iamport_data(self, request):
        if request.method == 'POST' and request.is_ajax():
            imp_uid = request.POST.get('imp_uid')
            data = {
                "imp_key": "1234567",
                "imp_secret": "fefefefefe"
            }

            response = requests.post('https://api.iamport.kr/users/getToken', data=data)
            data = response.json()
            my_token = data['response']['access_token']

            headers = {"Authorization": my_token}
            response = requests.get('https://api.iamport.kr/payments/'+imp_uid, data=data, headers = headers)
            data = response.json()

            order_amount = self.price
            amountToBePaid = data['response']['amount']
            status = data['response']['status']

            if order_amount==amountToBePaid:
                if status == 'ready':
                    return HttpResponse(json.dumps({'status': "vbankIssued", 'message': "가상계좌 발급 성공"}),
                                        content_type="application/json")

                elif status=='paid':
                    return HttpResponse(json.dumps({'status': "success", 'message': "일반 결제 성공"}),
                                        content_type="application/json")

                else:
                    pass

            else:
                return HttpResponse(json.dumps({'status': "forgery", 'message': "위조된 결제시도"}), content_type="application/json")
        else:
            pass

billing_page.html에서 json을 통해 결제 정보를 검증하는 코드이다. 기존 Django와 달라진 점은 view에서의 정의한 것이 아니라 models.py에 route를 통해 정의한 것이다. 

 

문제가 없으면 결제 성공을 HttpResponse를 통해 보낸다.

 

4. 결제 완료

 

결제가 정상적이면 complete를 보낸다. 

done(function (data) {
  if (data.status=='success') {
  location.href = '{{ course.url }}complete/';
  } else {
  var msg = '아직 제대로 결제가 되지 않았습니다.';
  alert(msg);
}

 

course/models.py

    @route(r'^complete/$', name='payment_complete')
    def payment_complete(self, request):

        context = {
            "information": self
        }
        return render(request, 'billing/payment_complete.html', context)

결제가 성공적으로 되었으면 결제 페이지 정보와 같이 payment_complete.html에 렌더해준다. 

 

billing/payment_complete.html

{% extends 'base.html' %}
{% load wagtailcore_tags %}

{% block content %}
<div class="section mt-6">
    <div class="container">
        <h1>
            결제가 완료 되었습니다!!!!!!!!!!!
        </h1>
        <a href="{{ information.url }}">돌아가기</a> <!--코스 페이지로 돌아가기-->
    </div>
</div>
{% endblock %}

결제 완료 페이지이다. 그냥 결제 완료를 위해서 사용한 것이다.

여기서 중요한 점은 결제 완료 페이지로 넘어가기 위해서는 js에서 location.ref로 정의 해놔야 한다.

'Back-End > Wagtail, Django' 카테고리의 다른 글

알아두면 좋을 것들  (0) 2021.10.22
Wagtail StyleGuide + 추가 모듈  (0) 2021.10.18
Wagtail 중복 로그인 방지 (Django사용)  (0) 2021.10.06
Wagtail Video  (0) 2021.10.01
Wagtail Custom Widget (+Model)  (0) 2021.09.29

+ Recent posts