I am hoping to use the PayPal Pro Hosted Solution to handle payments for my website, and what i would like to achieve is that user submitted data is NOT inserted into my database until PayPal confirms i have received payment for their entry.
From what I've read, i understand the IPN is the best way to achieve this.
So at the moment, users are entering their data with a form, which i am then previewing to them, and if they approve their entry, i am inserting into a database (using PHP/MySQL). The form data at the moment is being passed along in SESSION variables and working fine. The file process is:
User enters data
User is presented with their entered data on a knew page and if they approve...
They click a button which handles the insert into the database.
However what i would like to do is, if they approve their entry on the preview page, when they click approve, instead of the database being updated there and then, send them to PayPal to make the payment and only update the database with their entry if the payment is approved, like this:
User enters data
User is presented with their entered data on a knew page and if they approve...
They click a button which takes them to the payment page
If payment is received, their data is added to the database.
Does anyone have any experience of this type of approach point me in the right direction or give me some guidance on how to go about this please?
I have looked over the PayPal documentation but because I'm new to this, i need things explained in a pretty simple manner.
My original idea was just to store the form is SESSION variables but i will lose this by redirecting people to the payment page. Another thought i had was to create an identical database to what i already have as a temporary holding stage for data, then if the IPN comes back approved, move the data to the final hosting database, but this seems like over engineering the problem a bit.
I hope someone can help.
Thanks
Dan
Using PayPal IPN seems to be the best solution in this case.
In my opinion, using temporary table seems to be the best solution. It'll be following KISS rule.
Please consider using following scenario:
user enters the data
the form is being submitted
data is stored in temporary table in database
while redirecting to PayPal website you can add custom field that will be used to identify user when we be back on your page
update transaction status
insert data in the table of your needs
It seems to be the simplest solution.
One matter to recognize regarding IPN is that it is an 'Asynchronous' response from PayPal - it is not in the user's browser session, so session variables will not work if you are relying exclusively on IPN (other than if you receive the IPN response and then match it to the user's session). PayPal also offers PDT (Payment Data Transfer) which is an 'in-session' response which could return the user to your site.
I would not rely exclusively on IPN for payment notifications (see my answer in the following SO topic) Can one rely on Paypal IPN solely to record purchases?.
Our system uses a combination of both IPN and PDT, with the 'cart' data stored in a DB (as your 'temporary' record) until notification of the completed payment by either PDT or IPN - whichever arrives first which completes the transaction (your 'permanent' database insertion) and deletes the 'temporary' record (so a subsequent IPN or PDT does not trigger a duplicate transaction).
My original idea was just to store the form is SESSION variables but i will lose this by redirecting people to the payment page.
Not necessarily. Sessions can generally persist for as long as the current browser (session) is open. This is not the same as "as long as the current page is viewed" provided you set the session cookie correctly. You can if you do it right have the sessions persist for days, months, years...
Another thought i had was to create an identical database to what i already have as a temporary holding stage for data, then if the IPN comes back approved, move the data to the final hosting database, but this seems like over engineering the problem a bit.
No this is not overkill.
It deals with the situation where a transaction is not completed. This could occur for a number of reasons, for example your user goes to lunch and forgets to complete the process before the session times out (the default is 20 or so minutes) or where there is a problem with the Paypal end (unlikely but you have to presume it can occur) or where there is a general network issue (isp goes down mid transaction), or where your mobile users goes out of network coverage. Anything can disturb a transaction and you need to have a fall-back position. Otherwise it becomes annoying for you (because you don't know anything about what interrupted the transaction and at what point) and for your user who has to start over again.
Having a temporary database allows you to monitor incomplete transactions and if necessary prompting the user to complete if they do not do so within a given period of time.
Related
I have written a PHP code. When a user submits the form, it saves all information in session and redirect user to PayPal Payment page. When user successfully makes Payment, Paypal sends user to Return path. The return path page gets values from session and enter user in database. But, after submitting the form if user manually visit Return path URL, it will save information in database without getting payment. Any solution for this?
Without sharing your code, it's difficult to give an accurate answer, but based upon what you've provided...
Paypal allows you to provide 2 URLs to it's submission, a return_url and a notify_url.
With the return_url, it should be for display only (e.g. www.website.com/order_complete/), and should NEVER have any functionality behind it, such as updating an order status for the exact reason you've asked the question. Therefore, when you query the order in the DB, it would still be marked as unpaid, and then you can put in the appropriate response.
Validating the order is what the notify_url is for (see https://developer.paypal.com/docs/classic/products/instant-payment-notification/ for more information). Basically, this does a checkback to paypal to confirm that the order you have attempted to make has actually gone through successfully, and then you do your DB updates (setting the order to complete).
The solution for you would be to remove the 'order updating' functionality from the return_url, and implement the IPN.
I have been scratching my head for days now and wonder if you can help.
I am busy developing a ticket booking system BUT don’t want to store data to the database UNTIL payment successful, or in other words the visitor is returned to my site after payment.
So what I have is a form that a post to a confirmation form. On the confirmation form I catch all the values via POST commands for visitor to review. I then POST this off to the payment provider and once the transaction is successful the visitor is routed back to my site with a confirmation page.
It’s THIS confirmation page that I want to use the store the values in the mysql database.
Now I can use sessions to keep the values in an array or I could write the values into a TEMP database table, but I don’t want to write to and back from the database to many times as I don’t have load balancing in place plus I want to it to be as lightweight as possible.
Any ideas?
The answer is fairly simple. Important data have to be stored in a reliable storage. Session is not one by design.
So, being guided by not a whim but a reason, you'll end up storing this data in database, connecting it with user id.
The solution, as you said, is to use SESSION. If you want data to be more persistent, you can also use cookies.
So before sending your data to the payment gateway, you should do something like this :
$_SESSION['posted_data'] = $_POST;
I have a member sign-up process which requires a monthly subscription payment. I have a script running which can update my member's database using an IPN script. I am curious about the best way to go about validating a new user once they have successfully submitted payment. Here is the work flow that I have envisioned for this process, but please advise if you have done something similar in a more direct fashion.
Step 1) New User completes signs up form which includes their username and password.
At this point I would take the the password they generated and manipulate it in the database. This way if they tried to log in they would be denied access.
Step 2) User submits credit card payment through a third party processor. Third party processor sends out IPN to update database.
Using the IPN script, once their payment method is validated I would set the password back to the one that they created.
Step 3) User is validated with a successful payment.
Since their password is back to the one they initially wanted, the user can login.
I don't see any reason this would not work, but it seems clunky. Is there a better way? Thanks.
Rather than not setting their password correctly, why not just have an extra field named 'paid' and default that to '0' and then if/when they pay it's set to '1'.
Then in the login script simply make sure that field is set to '1' when they try to login.
I'm assuming they buy 30 days of subscription? If so when the payment comes in set a field called DaysLeft to 30, then every day you subtract 1 from that field. When a user tries to log in, it gets their name and verifies their password, then check to make sure they have days left DaysLeft > 0. This allows them to log in.
It would be a simple stored procedure that you can run every day, and handles every user. It also keeps track of how long until they need to pay again. You could set a reminder on login when they have less than 5 days left or something. Just some ideas
Well, my problem is what the title says.
I have build a small application (php + mysql), to test my skills in an e-commerce environment - 6 pages in total.
Each page after the 1st, relies on an id to retrieve/save data. This id is passed usually as hidden form field between pages.
On top of each page i have a small script that checks in what state is the selected id (2 checks actually.... a) if user has reached the last page/step of application and b) if a fantastic payment has been completed for this user) - if both of these conditions are valid, then i redirect user to a thank you page, stating that his process is already completed and he can choose to start over.
Yet i have problems with hitting the back button on my browser.
Hitting the back button once, works good - validation check forces the redirect i have implemented in my code.
But hitting the back button fast for 2 or more times, break this script - leading to lost records in my database - in live environment these will be purchases.
So my question is this: what measures should i take to prevent the "back hitting user" of duplicating/deleting/overwrite data records in the application.
I am looking for ideas and strategies.
Check wether the user is eligble for the thank-you page on any of the pages. You can do this with sessions or by storing a flag into the database.
If a user that has finished the checkout already moves back more than one step you can check on that page if the user has already the checkout done or not - an react according to it.
I don't think is a good idea to pass variables from pages in post forms. Most likely you should make a good use out of sessions, paths and database.
What I'm trying to say is to save all info in a good structured database, every step has to be separated, that way you can always return to any step and load that step info from database without losing or breaking anything.
Since is an e-commerce website you can't afford to make a double payment or errors, since one single error can lead you into losing that client.
After finishing the forms you can save a field in database and tell other scripts to redirect the client on another page since he finished.
I have a form were a user enters information, and then I have a PayPal button that the user will click once the fields have been filled in. The problem I'm having is how to you capture the user information when the paypal button is clicked, if the form has action="http://paypl.com/something/something".
Do I have to make this a 2 page process - one for me to capture the user information and then one to have the user click the paypal button?
By the way - the PayPal button directs the user to paypal.com to actually make the payment.
Guys, there's an easier solution here. Paypal allows you to pass those values through to it, then it will spit them back to you. There's actually two methods of getting the data back--a return URL that posts upon completion with return values (I've not been terribly lucky making that work) then a separate function that sends you a post upon completion of a transaction to a separate page on your site, where you can collect back all the variables you posted to the site. I suggest the latter because on a buy it now page there's a possibility of the user not being returned to the site because the return button UI is pretty weak on PayPal's end.
To set it up you'd log in to your PayPal account, click on myaccount > profile > website payment preferences. Enabling the "payment data transfer" will do the trick. Once you've got it setup correctly, upon completion of a transaction it'll send to the page of your choice a post of everything you sent it....remember, you can send in variables such as Name, Address, etc just by defining them properly in the form. All the variables available are found here
Sure, you could go through grabbing the elements from the form via Jquery or the like, then do an onclick save to DB, but why fight it? It's a heck of a lot more work and may have issues if Javascript is off.
Don't forget to build a sandbox site to test! Good Luck.
You have a few options here. You could make two forms, one which submits to your server where you capture the user information, and then display a second form with a "Pay Now" button. As a second option, you could extract the information from the form using JavaScript and submit it to your server using AJAX, then submit the form to PayPal when the AJAX request completes. This may or may not be more complicated, but it will not alter the existing user interface, which may be desirable.
I would make the action the current page, catch the button click and store the user information, then use header: Location("http://paypl.com/something/something");. Its something like that anyway. Hope this helps.
Edit: Also see the other answer by Josh. They are equally good possibilities. Note that the Ajax option would require JavaScript to be switched on - so safeguards would have to be put in place in case it is switched off.
My recommendation would be to add all of your user/order data into your own local database so that you can generate an order ID of some kind. You can then pass this order ID into your PayPal button code in a field named invoice.
This value will then come back in PDT/IPN as $_POST['invoice'] so you can easily pull all of that data back out and handle it within your application accordingly.
Another alternative would be to use Express Checkout instead of Payments Standard. It's a little bit more involved, but it has fewer limitations.
Even with EC, though, I still recommend sending an order ID of some sort along with the payment request so you can relate everything back and forth easily.