Skip to content

Commit 77a841d

Browse files
authored
Merge pull request #90 from golony6449/feature/golony/payment
portone callback 및 payment-key 생성 API 추가
2 parents 824d7ae + ef4eb97 commit 77a841d

File tree

4 files changed

+108
-7
lines changed

4 files changed

+108
-7
lines changed

payment/enum.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from enum import Enum
2+
3+
4+
class PaymentStatus(Enum):
5+
BEFORE_PAYMENT = 1
6+
PAYMENT_FAILED = 2
7+
PAYMENT_SUCCESS = 3
8+
REFUND_FAILED = 4
9+
REFUND_SUCCESS = 5

payment/logic.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from django.contrib.auth import get_user_model
2+
from django.db import transaction
3+
4+
from payment.enum import PaymentStatus
5+
from payment.models import Payment, PaymentHistory
6+
from ticket.models import TicketType, Ticket
7+
8+
import shortuuid
9+
10+
User = get_user_model()
11+
12+
13+
@transaction.atomic
14+
def generate_payment_key(user: User, ticket_type: TicketType):
15+
new_payment = Payment(
16+
payment_key=shortuuid.uuid(),
17+
user=user,
18+
ticket_type=ticket_type,
19+
money=ticket_type.price,
20+
status=PaymentStatus.BEFORE_PAYMENT.value
21+
)
22+
23+
new_payment.save()
24+
25+
_save_history(new_payment.payment_key, PaymentStatus.BEFORE_PAYMENT.value)
26+
return new_payment.payment_key
27+
28+
29+
@transaction.atomic
30+
def proceed_payment(payment_key: str, is_succeed: bool):
31+
status_value = PaymentStatus.PAYMENT_SUCCESS.value if is_succeed else PaymentStatus.PAYMENT_FAILED.value
32+
33+
target_payment = Payment.objects.get(payment_key=payment_key)
34+
target_payment.status = status_value
35+
target_payment.save()
36+
37+
_save_history(payment_key, status_value)
38+
39+
40+
def _save_history(payment_key: str, status: int):
41+
new_payment_history = PaymentHistory(
42+
payment_key=payment_key,
43+
status=status
44+
)
45+
46+
new_payment_history.save()

payment/urls.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
from django.contrib import admin
22
from django.urls import include, path
33

4-
urlpatterns = []
4+
from payment.views import PortoneWebhookApi, get__generate_payment_key
5+
6+
7+
urlpatterns = [
8+
path("portone/webhook/", PortoneWebhookApi.as_view(), name="portone-webhook"),
9+
path("key/", get__generate_payment_key, name="get-payment-key"),
10+
]

payment/views.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,52 @@
1+
from rest_framework.decorators import api_view
2+
from rest_framework.response import Response
13
from rest_framework.views import APIView
24

5+
from ticket.models import TicketType
6+
from payment.logic import generate_payment_key
7+
from payment.models import Payment
38

4-
class PortoneWebhookAPI(APIView):
9+
from django.conf import settings
10+
11+
12+
class PortoneWebhookApi(APIView):
513
def post(self, request):
6-
# TODO: IP Filtering
7-
# 52.78.100.19
8-
# 52.78.48.223
9-
# 52.78.5.241 (Webhook Test Only)
14+
portone_ips = [
15+
"52.78.100.19",
16+
"52.78.48.223",
17+
"52.78.5.241" # (Webhook Test Only)
18+
]
19+
20+
if settings.DEBUG is False and request.META.get("REMOTE_ADDR") not in portone_ips:
21+
raise ValueError("Not Allowed IP")
22+
23+
target_payment = Payment.objects.get(payment_key=request.data["merchant_uid"])
24+
25+
if request.data["status "] != "paid":
26+
raise ValueError("결제 승인건 이외의 요청")
27+
28+
dto = {
29+
"msg": "ok",
30+
"merchant_uid": request.data["merchant_uid"]
31+
}
32+
33+
return Response(dto)
34+
35+
36+
@api_view(["GET"])
37+
def get__generate_payment_key(request):
38+
39+
request_ticket_type = TicketType.objects.get(id=request.data["ticket_type"])
40+
41+
payment_key = generate_payment_key(
42+
user=request.user,
43+
ticket_type=request_ticket_type
44+
)
1045

11-
pass
46+
response_data = {
47+
"msg": "ok",
48+
"payment_key": payment_key,
49+
"price": request_ticket_type.price
50+
}
1251

52+
return Response(response_data)

0 commit comments

Comments
 (0)