JourneyJoker/payment/models.py

163 lines
5.5 KiB
Python

from django.db.models import Model, ForeignKey, DecimalField, CharField, DecimalField, UUIDField, BooleanField, CASCADE
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.conf import settings
from django.shortcuts import redirect
from django.urls import reverse_lazy, reverse
from polymorphic.models import PolymorphicModel
from dbsettings.models import Setting
import stripe
import uuid
import paypalrestsdk
from auction.models import Inquiry
PAYMENT_STATUS_AUTHORIZED = -1
PAYMENT_STATUS_SUCCESS = 0
PAYMENT_STATUS_PENDING = 1
PAYMENT_STATUS_FAILURE = 2
PAYMENT_STATUS_REFUND = 3
stripe.api_key = Setting.objects.get(key="stripe.key.secret").value # pylint: disable=no-member
paypal_config = {
"mode": Setting.objects.get(key="paypal.api.mode").value, # pylint: disable=no-member
"client_id": Setting.objects.get(key="paypal.api.id").value, # pylint: disable=no-member
"client_secret": Setting.objects.get(key="paypal.api.secret").value # pylint: disable=no-member
}
paypalrestsdk.configure(paypal_config)
class Payment(PolymorphicModel):
uuid = UUIDField(default=uuid.uuid4, primary_key=True)
content_type = ForeignKey(ContentType, on_delete=CASCADE)
object_id = CharField(max_length=255)
invoice = GenericForeignKey()
active = BooleanField(default=True)
def start(self):
raise NotImplementedError(
"start() not implemented in %s!" % type(self).__name__)
def status(self):
raise NotImplementedError(
"status() not implemented in %s!" % type(self).__name__)
def capture(self):
return self.status()
def cancel(self):
invoice = self.invoice
self.active = False
self.save()
return redirect(invoice.get_absolute_url() + "?status=cancelled")
def refund(self):
return False
class PaypalPayment(Payment):
paypal_id = CharField(max_length=255, blank=True, null=True)
def start(self):
payment = paypalrestsdk.Payment({
"intent": "sale",
"payer": {
"payment_method": "paypal"},
"redirect_urls": {
"return_url": settings.BASE_URL +
reverse("payment:callback", args=[self.uuid]),
"cancel_url": settings.BASE_URL +
reverse("payment:callback", args=[self.uuid])},
"transactions": [{
"item_list": {
"items": [{
"name": "Einzahlung",
"price": float(self.invoice.amount),
"currency": self.invoice.currency.upper(),
"quantity": 1}]},
"amount": {
"total": float(self.invoice.amount),
"currency": self.invoice.currency.upper()},
"description": "Einzahlung"}]})
payment.create()
self.paypal_id = payment.id
self.save()
print(repr(payment))
for link in payment.links:
if link.rel == "approval_url":
return redirect(str(link.href))
def status(self):
payment = paypalrestsdk.Payment.find(self.paypal_id)
print(repr(payment))
return PAYMENT_STATUS_FAILURE
def capture(self):
payment = paypalrestsdk.Payment.find(self.paypal_id)
payer = payment.payer.payer_info.payer_id
if payment.execute(payer):
return PAYMENT_STATUS_SUCCESS
else:
self.active = False
self.save()
return PAYMENT_STATUS_FAILURE
class StripePayment(Payment):
session = CharField(max_length=255, blank=True, null=True)
def start(self):
self.session = stripe.checkout.Session.create(
customer_email=self.invoice.user.user.email,
payment_method_types=['card'],
line_items=[{
'name': 'Urlaubsauktion',
'description': 'Einzahlung',
'amount': int(self.invoice.amount * 100),
'currency': self.invoice.currency,
'quantity': 1,
}],
success_url=settings.BASE_URL +
reverse("payment:callback", args=[self.uuid]),
cancel_url=settings.BASE_URL +
reverse("payment:callback", args=[self.uuid]),
payment_intent_data={"capture_method": "manual", },
).id
self.save()
return redirect(reverse("payment:redirect_stripe", args=[self.uuid]))
def capture(self):
session = stripe.checkout.Session.retrieve(self.session)
payment_intent = session.payment_intent
capture = stripe.PaymentIntent.capture(payment_intent)
return PAYMENT_STATUS_SUCCESS if capture.status == "succeeded" else PAYMENT_STATUS_FAILURE
def status(self):
session = stripe.checkout.Session.retrieve(self.session)
payment_intent = stripe.PaymentIntent.retrieve(session.payment_intent)
print(payment_intent.status)
if payment_intent.status == "processing":
return PAYMENT_STATUS_PENDING
elif payment_intent.status == "succeeded":
return PAYMENT_STATUS_SUCCESS
elif payment_intent.status == "requires_capture":
return PAYMENT_STATUS_AUTHORIZED
return PAYMENT_STATUS_FAILURE
class KlarnaPayment(Payment):
pass
class DummyPayment(Payment):
def start(self):
return redirect(reverse_lazy("payment:status"))
def status(self):
return PAYMENT_STATUS_SUCCESS