|
| 1 | +import enum |
1 | 2 | import json
|
2 | 3 | from typing import Iterable
|
| 4 | +from typing import Optional |
3 | 5 | from typing import Union
|
4 | 6 | from uuid import uuid4
|
5 | 7 |
|
@@ -36,6 +38,49 @@ def __setattr__(self, key, value):
|
36 | 38 | self._payment.extra_data = json.dumps(data)
|
37 | 39 |
|
38 | 40 |
|
| 41 | +class BaseSubscription(models.Model): |
| 42 | + token = models.CharField( |
| 43 | + _("subscribtion token/id"), |
| 44 | + help_text=_("Token/id used to identify subscription by provider"), |
| 45 | + max_length=255, |
| 46 | + default=None, |
| 47 | + null=True, |
| 48 | + blank=True, |
| 49 | + ) |
| 50 | + |
| 51 | + class TimeUnit(enum.Enum): |
| 52 | + year = "year" |
| 53 | + month = "month" |
| 54 | + day = "day" |
| 55 | + |
| 56 | + def get_token(self) -> str: |
| 57 | + return self.token |
| 58 | + |
| 59 | + def set_data(self, token: str, **kwargs): |
| 60 | + """ |
| 61 | + Sets token and other values asociated with subscription |
| 62 | + Kwargs can contain provider-specific values |
| 63 | + """ |
| 64 | + self.token = token |
| 65 | + |
| 66 | + def get_period(self) -> int: |
| 67 | + raise NotImplementedError() |
| 68 | + |
| 69 | + def get_unit(self) -> TimeUnit: |
| 70 | + raise NotImplementedError() |
| 71 | + |
| 72 | + def cancel(self): |
| 73 | + """ |
| 74 | + Cancel the subscription |
| 75 | + Used by providers, that use provider initiated subscription workflow |
| 76 | + """ |
| 77 | + provider = provider_factory(self.variant) |
| 78 | + provider.cancel_subscription(self) |
| 79 | + |
| 80 | + class Meta: |
| 81 | + abstract = True |
| 82 | + |
| 83 | + |
39 | 84 | class BasePayment(models.Model):
|
40 | 85 | """
|
41 | 86 | Represents a single transaction. Each instance has one or more PaymentItem.
|
@@ -144,6 +189,33 @@ def get_success_url(self) -> str:
|
144 | 189 | def get_process_url(self) -> str:
|
145 | 190 | return reverse("process_payment", kwargs={"token": self.token})
|
146 | 191 |
|
| 192 | + def get_payment_url(self) -> str: |
| 193 | + """ |
| 194 | + Get the url the view that handles the payment (payment_details() in documentation) |
| 195 | + For now used only by PayU provider to redirect users back to CVV2 form |
| 196 | + """ |
| 197 | + raise NotImplementedError() |
| 198 | + |
| 199 | + def get_subscrption(self) -> Optional[BaseSubscription]: |
| 200 | + """ |
| 201 | + Returns subscription object asociated with this payment |
| 202 | + or None if the payment is not recurring |
| 203 | + """ |
| 204 | + return None |
| 205 | + |
| 206 | + def is_recurring(self) -> bool: |
| 207 | + return self.get_subscrption() is not None |
| 208 | + |
| 209 | + def auto_complete_with_subscription(self): |
| 210 | + """ |
| 211 | + Complete the payment with subscription |
| 212 | + Used by providers, that use server initiated subscription workflow |
| 213 | +
|
| 214 | + Throws RedirectNeeded if there is problem with the payment that needs to be solved by user |
| 215 | + """ |
| 216 | + provider = provider_factory(self.variant) |
| 217 | + provider.auto_complete_with_subscription(self) |
| 218 | + |
147 | 219 | def capture(self, amount=None):
|
148 | 220 | if self.status != PaymentStatus.PREAUTH:
|
149 | 221 | raise ValueError("Only pre-authorized payments can be captured.")
|
|
0 commit comments