есть вьюшка checkout, там модель order создается и то что было в корзине появляется в order. Ну и плюс еще payment_type и user_info. Есть модель Payment которая создается сразу после Order в checkout view и связан объект с user, order и филиалом. Я интегрировал пока вместо банковских шлюзов Yoomoney, чтобы понять вообще процесс и написал api клиента.
Так вот, после того как мне yoomoney дает ссылку на оплату, как проверить что оплата прошла успешно и поменять статусы payment и order на complete. Webhook не вариант так как нужно авторизация по токену каждый раз для того чтобы смотреть историю операций.
Yoomoney дает параметр successfulUrl, туда надо вставить может урл на еще одну вьюшку и если это вьюшка вызывается, то и статус транзакции и заказа я ставлю в оплачен? А где тогда и в каких ситуациях указывать статусы canceled или failed или вызывать вьюшку failed payment? Как быть если выбран тип оплаты не онлайн через карту, а наличными или картой при получении? Админ сам типо вручную будет в этих случаях отмечать статус оплаты и заказа? Инфы достойной вообще про workflow этого процесса я не нашел, если кто-то может рассказать как правильно делается или где об этом прочитать, очень прошу.
Вот пока как у меня идет, пример вьюшки checkout:
class CheckoutAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, domain):
institution = Institution.objects.get(domain=domain)
session = self.request.session
user = self.request.user
# check if request data exists
if "name" not in request.data:
return Response({"detail": "Enter your name"},
status=status.HTTP_400_BAD_REQUEST)
else:
name = request.data['name']
if "phone" not in request.data:
return Response({"detail": "Enter your phone"},
status=status.HTTP_400_BAD_REQUEST)
else:
phone = request.data['phone']
if "comment" not in request.data:
comment = ""
else:
comment = request.data['comment']
if "payment_type" not in request.data:
return Response({"detail": "Choose your payment_type"},
status=status.HTTP_400_BAD_REQUEST)
else:
payment_type = request.data['payment_type']
# check if payment_type exists in db with affiliate
if payment_type in institution.payment_type.values_list("type",
flat=True):
payment_type = institution.payment_type.get(type=payment_type).type
else:
return Response({"detail": "Wrong payment type"},
status=status.HTTP_400_BAD_REQUEST)
# cart check
cart = Cart.objects.filter(institution=institution,
customer=user)
if cart.exists():
cart = cart.first()
# order create or update
order, order_created = Order.objects.update_or_create(
institution=institution, customer=user, cart=cart,
defaults={"name": name,
"phone": phone,
"comment": comment,
"payment_type": payment_type})
# payment create or update
payment, payment_created = Payment.objects.update_or_create(
institution=institution, user=user, order=order,
defaults={"total": order.final_price})
# check if payment type is online by card
if payment_type == PaymentType.ONLINE:
if "gateway" not in request.data:
return Response({"detail": "Choose your payment gateway"},
status=status.HTTP_400_BAD_REQUEST)
else:
gateway = request.data['gateway']
payment.type = PaymentType.ONLINE
payment.status = PaymentStatus.PENDING
payment.save()
# if customer choose pay by yoomoney
if gateway == "yoomoney":
wallet = institution.user.yoomoney.values_list("wallet", flat=True)[0]
if wallet:
from apps.payment.services.YooMoney.send_payment import YooMoneyPay
client = YooMoneyPay(wallet,
"shop",
order.code,
"AC",
order.final_price,
f"APP: заказ {order.id}",
f"APP: заказ {order.id}",
order.code,
"localhost")
return Response({"url": client.redirected_url})
if user.is_authenticated:
pass
# cart check
# cart = Cart.objects.filter(institution=institution,
# customer=user)
# # if settings.CART_SESSION_ID in session:
# # cart = Cart.objects.filter(institution=institution,
# # customer=user,
# # session_id=session[
# # settings.CART_SESSION_ID])
# if cart.exists():
# cart = cart.first()
#
# order, created = Order.objects.update_or_create(
# institution=institution, customer=user, cart=cart,
# defaults={"name": name,
# "phone": phone,
# "comment": comment,
# "payment_type": payment_type.type})
#
# serializer = OrderSerializer(order)
#
# return Response({"detail": serializer.data})
else:
return Response({"detail": "Please login"})