user8887187
user8887187

Reputation:

Why is the View returning None when I navigate to the payment page in Django?

The rest of the application is working well but a problem arises when I navigate to the payment page, the app returns None. I can't figure out where the error is.

This is the payment_page.html, the error arises when I try to access this page

{% extends 'customer/base.html' %}
{% load bootstrap4 %}

{% block head %}
<script src="https://js.stripe.com/v3/"></script>
{% endblock %}

{% block main %}

{% if not request.user.customer.stripe_payment_method_id %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
    Let's add your credit / debit card to <strong>Create a Job</strong>
    <button type="button" class="close" data-dismiss="alert">
    <span aria-hidden="true">&times;</span>
    </button>
</div>
{% endif %}

<b class="text-secondary">Your Credit / Debit Card</b>

<style>
    .StripeElement {
        height: 40px;
        padding: 10px 12px;
        width: 100%;
        color: #32325d;
        background-color: white;
        /*border: 1px solid transparent; */
        border: 1px solid #cfd7da;
        border-radius: 4px;

    }

    .StripeElement--focus {
        border-color: #80bdff;
        box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, .25);

    }

    .StripeElement--invalid {
        border-color: #fa755a;
    }

    .StripeElement--webkit-autofill {
        background-color: #fefde5 !important;
    }
</style>

<div class="card bg-white mt-2 mb-5">
    <div class="card-body">
        {% if request.user.customer.stripe_payment_method_id %}
        <div id="change-card" class="input-group">
            <input type="text" class="form-control" disabled
                value="****  **** **** {{request.user.customer.stripe_card_last4}}">
            <div class="input-group-append">
                <form method="POST">
                    {% csrf_token %}
                    <button type="submit" class="btn btn-danger">Remove</button>
                </form>
            </div>
        </div>
        {% else %}
        <form id="setup-form" data-secret="{{ client_secret }}">
            <div id="card-element"></div>
            <button id="card-button" class="btn btn-warning mt-3" type="button">
                Save Card
            </button>
        </form>
        {% endif %}
    </div>
</div>
{% if not request.user.customer.stripe_payment_method_id %}

<script>
    var stripe = Stripe("{{ STRIPE_API_PUBLIC_KEY }}");

    var elements = stripe.elements();
    var cardElement = elements.create('card');
    cardElement.mount('#card-element');


    //setting up stripe info
    var cardholderName = document.getElementById('cardholder-name');
    var cardButton = document.getElementById('card-button');
    var clientSecret = "{{ client_secret}}";

    cardButton.addEventListener('click', function (ev) {
        ev.preventDefault();
        stripe.confirmCardSetup(
            clientSecret,
            {
                payment_method: {
                    card: cardElement,
                },
            }
        ).then(function (result) {
            if (result.error) {
                // Display error.message in your UI.
                console.log(result.error.message, 'error');
                toast(result.error.message, 'error')


            } else {
                // The setup has succeeded. Display a success message.
                console.log("Payment method is added", 'success');
                toast("Payment method is added", 'success');
                window.location.reload();
            }
        });
    });

</script>
{% endif %}
{% endblock %}

This is the payment method in the view, it failing to return an HttpResponse object it's instead returning None.


# Method for processing payments
def payment_method_page(request):
    current_customer = request.user.customer
    
    #Remove existing card
    if request.method == "POST":
        stripe.PaymentMethod.detach(current_customer.stripe_payment_method_id)
        current_customer.stripe_payment_method_id = ""
        current_customer.stripe_card_last4= ""
        current_customer.save()
        return redirect(reverse('customer:payment_method'))
        
    #Save Stripe customer info
    if not current_customer.stripe_customer_id:
        customer = stripe.Customer.create()
        current_customer.stripe_customer_id = customer['id']
        current_customer.save()
        
    #GEt Stripe payment method
    stripe_payment_methods = stripe.PaymentMethod.list(
        customer = current_customer.stripe_customer_id,
        type = "card",
    )
    print(stripe_payment_methods)
    
    if stripe_payment_methods and len(stripe_payment_methods.data) > 0:
        payment_method = stripe_payment_methods.data[0]
        current_customer.stripe_payment_method_id = payment_method.id
        current_customer.stripe_card_last4 = payment_method.card.last4
        current_customer.save()
    
    else: 
         current_customer.stripe_payment_method_id = ""
         current_customer.stripe_card_last4 = ""
         current_customer.save()
    
    if not current_customer.stripe_payment_method_id:
        
        intent = stripe.SetupIntent.create(
            customer  = current_customer.stripe_customer_id
        )
        return render(request, 'customer/payment_method.html', {
            "client_secret": intent.client_secret,
            "STRIPE_API_PUBLIC_KEY": settings.STRIPE_API_PUBLIC_KEY
        })
    else:
        render(request, 'customer/payment_method.html')


Upvotes: 0

Views: 40

Answers (1)

Agate
Agate

Reputation: 3232

I think render(request, 'customer/payment_method.html') (the last line of your view) is the culprit here. You should probably use return render(request, 'customer/payment_method.html') to solve the issue.

Upvotes: 1

Related Questions