Skip to content

Commit

Permalink
Payment Intent and Checkout Session (SCA, EU Regulations) (dj-stripe#914
Browse files Browse the repository at this point in the history
)

Add models and functionalities to support SCA regulations (https://stripe.com/docs/strong-customer-authentication/migration)

New Models:
* Payment Method
* Setup Intent
* Payment Intent
* Checkout

Also, extra changes to support model additions such as:
* Update Subscriptions with new `pending_setup_intent` field 
* Rename property payment_methods for Customer object to solve conflict: Due to addition of new Payment Method model, there has been a conflict in the name of property `payment_methods` on Customer object, hence the required name change.
* Update migrations and test fixtures.
*  Add `Charge.payment_intent` + test fixture

This resolves dj-stripe#803, dj-stripe#897

Co-authored-by: Ayush Tiwari <[email protected]>
Co-authored-by: John Carter <[email protected]>
Co-authored-by: Aymeric Derbois <[email protected]>
  • Loading branch information
3 people committed Aug 1, 2019
1 parent 482a9d2 commit 23ab857
Show file tree
Hide file tree
Showing 35 changed files with 2,357 additions and 56 deletions.
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ History
- Made ``SubscriptionItem.quantity`` nullable as per Plans with ``usage_type="metered"`` (follow-up to #865)
- Added manage command ``djstripe_sync_models`` (#727, #89)
- Fixed issue with re-creating a customer after `Customer.purge()` (#916)
- New models
- Payment Intent
- Setup Intent
- Payment Method
- Session

Changes from API 2018-11-08:

Expand Down Expand Up @@ -44,6 +49,7 @@ Changes from API 2019-03-14:
- Removed ``Invoice.date``, in place of ``Invoice.created`` (added deprecated property for the old name)
- Added ``Invoice.status_transitions``
- Renamed ``Customer.account_balance`` to ``Customer.balance`` (added deprecated property for the old name)
- Renamed ``Customer.payment_methods`` to ``Customer.customer_payment_methods``

2.0.4 (unreleased)
------------------
Expand Down
38 changes: 38 additions & 0 deletions djstripe/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,37 @@ class FileUploadAdmin(StripeModelAdmin):
search_fields = ("filename",)


@admin.register(models.PaymentIntent)
class PaymentIntentAdmin(StripeModelAdmin):
list_display = (
"id",
"customer",
"amount",
"currency",
"description",
"amount_capturable",
"amount_received",
"receipt_email",
)
search_fields = ("customer__id", "invoice__id")


@admin.register(models.SetupIntent)
class SetupIntentAdmin(StripeModelAdmin):
list_display = (
"id",
"created",
"customer",
"description",
"on_behalf_of",
"payment_method",
"payment_method_types",
"status",
)
list_filter = ("status",)
search_fields = ("customer__id", "status")


@admin.register(models.Invoice)
class InvoiceAdmin(StripeModelAdmin):
list_display = (
Expand Down Expand Up @@ -327,6 +358,13 @@ class SourceAdmin(StripeModelAdmin):
list_filter = ("type", "status", "usage", "flow")


@admin.register(models.PaymentMethod)
class PaymentMethodAdmin(StripeModelAdmin):
raw_id_fields = ("customer",)
list_display = ("customer", "billing_details")
list_filter = ("customer",)


@admin.register(models.Subscription)
class SubscriptionAdmin(StripeModelAdmin):
raw_id_fields = ("customer",)
Expand Down
50 changes: 50 additions & 0 deletions djstripe/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ class BusinessType(Enum):
company = _("Company")


class CaptureMethod(Enum):
automatic = _("Automatic")
manual = _("Manual")


class CardCheckResult(Enum):
pass_ = (_("Pass"), "pass")
fail = _("Fail")
Expand Down Expand Up @@ -231,6 +236,11 @@ class ChargeStatus(Enum):
failed = _("Failed")


class ConfirmationMethod(Enum):
automatic = _("Automatic")
manual = _("Manual")


class CouponDuration(Enum):
once = _("Once")
repeating = _("Multi-month")
Expand Down Expand Up @@ -285,6 +295,39 @@ class InvoiceBilling(Enum):
send_invoice = _("Send invoice")


class IntentUsage(Enum):
on_session = _("On session")
off_session = _("Off session")


class IntentStatus(Enum):
"""
Status of Intents which apply both to PaymentIntents
and SetupIntents.
"""

requires_payment_method = _(
"Intent created and requires a Payment Method to be attached."
)
requires_confirmation = _("Intent is ready to be confirmed.")
requires_action = _("Payment Method require additional action, such as 3D secure.")
processing = _("Required actions have been handled.")
canceled = _(
"Cancellation invalidates the intent for future confirmation and cannot be undone."
)


class PaymentIntentStatus(IntentStatus):
succeeded = _("The funds are in your account.")
requires_capture = _("Capture the funds on the cards which have been put on holds.")


class SetupIntentStatus(IntentStatus):
succeeded = _(
"Setup was successful and the payment method is optimized for future payments."
)


class PayoutFailureCode(Enum):
"""
Payout failure error codes.
Expand Down Expand Up @@ -447,6 +490,13 @@ class SourceRedirectStatus(Enum):
failed = _("Failed")


class SubmitTypeStatus(Enum):
auto = _("Auto")
book = _("Book")
donate = _("donate")
pay = _("pay")


class SubscriptionStatus(Enum):
trialing = _("Trialing")
active = _("Active")
Expand Down
17 changes: 16 additions & 1 deletion djstripe/event_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,17 @@ def customer_subscription_webhook_handler(event):


@webhooks.handler(
"transfer", "charge", "coupon", "invoice", "invoiceitem", "plan", "product", "source"
"transfer",
"charge",
"coupon",
"invoice",
"invoiceitem",
"paymentintent",
"paymentmethod",
"plan",
"product",
"setupintent",
"source",
)
def other_object_webhook_handler(event):
"""Handle updates to transfer, charge, invoice, invoiceitem, plan, product and source objects.
Expand All @@ -117,6 +127,8 @@ def other_object_webhook_handler(event):
- plan: https://stripe.com/docs/api#plans
- product: https://stripe.com/docs/api#products
- source: https://stripe.com/docs/api#sources
- payment_method: https://stripe.com/docs/api/payment_methods
- payment_intent: https://stripe.com/docs/api/payment_intents
"""

if event.parts[:2] == ["charge", "dispute"]:
Expand All @@ -129,9 +141,12 @@ def other_object_webhook_handler(event):
"coupon": models.Coupon,
"invoice": models.Invoice,
"invoiceitem": models.InvoiceItem,
"paymentintent": models.PaymentIntent,
"paymentmethod": models.PaymentMethod,
"plan": models.Plan,
"product": models.Product,
"transfer": models.Transfer,
"setupintent": models.SetupIntent,
"source": models.Source,
}.get(event.category)

Expand Down
2 changes: 1 addition & 1 deletion djstripe/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -1580,7 +1580,7 @@ class Migration(migrations.Migration):
"status",
djstripe.fields.StripeEnumField(
enum=djstripe.enums.PayoutStatus,
help_text="Current status of the payout. A payout will be `pending` until it is submitted to the bank, at which point it becomes `in_transit`. I t will then change to paid if the transaction goes through. If it does not go through successfully, its status will change to `failed` or `canceled`.",
help_text="Current status of the payout. A payout will be `pending` until it is submitted to the bank, at which point it becomes `in_transit`. It will then change to paid if the transaction goes through. If it does not go through successfully, its status will change to `failed` or `canceled`.",
max_length=10,
),
),
Expand Down
Loading

0 comments on commit 23ab857

Please sign in to comment.