2020-02-07 14:57:30 +00:00
|
|
|
from django.db.models import Model, ForeignKey, DecimalField, CharField, DecimalField, UUIDField, BooleanField, CASCADE
|
2020-01-22 17:32:13 +00:00
|
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
2019-12-24 13:41:49 +00:00
|
|
|
from django.conf import settings
|
2020-01-26 10:53:25 +00:00
|
|
|
from django.shortcuts import redirect
|
2020-02-07 14:57:30 +00:00
|
|
|
from django.urls import reverse_lazy, reverse
|
2020-01-26 10:53:25 +00:00
|
|
|
|
2019-12-24 13:41:49 +00:00
|
|
|
from polymorphic.models import PolymorphicModel
|
2020-01-26 10:53:25 +00:00
|
|
|
from dbsettings.models import Setting
|
|
|
|
|
|
|
|
import stripe
|
|
|
|
import uuid
|
2020-02-07 14:57:30 +00:00
|
|
|
import paypalrestsdk
|
2019-12-24 13:41:49 +00:00
|
|
|
|
|
|
|
from auction.models import Inquiry
|
|
|
|
|
2020-01-22 17:32:13 +00:00
|
|
|
PAYMENT_STATUS_AUTHORIZED = -1
|
|
|
|
PAYMENT_STATUS_SUCCESS = 0
|
|
|
|
PAYMENT_STATUS_PENDING = 1
|
|
|
|
PAYMENT_STATUS_FAILURE = 2
|
|
|
|
PAYMENT_STATUS_REFUND = 3
|
2019-12-24 13:41:49 +00:00
|
|
|
|
2020-02-07 14:57:30 +00:00
|
|
|
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)
|
2020-01-26 10:53:25 +00:00
|
|
|
|
2019-12-24 13:41:49 +00:00
|
|
|
class Payment(PolymorphicModel):
|
2020-01-26 10:53:25 +00:00
|
|
|
uuid = UUIDField(default=uuid.uuid4, primary_key=True)
|
2020-01-22 17:32:13 +00:00
|
|
|
content_type = ForeignKey(ContentType, on_delete=CASCADE)
|
|
|
|
object_id = CharField(max_length=255)
|
|
|
|
invoice = GenericForeignKey()
|
2020-02-07 14:57:30 +00:00
|
|
|
active = BooleanField(default=True)
|
2019-12-24 13:41:49 +00:00
|
|
|
|
2020-01-26 10:53:25 +00:00
|
|
|
def start(self):
|
2020-02-07 14:57:30 +00:00
|
|
|
raise NotImplementedError(
|
|
|
|
"start() not implemented in %s!" % type(self).__name__)
|
2020-01-26 10:53:25 +00:00
|
|
|
|
2019-12-24 13:41:49 +00:00
|
|
|
def status(self):
|
2020-02-07 14:57:30 +00:00
|
|
|
raise NotImplementedError(
|
|
|
|
"status() not implemented in %s!" % type(self).__name__)
|
2019-12-24 13:41:49 +00:00
|
|
|
|
2020-01-26 10:53:25 +00:00
|
|
|
def capture(self):
|
|
|
|
return self.status()
|
|
|
|
|
|
|
|
def cancel(self):
|
|
|
|
invoice = self.invoice
|
2020-02-07 14:57:30 +00:00
|
|
|
self.active = False
|
|
|
|
self.save()
|
2020-01-26 10:53:25 +00:00
|
|
|
return redirect(invoice.get_absolute_url() + "?status=cancelled")
|
2020-02-07 14:57:30 +00:00
|
|
|
|
|
|
|
def refund(self):
|
|
|
|
return False
|
|
|
|
|
2020-01-26 10:53:25 +00:00
|
|
|
|
2019-12-24 13:41:49 +00:00
|
|
|
class PaypalPayment(Payment):
|
2020-02-07 14:57:30 +00:00
|
|
|
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
|
2019-12-24 13:41:49 +00:00
|
|
|
|
|
|
|
class StripePayment(Payment):
|
2020-01-26 10:53:25 +00:00
|
|
|
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,
|
|
|
|
}],
|
2020-02-07 14:57:30 +00:00
|
|
|
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
|
2020-01-26 10:53:25 +00:00
|
|
|
self.save()
|
2020-02-07 14:57:30 +00:00
|
|
|
return redirect(reverse("payment:redirect_stripe", args=[self.uuid]))
|
2020-01-26 10:53:25 +00:00
|
|
|
|
|
|
|
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)
|
2020-02-07 14:57:30 +00:00
|
|
|
print(payment_intent.status)
|
2020-01-26 10:53:25 +00:00
|
|
|
if payment_intent.status == "processing":
|
|
|
|
return PAYMENT_STATUS_PENDING
|
|
|
|
elif payment_intent.status == "succeeded":
|
|
|
|
return PAYMENT_STATUS_SUCCESS
|
2020-02-07 14:57:30 +00:00
|
|
|
elif payment_intent.status == "requires_capture":
|
|
|
|
return PAYMENT_STATUS_AUTHORIZED
|
2020-01-26 10:53:25 +00:00
|
|
|
return PAYMENT_STATUS_FAILURE
|
2020-02-07 14:57:30 +00:00
|
|
|
|
2019-12-24 13:41:49 +00:00
|
|
|
|
|
|
|
class KlarnaPayment(Payment):
|
2020-01-22 17:32:13 +00:00
|
|
|
pass
|
2019-12-24 13:41:49 +00:00
|
|
|
|
2020-02-07 14:57:30 +00:00
|
|
|
|
2020-01-22 17:32:13 +00:00
|
|
|
class DummyPayment(Payment):
|
2020-01-26 10:53:25 +00:00
|
|
|
def start(self):
|
|
|
|
return redirect(reverse_lazy("payment:status"))
|
|
|
|
|
2020-01-22 17:32:13 +00:00
|
|
|
def status(self):
|
|
|
|
return PAYMENT_STATUS_SUCCESS
|