Django: Handling post transaction logic - django

Common use case:
User select item to add to cart
User makes payment via off site payment gateway such as paypal or
worldpay
User gets redirect to payment page and makes payment
Payment portal sends a POST request to a callback URL
User gets redirected back to your page
On Step 4, typically the following things happen:
Error handling and anti fraud checking
Updating of order/cart models and additional logic
My question is pertaining to this step 4:
In apps like Django-Paypal, rather than do all the logic processing on the callback url view function, signals are used instead. Is there a good reason for this? Why not just do all the logic on the callback url view function?

The use of signals decouples django-paypal from your own apps. You can have all kinds of crazy custom stuff happening on payment success or failure in your projects and still use the default provided view.
The class based views in Django 1.3 do make it possible to extend views, and provide an alternative way to decoupling an apps view.
Other considerations you should have before putting logic in views is time; if logic could take a long time (like any I/O), ask yourself if they are crucial to the Response at hand and consider putting it in a task queue, so you can handle the Request quickly, without blocking.

Related

How to connect a payment system in django?

I'm new to the Django framework and I don't quite understand how to connect the payment system to the site, at the same time, so that part of the payment for the product goes to the balance of the user who exposed it, and 10%-20% of the amount goes to the balance of the service. And what is the best way to connect a payment system for individuals.faces?
So, you need to answer yourself a few questions like:
What payment provider I need? It need to be paypal, stripe or...?
If I know what payment provider I need, is there package for django (or python) for it?
If yes, it is up-to-date?
If no, were there updates to API or solutions described in payment provider documentation?
Are they better in any term?
Depending on these answers, you could go straightforward to implementing payments using external library (for e.g. https://django-paypal.readthedocs.io/en/latest/) or just implement it yourself. In my situation when I implemented paypal payments in e_commerce store I just went with paypal buttons because they were looking better, and they, so far work more nicely.
What also you must mostly implement is something that Paypal calls IPN (instant payment notifications). Stripe, and for example TPay also has IPN-like mechanisms. The IPN is simply an view (functional or generic) that handles payments using data with usually md5 verification, where you update status of order to COMPLETED or et cetera.
The lack of security validation can make endpoint vulnerable to custom requests made by postman, curl or any kind of HTTP-testing tool.
For models - you should write them yourself or use provided by package. This usually means that with multiple payments you store one model per provider with ForeignKey to Order global model that collects all the data. You could use also abstract models for implementing multiple models with similar fields, but this causes some database query issues for additional logic handling (you can't query abstract models, so you need to parse stuff using forloops when you need it instead of using filters).
Frontend is also depending what you will use, but remember about not having price as hidden input :)
The thread is much bigger as it seems, but I hope I gave you point-of-view of the topic.

How to implement a manual security procedure with Django

I'm writing a web application with Django framework. This web application is API based and I'm using Django rest_framework. I have a security issue: On the first page, the user must solve a Recaptcha. After solving the Recaptcha my site gives a session ID to the user and after this, the user must post this session ID in the body of all his/her API calls and every API can be called just once with a specific session ID. In other words, I have a state machine for the APIs being called by the user and in each state, the user can call the APIs which have corresponding outgoing edges from that state.
The purpose of all of the above procedures is preventing the user from crawling my website. (User can't call an API many times with a session ID and he/she should act as a normal user and call every API at most two or three times)
Now my question is that how should I handle this in my Django app? Before this, I just used the ordinary Django session middleware for handling sessions. Now should I handle the authentication process and passing and getting session ID completely in a manual way or is there a way in which I can use that middleware that it can be able to handle my procedure.
You can do this with simply with saving your user's state and in each step update your user's state and consider the next states which user can see.
Use custom permission classes for your APIViews to block such request.
Read more here https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

How to use Pusher with Django?

I am trying to build an app using pusher and django. I went through few of the links like https://github.com/pusher/django-pusherable, but it lacked an example and thus was difficult to understand! Can anyone please help in here?
And also what are channels in here and thus how to create a follow-following system with feeds(activity streams)?
Thanks!
Pusher allows you to easily implement a publish/subscribe pattern for messaging (also called pub/sub for short).
In this pattern, there are a number of channels. Each channel is like a radio station's frequency. A publisher puts messages on a channel, and any subscribers (listeners) that are listening to that channel will receive the message.
The publisher does not know how many people are listening to a particular channel, it just sends the message. It is up to the subscribers to listen to the channels that they are interested in.
Practically speaking, a channel is usually contains an event type; so subscribers can decide what to do with the data depending on the event type. This is sometimes also called a message class.
For example, stock updates can be a channel. The publisher (your backend script) will push a message to this channel whenever there is a change in stock; any and all clients listening on this channel will get that message.
Read more about channels at the API guide for channels.
Pusher takes care of managing the channels and giving you the tools to write listeners.
In your example each user would have their own activity stream channel. Followers (these can be users) can subscribe to listen on the channel of the user they are interested in.
Your system simply publishes updates for all channels.
In code, this would work like this (example from the pusher docs) - from the publisher (backend) side:
from pusher import Pusher
pusher.trigger(u'test-channel', u'my-event', {u'message': u'hello world'})
From the consumer (client) side:
var channel = pusher.subscribe('test-channel');
channel.bind('my-event', function(data) {
alert('An event was triggered with message: ' + data.message);
});
Once that is clear, lets move to django.
The django-pusherable module just makes it easy to create channels by decorating your views.
Each view that is decorated will automatically have a channel created for the object being accessed in the view. Each object gets its own channel, named modelclass_pk, so if your model is called Book, and you just created your first book, the channel will be called Book_1.
from pusherable.mixins import PusherDetailMixin, PusherUpdateMixin
class BookDetail(PusherDetailMixin, DetailView):
model = Book
class BookUpdate(PusherUpdateMixin, UpdateView):
model = Book
This takes care of the backend (pushing messages).
On the front end (client, reading messages), there are a few template tags provided for you. These tags just import the necessary javascript and help subscribe you to the correct events.
There are two default events for each model, update and view.
Now, suppose you want to know whenever the book with id 1 is updated, and automatically update the page, in your templates you would write the following. obj is the the object for book:
{% load pusherable_tags %}
{% pusherable_script %}
{% pusherable_subscribe 'update' obj %}
<script>
function pusherable_notify(event, data) {
console.log(data.user + "has begun to " + event + " " + data.model);
}
</script>
In your backend, you would call this view with a specific book:
def book_update(request):
obj = get_object_or_404(Book, pk=1)
return render(request, 'update.html', {'obj': obj})
Now open that view in a new browser tab.
In another browser tab, or in the django shell - update the book with id 1, and you'll notice the javascript console will automatically log your changes.
How can I use it if I have 2 classes in my database like say,one for
question and one for options, after creating one question it should
appear in the feeds of its followers and along with options, Do I have
to push the options also? How to do this?
Pusher does not care what your database classes are, or what your database relationships are. You have to figure this out yourself.
Pusher's job is limited to making the "live update" happen on the browser without the user having to refresh the page.
Plus how to create relationships, i.e when an user follows another how
to subscribe to it and show related feeds?
I think you don't quite understand what is Pusher's role in all this.
Pusher doesn't care about your database and it has no knowledge about your relationships in the database, what object relates to what and who is following whom.
All pusher does is makes so that one page on the browser will automatically update without the user having to refresh.
The logic to "follow" another user should already be created in your application. That is, you must have a view that allows a user to follow someone else. Once they follow someone, a record will be created/updated in the database. This action will trigger Pusher to publish a message for that database object. Now, whoever is listening on that channel will receive that message, and then can do whatever they want with it.
Here is the order of events/development:
First, create your application as normal. It should have all the features that you expect. If this is a social network, people should be able to follow others and refresh their profile page to see any updates from their followers.
The system should already "know" what is an update and what content is stored for each entity. So, if you are creating "users" and "followers", there should already be the forms, screens, logic, database tables, etc. to make sure that content can be added, updated, by the correct users.
Once you have all that in place correctly and working as you like, now you bring in Pusher; and then you decide which "event" do you want to have automatically updated in the browser.
Suppose the event is "whenever a user adds new content to the site, all their followers should be notified". So you would then do the following:
Go to the view that is executed when a user posts new content.
Update that view as described above, inheriting from PusherUpdateMixin
Go to the template that is shown for users where all their followers are shown. In this template code, add the tags described above to include the pusher javascript api.
Next, in the same template, you will have code that lists all the users this user is following, in that logic code, you can then add a div which will be updated "automatically" whenever that user posts an update.

Django paypal checkout for WHOLE cart

I made a Django online-store site and I need to include paypal checkout system for the cart, but solutions I found online either just for one item only(Buy Now buttons) or something like django-paypal-cart, which is not well-documented and I can't figure out how to make it to the checkout.
Please, give me some hint, maybe good article about how to make your cart items go to the checkout, anything will be highly appreciated, I don't know what else to google now
There are numerous options for tying PayPal into your website or app. Depending on exactly what you're doing or how good you are with web service API's you may choose one or another.
If you want to keep things simple, you can stick with Payments Standard. This is basically what you're referring to about the one item only buy now button, but you can use the cart upload command method to build a form that includes multiple items and pass it all over to PayPal at once.
If you prefer web service API's I'd recommend using Express Checkout. This consists of SetExpressCheckout, GetExpressCheckoutDetails, and DoExpressCheckoutPayment. Read through that general EC documentation to get familiar with the calls and how it all flows.
Another thing I would highly recommend utilizing is Instant Payment Notification (IPN). This is a feature where PayPal will POST transaction data to a listener script that you have sitting on your server any time a transaction occurs on your PayPal account. This includes payments, refunds, disputes, cleared payments that were pending, etc. This allows you to automate tasks like updating your database, sending out custom email notifications, hitting 3rd party web services, etc. and it happens in real-time, so it's very powerful.

Randomly adding messages to the Django messages framework

In a Django project I have a space in the templates to show the messages coming from the Django messages framework. I would like to use that framework to show some messages that are not triggered by user actions in some views but instead are set by an app. Ideally my app will decide when it is best to send the messages but initially it will be random. An example to clarify a bit; I don't want to send the typical message related to an action like 'you have successfully updated your profile'. Instead I would like to recommend some content from times to times, something like 'you might be interested by spam'. The content ('spam' in this case) is provided by some objects in the database that another app gathers already.
I was wondering how I can set a message outside of the typical view. I was thinking about implementing a middleware that would be called on every request and setting the message in the process-request() class if this particular user has been marked to receive any.
Is it the even a good idea to begin with?