Reputation: 21
I have a django project that takes payments and I need to update my database with a new owed balance of 0 after the paypal transaction is complete. I'm a newbie to javascript and the paypal docs aren't being helpful. here's my code:
I need to create a new payment from this and update the invoice with the correct amount owed.
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="card card-primary">
<div class="card-header">
<h2>Make a Payment</h2>
</div>
<div class="float-right list-group-item">
<p class="font-weight-bold float-left p-0 m-0">Invoice Number</p>
<p class="font-weight-bold float-right p-0 m-0">{{ object.pk }}</p>
</div>
<div class="float-right list-group-item">
<p class="font-weight-bold float-left p-0 m-0">Amount Billed</p>
<p class="font-weight-bold float-right p-0 m-0">${{ object.amount_billed }}</p>
</div>
<div class="float-right list-group-item">
<p class="font-weight-bold float-left p-0 m-0">Amount Owed</p>
<p class="font-weight-bold float-right p-0 m-0">${{ object.amount_owed }}</p>
</div>
<div class="float-right list-group-item">
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
</div>
<div class="float-right list-group-item">
<a href="{% url 'invoice-list'%}"><button type="button" class="btn btn-primary float-right">Go back</button></a>
</div>
</div>
<!-- Include the PayPal JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?client-id=AeFSJDq8sonOdMT62SM-B040Eo4YWi6IS6xsPqDe-eamtEbGs9Jtbf5AbtwjnPC45LjFPOCa4sNoHEIt¤cy=USD&disable-funding=credit&commit=false"></script>
<script>
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
// Set up the transaction
createOrder: function (data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: {{ object.amount_owed_as_string }}
}
}]
});
},
// Finalize the transaction
onApprove: function (data, actions) {
return actions.order.capture().then(function (details) {
// Show a success message to the buyer
alert('Transaction completed by ' + details.payer.name.given_name + '!');
});
}
}).render('#paypal-button-container');
</script>
{% endblock content %}
{% extends "base.html" %}
{% block content %}
<div class="card p-4 float">
<div class="card-header mb-3"><h3>Invoices - {{ user.get_full_name }}</h3></div>
<div class="card">
<div class="list-group">
<div class="list-group-item list-group-item-action active disabled">
<p class="float-left">Invoice Number</p>
<p class="float-right">Amount Owed</p>
</div>
{% for invoice in user.invoice_set.all %}
<a href="{% url 'make-payment' pk=invoice.pk %}" class="list-group-item list-group-item-action
{% if invoice.amount_owed <= 0 %} disabled {% endif %}">
<p class="float-left">{{ invoice.pk}}</p>
<p class="float-right">${{ invoice.amount_owed }}</p>
</a>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
This is models.py for the payments application
from django.db import models
from django.contrib.auth.models import User
from django.contrib.admin.utils import timezone
class Invoice(models.Model):
# invoice number is it's primary key
patient = models.ForeignKey(User, on_delete=models.CASCADE)
amount_owed = models.DecimalField(decimal_places=2, max_digits=8)
amount_billed = models.DecimalField(decimal_places=2, max_digits=8)
date_billed = models.DateField(default=timezone.now)
def amount_owed_as_string(self):
return str(self.amount_owed)
def __str__(self):
return str(self.pk) + " - " + str(self.amount_billed)
class Payment(models.Model):
payment_method = models.CharField(max_length=15)
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE)
payment_amount = models.DecimalField(decimal_places=2, max_digits=8)
def __str__(self):
return str(self.invoice.pk) + " - " + str(self.payment_amount)
views.py
from django.views.generic import ListView, DetailView
from .models import Payment, Invoice
class PaymentList(ListView):
model = Payment
paginate_by = 15
ordering = ['payment_amount']
template_name = 'payment_list.html'
class MakePayment(DetailView):
model = Invoice
template_name = 'make_payment.html'
class InvoiceList(ListView):
model = Invoice
paginate_by = 15
ordering = ['date_billed']
template_name = 'invoice_list.html'
Upvotes: 2
Views: 528
Reputation: 30379
onApprove: function (data, actions) {
return actions.order.capture().then(function (details) {
// Show a success message to the buyer
alert('Transaction completed by ' + details.payer.name.given_name + '!');
});
}
This is where you need to add your own JS code that
Note that this is an insecure, client-side-only design of payment creation and capture.
For a secure solution, you need to call the v2/orders API from your server. Here is a front-end that uses that pattern, communicating via fetch() with routes on your server (which you need to implement, which would then call the PayPal v2/orders API) https://developer.paypal.com/demo/checkout/#/pattern/server
Upvotes: 1