Record Stripe payment intent, export to CSV
This commit is contained in:
parent
36ecf098b0
commit
a74244efb4
8 changed files with 86 additions and 7 deletions
|
@ -1,3 +1,5 @@
|
|||
import os
|
||||
|
||||
from .base import * # NOQA
|
||||
|
||||
DEBUG = True
|
||||
|
@ -13,3 +15,6 @@ DATABASES = {
|
|||
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
|
||||
STRIPE_API_KEY = os.getenv('STRIPE_API_KEY', '')
|
||||
STRIPE_ENDPOINT_SECRET = os.getenv('STRIPE_ENDPOINT_SECRET', '')
|
||||
|
|
|
@ -37,3 +37,6 @@ def get_secret(secrets, setting):
|
|||
SECRET_KEY = get_secret(secrets, 'SECRET_KEY')
|
||||
|
||||
SESSION_COOKIE_SECURE = True
|
||||
|
||||
STRIPE_API_KEY = get_secret(secrets, 'STRIPE_API_KEY')
|
||||
STRIPE_ENDPOINT_SECRET = get_secret(secrets, 'STRIPE_ENDPOINT_SECRET')
|
||||
|
|
|
@ -13,6 +13,8 @@ class SustainerOrderAdmin(admin.ModelAdmin):
|
|||
fields = [
|
||||
'created_time',
|
||||
'paid_time',
|
||||
'payment_method',
|
||||
'payment_id',
|
||||
'name',
|
||||
'email',
|
||||
'amount',
|
||||
|
@ -26,6 +28,6 @@ class SustainerOrderAdmin(admin.ModelAdmin):
|
|||
'country',
|
||||
]
|
||||
|
||||
readonly_fields = ['created_time', 'paid_time']
|
||||
readonly_fields = ['created_time', 'paid_time', 'payment_method', 'payment_id']
|
||||
list_display = ['created_time', 'name', 'email', 'amount', 'paid']
|
||||
list_filter = ['paid_time']
|
||||
|
|
0
conservancy/supporters/management/commands/__init__.py
Normal file
0
conservancy/supporters/management/commands/__init__.py
Normal file
31
conservancy/supporters/management/commands/export_stripe.py
Normal file
31
conservancy/supporters/management/commands/export_stripe.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
import csv
|
||||
import sys
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from ...models import SustainerOrder
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Closes the specified poll for voting"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
orders = SustainerOrder.objects.filter(paid_time__isnull=False)
|
||||
columns = ['time', 'name', 'email', 'amount', 'transaction_id', 'public_ack', 'shirt_size', 'join_list', 'street', 'city', 'state', 'zip_code', 'country']
|
||||
writer = csv.writer(sys.stdout)
|
||||
writer.writerow(columns)
|
||||
for order in orders:
|
||||
writer.writerow([
|
||||
order.created_time,
|
||||
order.name,
|
||||
order.email,
|
||||
order.amount,
|
||||
order.payment_id,
|
||||
order.acknowledge_publicly,
|
||||
repr(order.tshirt_size if order.tshirt_size else ''),
|
||||
order.add_to_mailing_list,
|
||||
order.street,
|
||||
order.city,
|
||||
order.state,
|
||||
order.zip_code,
|
||||
order.country,
|
||||
])
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 4.2.11 on 2024-10-08 09:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supporters', '0003_remove_sustainerorder_monthly_recurring_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='sustainerorder',
|
||||
name='payment_id',
|
||||
field=models.CharField(blank=True, max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='sustainerorder',
|
||||
name='payment_method',
|
||||
field=models.CharField(default='Stripe', max_length=10),
|
||||
),
|
||||
]
|
|
@ -27,7 +27,7 @@ class SustainerOrder(models.Model):
|
|||
TSHIRT_CHOICES = [
|
||||
(
|
||||
'',
|
||||
(("None", "None"),),
|
||||
(("", "None"),),
|
||||
),
|
||||
(
|
||||
"Men's",
|
||||
|
@ -69,10 +69,12 @@ class SustainerOrder(models.Model):
|
|||
validators.MinValueValidator(100),
|
||||
])
|
||||
recurring = models.CharField(max_length=10)
|
||||
payment_method = models.CharField(max_length=10, default='Stripe')
|
||||
payment_id = models.CharField(max_length=255, blank=True)
|
||||
paid_time = models.DateTimeField(null=True, blank=True)
|
||||
acknowledge_publicly = models.BooleanField(default=True)
|
||||
add_to_mailing_list = models.BooleanField(default=True)
|
||||
tshirt_size = models.CharField(max_length=50, choices=TSHIRT_CHOICES)
|
||||
tshirt_size = models.CharField(max_length=50, choices=TSHIRT_CHOICES, blank=True)
|
||||
street = models.CharField(max_length=255, blank=True)
|
||||
city = models.CharField(max_length=255, blank=True)
|
||||
state = models.CharField(max_length=255, blank=True)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from datetime import datetime
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render, redirect
|
||||
from django.utils import timezone
|
||||
|
@ -47,6 +48,7 @@ def sponsors(request):
|
|||
|
||||
def create_checkout_session(reference_id, email: str, amount: int, recurring: str, base_url: str):
|
||||
# https://docs.stripe.com/payments/accept-a-payment
|
||||
# https://docs.stripe.com/api/checkout/sessions
|
||||
YOUR_DOMAIN = base_url
|
||||
try:
|
||||
checkout_session = stripe.checkout.Session.create(
|
||||
|
@ -94,7 +96,10 @@ def sustainers_stripe2(request):
|
|||
return render(request, 'supporters/sustainers_stripe2.html', {'form': form})
|
||||
|
||||
|
||||
stripe.api_key = 'sk_test_zaAqrpHmpkXnHQfAs4UWkE3d'
|
||||
stripe.api_key = settings.STRIPE_API_KEY
|
||||
if stripe.api_key == '':
|
||||
logger.warning('Missing STRIPE_API_KEY')
|
||||
|
||||
|
||||
def fulfill_checkout(session_id):
|
||||
print("Fulfilling Checkout Session", session_id)
|
||||
|
@ -108,7 +113,7 @@ def fulfill_checkout(session_id):
|
|||
# Retrieve the Checkout Session from the API with line_items expanded
|
||||
checkout_session = stripe.checkout.Session.retrieve(
|
||||
session_id,
|
||||
expand=['line_items'],
|
||||
expand=['line_items', 'invoice'],
|
||||
)
|
||||
|
||||
# Check the Checkout Session's payment_status property
|
||||
|
@ -122,6 +127,12 @@ def fulfill_checkout(session_id):
|
|||
try:
|
||||
order = SustainerOrder.objects.get(id=checkout_session['client_reference_id'], paid_time=None)
|
||||
order.paid_time = timezone.now()
|
||||
if checkout_session['payment_intent']:
|
||||
# Payments get a payment intent directly
|
||||
order.payment_id = checkout_session['payment_intent']
|
||||
else:
|
||||
# Subscriptions go get a payment intent generated on the invoice
|
||||
order.payment_id = checkout_session['invoice']['payment_intent']
|
||||
order.save()
|
||||
logger.info(f'Marked sustainer order {order.id} (order.email) as paid')
|
||||
except SustainerOrder.DoesNotExist:
|
||||
|
@ -139,7 +150,9 @@ def webhook(request):
|
|||
event = None
|
||||
|
||||
# From webhook dashboard
|
||||
endpoint_secret = 'whsec_lLy9pqxAAHdl4fwiC0cFg1KwR6y4CvOH'
|
||||
endpoint_secret = settings.STRIPE_ENDPOINT_SECRET
|
||||
if endpoint_secret == '':
|
||||
logger.warning('Missing STRIPE_ENDPOINT_SECRET')
|
||||
|
||||
try:
|
||||
event = stripe.Webhook.construct_event(
|
||||
|
|
Loading…
Reference in a new issue