Update user credit card details using Stripe + Django
Tags: python, django, tutorial, webdev
Published: 2022-03-18 00:27:34

So you're making a web app/site that accepts payments using the powerful Django web framework and the world's leading payment's processor stripe, however there comes a time when your user ends up in one of the following situations :

- Card expired
- Change who's paying 
- Got a lot of cards and wanna switch?

Either way the ability to change your payment details within a website/app is a necessity and in this tutorial you'll learn exactly how to do it.

## The front end

<hr>
**index.html**
```html
<form method="post" id="payment-form">
            {% csrf_token %}
            <div class="col-md-4 form-row">
                <label for="card-element">Credit or Debit Card</label>

                <div id="card-element">

                </div>

                <div id="alert alert-warning card-errors" role="alert"></div>
                <br>
                <br>
                <button class="btn btn-outline-dark" type="submit" class="btn pay-btn col-sm-2">Update</button>
            </div>
        </form>
```

<hr>
**style.css**

```css
.StripeElement {
            box-sizing: border-box;
            
            height: 40px;
            
            padding: 10px 12px;
            
            border: 1px solid transparent;
            border-radius: 4px;
            background-color: white;
            
            box-shadow: 0 1px 3px 0 #e6ebf1;
            -webkit-transition: box-shadow 150ms ease;
            transition: box-shadow 150ms ease;
            }
            
            .StripeElement--focus {
            box-shadow: 0 1px 3px 0 #cfd7df;
            }
            
            .StripeElement--invalid {
            border-color: #fa755a;
            }
            
            .StripeElement--webkit-autofill {
            background-color: #fefde5 !important;
            }
```

<hr>
**script.js**

```javascript
var stripe = Stripe("PUBLIC_STRIPE_TOKEN");
        // Create an instance of Elements.
        var elements = stripe.elements();

        // Custom styling can be passed to options when creating an Element.
        // (Note that this demo uses a wider set of styles than the guide below.)
        var style = {
        base: {
            color: '#32325d',
            fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
            fontSmoothing: 'antialiased',
            fontSize: '16px',
            '::placeholder': {
            color: '#aab7c4'
            }
        },
        invalid: {
            color: '#fa755a',
            iconColor: '#fa755a'
        }
        };

        // Create an instance of the card Element.
        var card = elements.create('card', {style: style});

        // Add an instance of the card Element into the `card-element` <div>.
        card.mount('#card-element');

        // Handle real-time validation errors from the card Element.
        card.addEventListener('change', function(event) {
        var displayError = document.getElementById('card-errors');
        if (event.error) {
            displayError.textContent = event.error.message;
        } else {
            displayError.textContent = '';
        }
        });

        // Handle form submission.
        var form = document.getElementById('payment-form');
        form.addEventListener('submit', function(event) {
        event.preventDefault();

        stripe.createToken(card).then(function(result) {
            if (result.error) {
            // Inform the user if there was an error.
            var errorElement = document.getElementById('card-errors');
            errorElement.textContent = result.error.message;
            } else {
            // Send the token to your server.
            stripeTokenHandler(result.token);
            }
        });
        });

        // Submit the form with the token ID.
        function stripeTokenHandler(token) {
        // Insert the token ID into the form so it gets submitted to the server
        var form = document.getElementById('payment-form');
        var hiddenInput = document.createElement('input');
        hiddenInput.setAttribute('type', 'hidden');
        hiddenInput.setAttribute('name', 'stripeToken');
        hiddenInput.setAttribute('value', token.id);
        form.appendChild(hiddenInput);

        // Submit the form
        form.submit();
        }
```

## Finally...The backend
<hr>

So the logic here is that we want to capture the stripe token that is sent back to us after the user submits his/her card info so now the ball is in the server side's court so we need to capture that token and then using that create the source for the stripe customer and finally extract the card ID from the **card_data** object and finally pass that card ID to the modify_source() method as shown below and voila! You are done!

**views.py**
```python
from django.shortcuts import render 
import stripe 

stripe.api_key = 'YOUR_STRIPE_SECRET_KEY'

card_data = stripe.Customer.create_source(
      user_setting.stripe_customer_id,
      source=request.POST['stripeToken']
)
            
stripe.Customer.modify_source(
      user_setting.stripe_customer_id,
      card_data['id']
)

return redirect('some-view-name')
```

Just add the following code to the Django view you are wanting to set as the payment details update page.

If you have any questions go ahead and comment down below :-)

Hope you found this tutorial helpful!