Field 'card_exp_month' expected a number but got (4,) - Django and stripe API when adding to model

Viewed 18

I'm writing a second ecommerce site. The first one seems to work perfectly well when downloading data from the stripe API. It extracts the card details and saves the information to the model perfectly. The second site, I keep getting the following error and I can't see why. Any help to track this down would be great!

Field 'card_exp_month' expected a number but got (4,). 

This is the code which is being run to save the data I'm getting:

def process_card(order, charge):
    print("I HAVE THE DATA AS: ", charge)
    print("I have the brand as: ", charge.payment_method_details.card.brand)
    print("I have the expiry year as: ", charge.payment_method_details.card.exp_year)
    print("I have the expiry month as: ", charge.payment_method_details.card.exp_month)
    print("I have the last 4 as: ", charge.payment_method_details.card.last4)
    payment = order.payment
    payment.stripe_payment_intent = order.stripe_payment_intent
    payment.total_paid = Money(charge.amount / 100, charge.currency)
    payment.card_brand = str(charge.payment_method_details.card.brand),
    payment.card_exp_year = int(charge.payment_method_details.card.exp_year),
    payment.card_exp_month = int(charge.payment_method_details.card.exp_month),
    payment.card_last4 = str(charge.payment_method_details.card.last4),
    payment.receipt_url = charge.receipt_url
    payment.save()
    order.stripe_payment_intent = None
    order.order_flow = "PAID"
    order.save()

When I view the console I get the following output which seems to show the correct values followed by the error message!

I have the brand as:  visa
I have the expiry year as:  2024
I have the expiry month as:  4
I have the last 4 as:  4242
3 I have an error as:  Field 'card_exp_month' expected a number but got (4,).

The print statement is showing just the number 4, but when I use the same code in a later line it's becoming (4,)???

My model is defined as follows:

class Payment(models.Model):
    order = models.OneToOneField(Order, on_delete=models.CASCADE, null=False, blank=False)
    stripe_payment_intent = models.CharField(max_length=30, blank=True, null=True)
    total_paid = MoneyField(max_digits=6, decimal_places=2, blank=False, null=False, default=0.00,
                            default_currency='AUD')
    discount = MoneyField(max_digits=6, decimal_places=2, blank=False, null=False, default=0.00, default_currency='AUD')
    refund_amount = MoneyField(max_digits=6, decimal_places=2, blank=False, null=False, default=0.00,
                               default_currency='AUD')
    card_brand = models.CharField(max_length=10, null=True)
    card_exp_month = models.SmallIntegerField(null=True)
    card_exp_year = models.SmallIntegerField(null=True)
    card_last4 = models.CharField(max_length=4, null=True)
    receipt_url = models.TextField(null=True, blank=False)
    created_at = models.DateTimeField(default=timezone.now, blank=False)
    updated_at = models.DateTimeField(default=timezone.now, blank=False)

    def __str__(self):
        return self.order.order_number

The data which is coming from the Stripe API is:

"payment_method_details": {
    "card": {
      "brand": "visa",
      "checks": {
        "address_line1_check": null,
        "address_postal_code_check": "pass",
        "cvc_check": "pass"
      },
      "country": "US",
      "exp_month": 4,
      "exp_year": 2024,
      "fingerprint": "z6FNTx3llenE17ly",
      "funding": "credit",
      "installments": null,
      "last4": "4242",
      "network": "visa",
      "three_d_secure": null,
      "wallet": null
    },
    "type": "card"
  },

Any help you might be able to give would be great.

1 Answers

Once again, a small error and a massive amount of time wasted.

But ... if someone else comes across the same problem, the commas at the end of the lines where I'm assigning the values was causing the problem:

    payment.card_brand = str(charge.payment_method_details.card.brand),
    payment.card_exp_year = int(charge.payment_method_details.card.exp_year),
    payment.card_exp_month = int(charge.payment_method_details.card.exp_month),

Removing the commas made it work as expected!

    payment.card_brand = str(charge.payment_method_details.card.brand)
    payment.card_exp_year = int(charge.payment_method_details.card.exp_year)
    payment.card_exp_month = int(charge.payment_method_details.card.exp_month)
Related