cantony2
cantony2

Reputation: 13

Why am I getting an incorrect payment total via Stripe in Python?

I'm trying to make a payment through the ecommerce website I created. The payment successfully went through but the total amount charged is different than what I wanted to charge. For example, I want to charge $29.19 but I get charged $2,918.90. I know it has something to do with the decimal places, but I seem to have it correct; 2 decimal places.

I tried adding decimal to the subtotal, tax, and shipping to get a decimal total, though it came, I still had a wrong total amount.

My cart.py:

def get_total(self):
        
        subtotal = sum(Decimal(item['price']) * int(item['quantity']) for item in self.cart.values())
        tax = Decimal('0.10')
        tax_price = sum(Decimal(item['price']) * int(item['quantity']) for item in self.cart.values()) * Decimal(tax)

        shipping_cost = 5
        total = Decimal(subtotal) + Decimal(tax_price) + Decimal(shipping_cost)
        return total

My Payment views.py:

@login_required
def CartView(request):
    cart = Cart(request)
    total = str(cart.get_total())
    total = total.replace('.', '')

    stripe.api_key = ''
    intent = stripe.PaymentIntent.create(
        amount=total,
        currency='usd',
        metadata={'userid': request.user.id}
    )

Order class:

total_paid = models.DecimalField(max_digits=5, decimal_places=2)

OrderItem class:

price = models.DecimalField(max_digits=5, decimal_places=2)

Upvotes: 0

Views: 575

Answers (1)

supsayan
supsayan

Reputation: 56

If you look at the PaymentIntent object in the Stripe documentation you can see that the amount parameter accepts the price in the smallest currency unit.

Amount intended to be collected by this PaymentIntent. A positive integer representing how much to charge in the smallest currency unit (e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal currency).

If you want to charge $1.00 the amount you pass to the PaymentIntent should be 100. If you want to charge $29.19 the amount you pass should be 2919.

Instead of total = total.replace('.', '') try making a int amount and multiply it by a 100 (or store the prices in the cents beforehand).

Upvotes: 2

Related Questions