List all the credit cards and the ability to add more cards
This commit is contained in:
parent
7986b825a7
commit
1c3d3efb3a
22 changed files with 528 additions and 158 deletions
|
|
@ -58,7 +58,7 @@ class StripeCustomer(models.Model):
|
|||
class StripeCreditCard(models.Model):
|
||||
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
||||
|
||||
card_name = models.CharField(null=False, max_length=128, default="My credit card")
|
||||
card_name = models.CharField(null=False, max_length=128, default="")
|
||||
card_id = models.CharField(null=False, max_length=32)
|
||||
last4 = models.CharField(null=False, max_length=4)
|
||||
brand = models.CharField(null=False, max_length=64)
|
||||
|
|
@ -76,6 +76,16 @@ class StripeCreditCard(models.Model):
|
|||
def __str__(self):
|
||||
return f"{self.card_name}: {self.brand} {self.last4} ({self.expiry_date})"
|
||||
|
||||
def delete(self, **kwargs):
|
||||
uncloud_pay.stripe.delete_card(self.card_id)
|
||||
super().delete(**kwargs)
|
||||
|
||||
|
||||
def activate(self):
|
||||
StripeCreditCard.objects.filter(owner=self.owner, active=True).update(active=False)
|
||||
self.active = True
|
||||
self.save()
|
||||
|
||||
class Payment(models.Model):
|
||||
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
||||
type = models.CharField(max_length=256,
|
||||
|
|
@ -125,6 +135,7 @@ class Payment(models.Model):
|
|||
return cls.objects.create(owner=owner, type="withdraw", amount=amount,
|
||||
currency=currency, notes=notes)
|
||||
|
||||
|
||||
|
||||
# See https://docs.djangoproject.com/en/dev/ref/models/fields/#field-choices-enum-types
|
||||
class RecurringPeriodDefaultChoices(models.IntegerChoices):
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from django.contrib.auth import get_user_model
|
|||
from rest_framework import serializers
|
||||
from uncloud_auth.serializers import UserSerializer
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from stripe.error import CardError
|
||||
|
||||
from .models import *
|
||||
import uncloud_pay.stripe as uncloud_stripe
|
||||
|
|
@ -25,13 +26,17 @@ class PaymentSerializer(serializers.ModelSerializer):
|
|||
read_only_fields = [ "external_reference", "source", "timestamp" ]
|
||||
|
||||
def validate(self, data):
|
||||
payment_intent = uncloud_stripe.charge_customer(data['owner'],
|
||||
data['amount'])
|
||||
|
||||
data["external_reference"] = payment_intent["id"]
|
||||
data["source"] = "stripe"
|
||||
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
try:
|
||||
if validated_data['type'] == 'deposit':
|
||||
return Payment.deposit(validated_data['owner'], validated_data['amount'], validated_data['source'], currency=validated_data['currency'], notes=validated_data['notes'])
|
||||
else:
|
||||
return Payment.objects.create(**validated_data)
|
||||
except CardError as err:
|
||||
raise serializers.ValidationError(err.user_message)
|
||||
|
||||
class BalanceSerializer(serializers.Serializer):
|
||||
balance = serializers.DecimalField(max_digits=AMOUNT_MAX_DIGITS, decimal_places=AMOUNT_DECIMALS)
|
||||
|
|
|
|||
|
|
@ -94,8 +94,11 @@ def get_card_from_payment(user, payment_method_id):
|
|||
|
||||
|
||||
@handle_stripe_error
|
||||
def attach_payment_method(payment_method_id, customer_id):
|
||||
return stripe.PaymentMethod.attach(payment_method_id, customer=customer_id)
|
||||
def attach_payment_method(payment_method_id, user):
|
||||
customer_id = get_customer_id_for(user)
|
||||
ret = stripe.PaymentMethod.attach(payment_method_id, customer=customer_id)
|
||||
sync_cards_for_user(user)
|
||||
return ret
|
||||
|
||||
@handle_stripe_error
|
||||
def create_customer(name, email):
|
||||
|
|
@ -107,7 +110,6 @@ def get_customer(customer_id):
|
|||
|
||||
@handle_stripe_error
|
||||
def get_customer_cards(customer_id):
|
||||
print(f"getting cards for: {customer_id}")
|
||||
|
||||
cards = []
|
||||
stripe_cards = stripe.PaymentMethod.list(
|
||||
|
|
@ -127,6 +129,10 @@ def get_customer_cards(customer_id):
|
|||
|
||||
return cards
|
||||
|
||||
@handle_stripe_error
|
||||
def delete_card(card_id):
|
||||
return stripe.PaymentMethod.detach(card_id)
|
||||
|
||||
def sync_cards_for_user(user):
|
||||
customer_id = get_customer_id_for(user)
|
||||
cards = get_customer_cards(customer_id)
|
||||
|
|
|
|||
9
uncloud_pay/urls.py
Normal file
9
uncloud_pay/urls.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from django.urls import path, include
|
||||
from django.conf import settings
|
||||
from .views import *
|
||||
|
||||
app_name = 'uncloud_pay'
|
||||
|
||||
urlpatterns = [
|
||||
path('cards/activate', CardActivateView.as_view(), name='card_activate'),
|
||||
]
|
||||
|
|
@ -38,14 +38,32 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
class PricingView(View):
|
||||
def get(self, request, **args):
|
||||
address = get_billing_address_for_user(self.request.user)
|
||||
vat_rate = False
|
||||
vat_validation_status = False
|
||||
if address:
|
||||
vat_rate = VATRate.get_vat_rate(address)
|
||||
vat_validation_status = "verified" if address.vat_number_validated_on and address.vat_number_verified else False
|
||||
pricing = get_order_total_with_vat(
|
||||
request.GET.get('cores'),
|
||||
request.GET.get('memory'),
|
||||
request.GET.get('storage'),
|
||||
pricing_name = args['name']
|
||||
pricing_name = args['name'],
|
||||
vat_rate = vat_rate * 100,
|
||||
vat_validation_status = vat_validation_status
|
||||
)
|
||||
return JsonResponse(pricing)
|
||||
|
||||
class CardActivateView(View):
|
||||
def post(self, request, **args):
|
||||
card_id = request.POST.get('card_id')
|
||||
if card_id:
|
||||
matched_card = StripeCreditCard.objects.filter(owner=self.request.user, card_id=card_id).first()
|
||||
matched_card.activate()
|
||||
return JsonResponse({'success': 1})
|
||||
else:
|
||||
return JsonResponse({'error': "Please select a card"})
|
||||
|
||||
class RegisterCard(TemplateView):
|
||||
template_name = "uncloud_pay/register_stripe.html"
|
||||
|
||||
|
|
@ -55,7 +73,6 @@ class RegisterCard(TemplateView):
|
|||
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
customer_id = uncloud_stripe.get_customer_id_for(self.request.user)
|
||||
setup_intent = uncloud_stripe.create_setup_intent(customer_id)
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue