From 27cabe32a7729a15c90d170951245d9a3c0013f4 Mon Sep 17 00:00:00 2001 From: Jerome Leclanche Date: Fri, 24 Nov 2017 14:25:16 +0200 Subject: [PATCH] Implement Source model and enums --- djstripe/enums.py | 53 +++++++++++++++++++++++++++++++++++ djstripe/models.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/djstripe/enums.py b/djstripe/enums.py index 42607512f5..96db2ea3a7 100644 --- a/djstripe/enums.py +++ b/djstripe/enums.py @@ -158,6 +158,35 @@ class PlanInterval(Enum): year = _("Year") +class SourceFlow(Enum): + redirect = _("Redirect") + receiver = _("Receiver") + code_verification = _("Code verification") + none = _("None") + + +class SourceStatus(Enum): + canceled = _("Canceled") + chargeable = _("Chargeable") + consumed = _("Consumed") + failed = _("Failed") + pending = _("Pending") + + +class SourceType(Enum): + card = _("Card") + three_d_secure = _("3D Secure") + alipay = _("Alipay") + ach_credit_transfer = _("ACH Credit Transfer") + bancontact = _("Bancontact") + bitcoin = _("Bitcoin") + giropay = _("Giropay") + ideal = _("iDEAL") + p24 = _("P24") + sepa_debit = _("SEPA Direct Debit") + sofort = _("SOFORT") + + class LegacySourceType(Enum): card = _("Card") bank_account = _("Bank account") @@ -165,6 +194,30 @@ class LegacySourceType(Enum): alipay_account = _("Alipay account") +class SourceUsage(Enum): + reusable = _("Reusable") + single_use = _("Single-use") + + +class SourceCodeVerificationStatus(Enum): + pending = _("Pending") + succeeded = _("Succeeded") + failed = _("Failed") + + +class SourceRedirectFailureReason(Enum): + user_abort = _("User-aborted") + declined = _("Declined") + processing_error = _("Processing error") + + +class SourceRedirectStatus(Enum): + pending = _("Pending") + succeeded = _("Succeeded") + not_required = _("Not required") + failed = _("Failed") + + class SubscriptionStatus(Enum): trialing = _("Trialing") active = _("Active") diff --git a/djstripe/models.py b/djstripe/models.py index c22d64a0fd..8fb1ee7938 100644 --- a/djstripe/models.py +++ b/djstripe/models.py @@ -1671,6 +1671,76 @@ def create_token( StripeSource = Card +class Source(StripeObject): + amount = StripeCurrencyField(null=True, blank=True, help_text=( + "Amount associated with the source. " + "This is the amount for which the source will be chargeable once ready. " + "Required for `single_use` sources." + )) + client_secret = StripeCharField(max_length=255, help_text=( + "The client secret of the source. " + "Used for client-side retrieval using a publishable key." + )) + currency = StripeCharField(null=True, blank=True, max_length=3, help_text="Three-letter ISO currency code") + flow = StripeCharField( + max_length=17, choices=enums.SourceFlow.choices, help_text=( + "The authentication flow of the source." + ) + ) + owner = StripeJSONField(help_text=( + "Information about the owner of the payment instrument that may be " + "used or required by particular source types." + )) + statement_descriptor = StripeCharField( + null=True, blank=True, max_length=255, help_text=( + "Extra information about a source. " + "This will appear on your customer’s statement every time you charge the source." + ) + ) + status = StripeCharField( + max_length=10, choices=enums.SourceStatus.choices, help_text=( + "The status of the source. Only `chargeable` sources can be used to create a charge." + ) + ) + type = StripeCharField( + max_length=19, choices=enums.SourceType.choices, help_text="The type of the source." + ) + usage = StripeCharField( + max_length=10, choices=enums.SourceUsage.choices, help_text=( + "Whether this source should be reusable or not. " + "Some source types may or may not be reusable by construction, " + "while other may leave the option at creation." + ) + ) + + # Flows + code_verification = StripeJSONField( + null=True, blank=True, stripe_required=False, help_text=( + "Information related to the code verification flow. " + "Present if the source is authenticated by a verification code (`flow` is `code_verification`)." + ) + ) + receiver = StripeJSONField( + null=True, blank=True, stripe_required=False, help_text=( + "Information related to the receiver flow. " + "Present if the source is a receiver (`flow` is `receiver`)." + ) + ) + redirect = StripeJSONField( + null=True, blank=True, stripe_required=False, help_text=( + "Information related to the redirect flow. " + "Present if the source is authenticated by a redirect (`flow` is `redirect`)." + ) + ) + + customer = models.ForeignKey( + "Customer", on_delete=models.CASCADE, related_name="sources_v3" + ) + + stripe_class = stripe.Source + stripe_dashboard_item_name = "sources" + + # ============================================================================ # # Subscriptions # # ============================================================================ #