Record Stripe payment intent, export to CSV

This commit is contained in:
Ben Sturmfels 2024-10-09 02:01:32 +11:00
parent 36ecf098b0
commit a74244efb4
Signed by: bsturmfels
GPG key ID: 023C05E2C9C068F0
8 changed files with 86 additions and 7 deletions

View file

@ -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', '')

View file

@ -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')

View file

@ -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']

View 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,
])

View file

@ -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),
),
]

View file

@ -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)

View file

@ -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(