Download file after payment with Django

644 Views Asked by At

I am building a digital ecommerce platform with Django. When my customers pay for a digital product, I want that the digital product gets downloaded immedately after payment. So when they complete a payment they get automatically the file downloaded.

For now after a payment I am getting rendered back to the home page and get a succesful payment. But instead of rendering back to home page I want the file to be downloaded after payment, so I want to be rendered to something like I return redirect( {{item.file.url}} ) instead of return redirect("/" ) (see last line of Views). My code in Views and Models is as follows:

Views

class PaymentView(View):
     def get(self, *args, **kwargs):
          order = Order.objects.get(user=self.request.user, ordered=False)
          context = {
               'order': order
          }
          return render(self.request, 'dashtemplates/payment.html', context)

     def post(self, *args, **kwargs):
          order = Order.objects.get(user=self.request.user, ordered=False)
          token = self.request.POST.get('stripeToken')
          amount = int(order.get_total() * 100)

          try:
               charge = stripe.Charge.create(
                    amount=amount,
                    currency="usd",
                    source=token
               )

               #create payment
               payment = Payment()
               payment.stripe_charge_id = charge['id']
               payment.user = self.request.user
               payment.amount = order.get_total()
               payment.save()

               #assign the payment to the order
               order_items = order.items.all()
               order_items.update(ordered=True)
               for item in order_items:
                    item.save()

               order.ordered = True
               order.payment = payment
               order.save()

               messages.success(self.request, "Your order was succesful!")
               return redirect("/" )

Models

class Item(models.Model):
    title = models.CharField(max_length=100)
    price = models.FloatField()
    category = models.CharField(choices=CATEGORY_CHOICES, max_length=20)
    slug = models.SlugField()
    description = models.TextField()
    image = models.ImageField()
    file = models.FileField()
1

There are 1 best solutions below

1
On

The problem with this approach is, the user with the download link could share it so any person with the link could download that file .

One way of avoiding this is to redirect to a download view which return s a FileResponse, that view will ensure that the user is authenticated then retrieve the File linked to their purchase and return a FileResponse

This way you ensure that only authenticated user that paid for a given file could download that file