I am trying to implement django-paypal (dcramers version from git) using PDT with subscriptions.
It works fine (meaning that the return_url is requested and answered), however signals are not triggered (put in models.py). I am using the following signals, connected to two different functions.
from paypal.standard.pdt.signals import pdt_successful, pdt_failed
What I noticed while browsing through my access logs is that I do get a POST request from paypal which is turned down.
"POST /an-obscure-string/pdt/ HTTP/1.0" 401 401 "-" "-"
I tried to modify /paypal/standard/pdt/views.py to accept POST requests but I still get the 401 error. I think this is the reason signals are not triggered.
I am having a bad time with this. Any help would be greatly appreciated.
PS: I am using the sandbox account
EDIT These are my PAYPAL POSTBACK values from conf.py
POSTBACK_ENDPOINT = "https://www.paypal.com/cgi-bin/webscr"
SANDBOX_POSTBACK_ENDPOINT = "https://www.sandbox.paypal.com/cgi-bin/webscr"
You are right, that is the reason why the signal does not get called since signals are sent at the very end of the view if the model's verify succeed.
Your solution is indeed wrong, Paypal will definitely send a GET request with the transaction ID to your app url if you choosed to use PDN.
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_html_paymentdatatransfer
I really suggest you to check your settings (on paypal account) since you are probably using IPN which uses POST requests.
Another possible cause of this is that after you received the GET request from paypal your app sends the POST data to your app instead of to paypal postback endpoint. (https://github.com/johnboxall/django-paypal/blob/master/standard/pdt/models.py#L47)
I would look at the access logs to see if the POST request comes after a GET request (for the same url), if yes I would check the value of the SANDBOX_POSTBACK_ENDPOINT and POSTBACK_ENDPOINT settings.
Related
i am playing around with Postman to get some insight on how things work behind the curtain and ran into, what I believe, is an issue but wanted to ask before I create a new issue on GitHub.
I am intercepting the request from my browser to the same site using the Postman Interceptor to use the request values in the native app. I have cookies enabled and the site (the whole domain) whitelisted.
When I use the history to resend the same request that was captured I get an auth error that is caused by the fact that the cookies are not included in the request (found that out by checking the cURL code snippet). I believe the reason for that is, that the cookies are set under another sub domain than that the request is send to.
I will try to include some pictures to clarify. My question here is:
Am I missing something/did I set something up in the wrong way
or is this an issue and I should create an issue in the official Postman Github page
cURL request
Cookies in Postman Native App
you should see if cookie is being send not using code snippet but the console :
its indeed sending cookies ,
I have a django app built with graphene and I have a problem running a simple POST query for the GraphQL endpoint, it keeps returning a 400 Bad request syntax.
but it should work since I don't have any problems running the query from the endpoint http://localhost:8000/graphql-dev
and I can't see any issues in the way I send the postman request.
I looked online for suitable solutions but couldn't find any that would help.
Any help/tips would be greatly appreciated.
EDIT:
I still didn't manage to see why I'm having this issue with postman, but here are some observations:
first, i changed the request to GET (since in graphql, query is for GET and mutation for POST - sorry, I missed that)
I tried the same request with postman (which didn't work) and with insomnia (which did)
with postman
with insomnia
What's weird is that if i check my django console the requests look the same.
EDIT2: okay, I figured it out...removing the Content-Type application/json did the trick. Now it works with postman as well.
I'm implementing user registration for a Web Service.
When somebody wants to register an account, my WS sends an activation link to his/her mail. Until this link is clicked, user account is not activated (but the info is persisted in database, so the resource exists).
So my question is, if you try to register the same mail several times, you will get a 409 CONFLICT code. But there are two scenarios right there:
User account pending on confirmation
User already registered and activated
I would like to know what is the right approach. Should I "invent" an HTTP status 4XX to distinguish them, or send 409 with a JSON with info? other solutions?
Thx!
EDIT:
I have found this response -> https://stackoverflow.com/a/3290369/1171280 where Piskvor suggest to use 409 status and request header to explain the reason why it failed and/or body. Which one? header? body? both?
What do you think?
EDIT 2:
HTTP status + body with detailed error (with machine-parseable codes even) is OK, Twitter does that (https://dev.twitter.com/docs/error-codes-responses) and RESPECT :) . But I still doubt with 403 vs 409... :S
Pending account is a special type of a user account, so I think both accounts (already registered and pending) are same in the context of your question. You should return 409 in both cases. For the REST API both are same cases because that resource already exists in the system.
Regarding your updated question, I would suggest using body (JSON) to send out error(s) instead of using a custom HTTP header to explain the reason why the call failed. Reason is that in the body can you have multiple error messages (each one as a separate JSON object/array element) where as in the header you can have only one (though you can split based on some character). Other reason is that you can have one generic error handling method which looks for an "error" object in the JSON instead of looking for different custom headers for each failure scenario.
HTTP codes:
403 - The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be
repeated.
409 - The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in
situations where it is expected that the user might be able to resolve
the conflict and resubmit the request.
I think it should be 409 because the conflict can be resolved by re-issuing the request with different email address.
HTTP status codes are not meant to "invented".
409 CONFLICT sounds OK to me. Including details in the body ist OK, too, if your client needs to know.
Don't use 409. Use 403.
[409] is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request.
It's for a request that should have been OK, but has a problem that can be resolved. If you edit a document and PUT the revised text but someone else did the same thing before you did, you should have a chance to look at the other person's work so you don't accidentally undo all their work. You'd get a 409 which means, if you want to revise it, you should send your revision with an indication that you've seen the latest revision by the other person -- i.e. you know what you're doing.
There's no way to 'correct' a redundant attempt to register. The only way to avoid the conflict is to register with a different username, but that's very incorrect.
I'm imagining a POST request that takes a username and email address and creates a new resource dedicated to that new user (which should now be used for validation), sending that resource's URL in an email. So you're dealing with the refusal of the POST request handler to create a new resource, for a reason specific to the business model of your application (rather than an HTTP-related reason like bad syntax).
There's no status code more specific to what you want than 403. In this case, all you should use HTTP's vocabulary to communicate is 'that's not allowed' -- use the layer on top of HTTP to communicate why, like a polite HTML page or a JSON object for the client to understand and render as a polite HTML page.
409 should be ok; for the details https://datatracker.ietf.org/doc/html/draft-nottingham-http-problem-04 might be of interest.
I have been attempting to get the django-paypal app working within my Django project. I'm using the dcramer fork, with Django 1.4. I am also using a Paypal developer account with business and personal accounts, processing transactions through the Paypal sandbox website.
If I have no receiver function connected to the payment_was_successful signal, things seem to work as expected. After a transaction has occured, a new row is created in the paypal_ipn table of the database which has a value of 'VERIFIED' in the response column. The Paypal IPN log reports that there were no retries for this transaction.
When I do have a receiver function connected to the payment_was_successful signal, the paypal_ipn table includes two new rows with created_at timestamps 10-15 seconds apart. They both have a value of 'VERIFIED' in the response column, but the latter of the two is flagged with flag_info indicating something like:
'Duplicate txn_id. (5M907276M1007902B)'
The Paypal business account reports that the IPN was retried 1 time.
I have found possible solutions that mention the use of dispatch_uid when connecting a receiver function to the signal which I am yet to try. My issue is that I have looked through the relevant django-paypal source code and I can't understand why Paypal would retry the IPN when the postback on the first one was verified.
Has anybody else come up against this and found a solution that they understand?
Update:
I have discovered that there was an error in my receiver function code, which would have been raising an exception. Now that I have fixed this, Paypal is no longer retrying the IPN. I'm glad that the problem has gone away, but I still can't figure out why it was happening.
Below is an excerpt of the most recent duplicate records in the database. Note that the first row was created and updated at least 10 seconds before the subsequent one.
created_at updated_at response flag
2013-02-03 07:53:56.628013+00 2013-02-03 07:53:56.628057+00 VERIFIED FALSE
2013-02-03 07:54:07.393795+00 2013-02-03 07:54:07.403008+00 VERIFIED TRUE
I have figured this one out. The short answer is to make sure your receiver functions are working correctly.
When Paypal sends an IPN to the URL you have specified, they are expecting a response with HTTP status code 200. If the response code is anything else, they will retry. Even if you process a callback and get a VERIFIED message, the IPN from Paypal needs a response of 200 OK.
I had a look through my Apache access logs and discovered that when I had errors in my receiver function for the payment_was_successful signal, the initial IPN from paypal received a HTTP status code 500.
The django-paypal package responds with HttpResponse("OKAY") only after everything else has been processed, including the postback to Paypal which was returning "VERIFIED", the PayPalIPN object being saved to the database, and the sending of signals. When things went wrong in my signal receiver function and an unhandled exception was raised, Django was responding with a HTTP status code 500.
When Paypal retried the IPN, the django-paypal package was detecting a duplicate txn_id and sending the payment_was_flagged signal. My receiver function for this signal was error free, so Paypal received the HTTP status code 200 it was expecting and stopped retrying.
Hopefully this helps someone else out there in the future.
I made an application using Qt/C++ that reads some values every 5-7 seconds and sends them to a website.
My approach is very simple. I am just reading the values i want to send and then i make an HTTP POST to the website. I also send the username and password to the website.
The problem is that i cannot find out if the request is successful. I mean that if i send the request and server gets it, i will get an HTTP:200 always. For example if the password is not correct, there is no way to know it. It is the way HTTP works.
Now i think i will need some kind of a protocol to take care the communication between the application and the website.
The question is what protocol to use?
If the action performed completes before the response header is sent you have the option of adding a custom status to it. If your website is built on PHP you can call header() to add the custom status of the operation.
header('XAppRequest-Status: complete');
if you can modify the server side script you could do the following
on one end :
You can make the HTTP post request via ajax
and evaluate the result of the ajax request.
On the serve side
On the HTTP request you do your process and if everything goes accordingly you can send data back to the ajax script that called it.
solves your problem .. ?