Skip to content

Commit 5b76568

Browse files
committed
Add Stripe recurring payments support
Implement wallet interface for Stripe recurring payments: - autocomplete_with_wallet() for server-initiated charges - Store PaymentMethod and Customer ID during first payment - Use PaymentIntent API with off_session flag for recurring charges - Support 3D Secure authentication when required Changes: - Add recurring_payments and store_payment_method parameters to init - Implement autocomplete_with_wallet() using stored payment method - Add customer_creation='always' to ensure customer is created - Extract and store PaymentMethod + Customer ID from Checkout Session - Handle payment_intent status responses (succeeded, requires_action, failed) Tests: - Webhook token storage test (test_webhook_stores_token.py) - Recurring payment flow tests (test_recurring.py): * Success case with stored payment method * Missing customer_id error handling * 3D Secure redirect handling * Card declined handling * Stripe API error handling * Missing token error handling Documentation: - Comprehensive webhook setup guide (docs/webhooks.rst) - Provider configuration examples (docs/backends.rst) - Note on use_token parameter (optional, defaults to True)
1 parent d6beb42 commit 5b76568

File tree

6 files changed

+567
-40
lines changed

6 files changed

+567
-40
lines changed

docs/backends.rst

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,30 +217,48 @@ Stripe
217217

218218
Example::
219219

220-
# Settings for Production
220+
# Production
221221
PAYMENT_VARIANTS = {
222222
'stripe': (
223223
'payments.stripe.StripeProviderV3',
224224
{
225-
'api_key': 'sk_test_123456',
226-
'use_token': True,
225+
'api_key': 'sk_live_123456',
227226
'endpoint_secret': 'whsec_123456',
228-
'secure_endpoint': True
227+
'secure_endpoint': True,
228+
# Optional: use_token defaults to True
229+
# 'use_token': True, # Use payment.token instead of payment.pk in client_reference_id
229230
}
230231
)
231232
}
232-
# Settings for Development
233+
234+
# Development
233235
PAYMENT_VARIANTS = {
234236
'stripe': (
235237
'payments.stripe.StripeProviderV3',
236238
{
237239
'api_key': 'sk_test_123456',
238-
'use_token': True,
239-
'secure_endpoint': False
240+
'secure_endpoint': False,
241+
# Optional: use_token defaults to True
242+
}
243+
)
244+
}
245+
246+
# Recurring payments (wallet-based)
247+
PAYMENT_VARIANTS = {
248+
'stripe-recurring': (
249+
'payments.stripe.StripeProviderV3',
250+
{
251+
'api_key': 'sk_live_123456',
252+
'endpoint_secret': 'whsec_123456',
253+
'recurring_payments': True,
240254
}
241255
)
242256
}
243257

258+
.. note::
259+
260+
Stripe uses global webhook endpoints. See :doc:`webhooks` for webhook configuration.
261+
244262

245263
MercadoPago
246264
-----------

docs/webhooks.rst

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,35 +61,87 @@ Your webhook URL would be::
6161
Stripe Webhooks
6262
===============
6363

64+
Stripe uses **global webhook endpoints** (configured once in dashboard for all payments).
65+
66+
Important: Stripe Test vs Live Mode
67+
------------------------------------
68+
69+
Stripe doesn't have a "sandbox" like PayU. Instead:
70+
71+
- **Test mode:** Uses ``sk_test_*`` API keys - no real charges
72+
- **Live mode:** Uses ``sk_live_*`` API keys - real charges
73+
74+
**Each mode has its own webhooks configured separately in the Stripe Dashboard.**
75+
6476
Setting up Webhooks in Stripe
6577
-----------------------------
6678

67-
To receive real-time payment notifications from Stripe, follow these steps:
79+
**For Test Mode (Development):**
80+
81+
#. Log in to `Stripe Dashboard <https://dashboard.stripe.com/>`_ and switch to **Test mode** (toggle in top right).
82+
#. Navigate to **Developers** → **Webhooks**.
83+
#. Click **Add destination** then choose **Webhook**.
84+
#. Enter webhook URL using your **variant name**::
85+
86+
https://your-devel-server.com/payments/process/stripe-recurring/
6887

69-
#. Log in to your `Stripe Dashboard <https://dashboard.stripe.com/>`_.
70-
#. In the left sidebar, navigate to **Developers** → **Webhooks**.
71-
#. Click **+ Add endpoint** to create a new webhook listener.
72-
#. Enter the webhook URL in the "Endpoint URL" field. The URL should follow the
73-
format::
88+
**Important:** Use the variant name from ``PAYMENT_VARIANTS``, not ``<uuid:token>``
7489

75-
https://your-app.com/payments/process/{variant}/
90+
#. Select events (expand sections to find):
7691

77-
where ``{variant}`` is the name configured in ``PAYMENT_VARIANTS``.
78-
Example: ``https://your-app.com/payments/process/stripe/``
92+
**Checkout section:**
93+
- ``checkout.session.completed``
94+
- ``checkout.session.expired``
95+
- ``checkout.session.async_payment_succeeded``
96+
- ``checkout.session.async_payment_failed``
97+
98+
**Payment Intent section** (for recurring payments):
99+
- ``payment_intent.succeeded``
100+
- ``payment_intent.payment_failed``
101+
- ``payment_intent.requires_action``
102+
103+
#. Choose **"Your account"** for event source (not "Connected accounts").
104+
#. Click **Add destination** to save.
105+
#. Copy the **Signing secret** (starts with ``whsec_``) to your settings.
106+
107+
**For Live Mode (Production):**
108+
109+
Repeat the same steps but:
110+
- Switch to **Live mode** in Stripe Dashboard
111+
- Use your production domain in webhook URL
112+
- You'll get a different signing secret
113+
114+
**Configuration:**
115+
116+
.. code-block:: python
79117
80-
#. Select the events you want to receive notifications for. At a minimum,
81-
include these:
118+
# Test mode (development)
119+
PAYMENT_VARIANTS = {
120+
'stripe-recurring': (
121+
'payments.stripe.StripeProviderV3',
122+
{
123+
'api_key': 'sk_test_...', # Test key
124+
'endpoint_secret': 'whsec_...', # Test webhook secret
125+
}
126+
)
127+
}
128+
129+
# Live mode (production)
130+
PAYMENT_VARIANTS = {
131+
'stripe-recurring': (
132+
'payments.stripe.StripeProviderV3',
133+
{
134+
'api_key': 'sk_live_...', # Live key
135+
'endpoint_secret': 'whsec_...', # Live webhook secret
136+
}
137+
)
138+
}
82139
83-
- ``checkout.session.async_payment_failed``
84-
- ``checkout.session.async_payment_succeeded``
85-
- ``checkout.session.completed``
86-
- ``checkout.session.expired``
140+
**How Stripe webhooks work:**
87141

88-
#. Click **Add endpoint** to save the webhook configuration.
89-
#. Copy the **Signing secret** provided by Stripe. You will need this to verify
90-
webhook authenticity in your Django application.
91-
#. Test the webhook by sending a test event using Stripe's **Send test
92-
webhook** feature.
142+
Stripe sends all events to the same URL. The payment is identified by
143+
``client_reference_id`` in the webhook payload, which django-payments
144+
automatically extracts using ``get_token_from_request()``.
93145

94146
Testing Webhooks Locally
95147
------------------------

0 commit comments

Comments
 (0)