PayPal API Process - php

I have read and read through the links and documentation about the PayPal API, but to be honest, I am pretty confused as to what it is I need to do.
I am trying to set up a simple API where a user on my website clicks a button which takes him to PayPal to make a payment. After he makes the payment, all I want is for the PayPal API to update a record on my database with the confirmation.
So far the process works perfectly one way. I am using this code to get the users to make their payments:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="username#mywebsite.com">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="item_name" value="Gift Certificate">
<input type="hidden" name="item_number" value="RI001CI3481">
<input type="hidden" name="amount" value="313">
<input type="hidden" name="return" value="http://mywebsite.com/paypal/thankyou">
<input type="submit" value="PayPal">
</form>
After the user finishes the transaction, they are returned to my 'return' page.
I get an email when the transaction is complete. That's how I now a payment has been made. I then go to PayPal, confirm the payment, and update my database record to mark the transaction complete.
Now, what do I have to do to have PayPal automatically update my database when that payment has been made? If you could point me to a simple to follow document or sample, that would be great. As I said, I have read through some of the available documentation online but for someone like me it's a bit confusing.
Thanks,
Manny

What you're showing here is not using the API. PayPal Standard is just basic HTML form method for setting up payments with PayPal. It sounds like that part is already working for you how you need, so that's fine.
To update the database, you want to use Instant Payment Notification (IPN). It's still not technically an API, but it is a push service that will POST transaction data about any transaction that hits your PayPal account to a listener script that you have setup on your server.
Within this script you can process the data however you need to. Update your database, generate custom email notifications, hit 3rd party web services, etc.
There are some good IPN templates available for PHP on GitHub / Packagist. PayPal also provides a very basic starter template for IPN.

I think that IPN is one answer, but it is prone to issues and can fail if your servers or PayPal's servers are having issues. Many people who use IPN have only one server, and perform maintenance late at night, and IPN may attempt a notification but fails because the server is down for maintenance. IPN will just fail silently. A better alternative is to use an API like Express Checkout where you set up the look and feel of the page, set txn details, etc. with SetExpressCheckout and take the customer to the PayPal page to check out, and afterwards they are returned to your site. At this point you run DoExpressCheckoutPayment to complete the transaction and then when your response contains "ACK=Success" you can call GetExpressCheckoutDetails to get more detail than you would see with IPN and not have to worry if you didn't receive a response from PayPal as with IPN. You would have a request / response as with any API call and you can log your responses to be able to see when things go wrong, as well as to get details of the transaction. Often it seems that people explaining EC and even PayPal docs show to call setEC, then getEc, then doEC but I usually call set, do and then get once the txn is successful. I'm sure there are scenarios when someone would need / want to call set, get, do, but for IPN we only care once the txn is successful. ALSO, IPN will not send unless there is a txn. You can set your code to allow for situations when you receive an error and act accordingly, like when you get an error for declined card or similar. You can log the error, send email / SMS, log to DB table, etc.
Here is the documentation to integrate Express Checkout:
https://developer.paypal.com/docs/classic/products/express-checkout/
Tons of links here since EC can be used for order / auth / capture or simple sales or subscriptions, etc.
Here is the list of parameters for SetExpressCheckout:
https://developer.paypal.com/docs/classic/api/merchant/SetExpressCheckout_API_Operation_NVP/
Here is the list of parameters for DoExpressCheckoutPayment:
https://developer.paypal.com/docs/classic/api/merchant/DoExpressCheckoutPayment_API_Operation_NVP/
Here is the list of parameters for GetExpressCheckoutDetails:
https://developer.paypal.com/docs/classic/api/merchant/GetExpressCheckoutDetails_API_Operation_NVP/

While the overall coverage isn't yet at the same level of IPN, PayPal also now has Webhooks: https://developer.paypal.com/docs/integration/direct/rest-webhooks-overview/
Webhooks are a much more modern form factor than IPN, and is supported in the REST SDKs, hopefully that helps.

Related

Passing information via PHP for a payment platform

I have a service based company and a website entirely created with Dreamweaver. It does not have a cart and no service we sell is exactly the same price so it would not make sense to include one.
My bank provided me with a payment gateway to automate payments and allow clients to select their own currency but it is built for a website with a cart or a database.
So I am trying to find a solution which:
1 - allows me to ask for the clients details
2 - asks the client to confirm the amount they are due to pay (which needs to be between 0 and 10000 euros, no dots, comas or space allowed and 2 decimals included)
3 - confirms their name and the amount filled in the form on a separate page (their terminal does not show the amount to be paid so I want to confirm this to the client)
4 - sends the correct information to the payment terminal
5 - returns to our website to confirm the payment has gone through
6 - sends me an email with all the information filled in by the client and that the payment has been approved.
Here is the code provided by the bank
<form action="https://hpp.prueba.santanderelavontpvvirtual.es/pay" method="POST">
<input type="hidden" name="MERCHANT_ID" value="<?=$merchantid?>">
<input type="hidden" name="ORDER_ID" value="<?=$orderid?>">
<input type="hidden" name="ACCOUNT" value="<?=$account?>">
<input type="hidden" name="CURRENCY" value="<?=$curr?>">
<input type="hidden" name="AMOUNT" value="<?=$amount?>">
<input type="hidden" name="TIMESTAMP" value="<?=$timestamp?>">
<input type="hidden" name="DCC_ENABLE" value="1">
<input type="hidden" name="SHA1HASH" value="<?=$sha1hash?>">
<input type="hidden" name="HPP_LANG" value="EN">
<input type="hidden" name="AUTO_SETTLE_FLAG" value="1">
<input type="hidden" name="MERCHANT_RESPONSE_URL" value="tpv-mailer.php">
<input type="Submit" value="Pay by credit card on a Secure Website">
</form>
I am new to php, the documentation the bank sent me is not clear at all so I have been stuck on this issue for a while.
I have the form requesting data from the client thought POST working and the payment system works (although it only charges the same amount) but I cannot seem to find the code to pass the $amount filled in by the client to "> on the bank gateway without breaking the hash.
I was thinking maybe of sending this information by url or creating a session. Does anyone have experience with this and can help me?
Thank you so much in advance!
This is how I would go about it:
Start from scratch with your own multi-step form (since you want to confirm their name and amount).
POST the form to a PHP script via jQUery AJAX.
In your PHP script validate every single field. Remember that the client can send anything, so you want to make sure they wrote an actual amount for example.
Prepare the POST request that you'll be sending to your bank's API endpoint from your PHP script. Use the fields the user submitted (after validating them) and generate any others that you might need, for example the timestamp and return URL.
Send this POST request to your bank.
Read their response.
Process their response, e.g. send back a JSON to your jQuery AJAX function with information on what to do next, such as which page to redirect to. This is where you can also configure PHP to send you that notification email.
You don't have to use AJAX but by doing it this way you can show a nice "Processing..." view to your client if you so desired.
You'll need to fully understand all the parameters that your bank is requesting, for example where the $sha1hhash is coming from. If they have poor documentation then there are always alternative such as:
PayPal: https://developer.paypal.com/docs/api/
Stripe: https://stripe.com/docs/api
That said, if you're running the company and are new to PHP as you've mentioned, you might want to consider hiring a professional to do it for you. It's worth the investment.
After spending all day and trying to learn about PHP I found the solution to my problem. As I could not find any documentation online answering this question, I would like to share it if anyone needs it one day:
First you need to create a 3 step php form:
The First page is a standard form which asks information from my client, filters it and cleans it up
It redirects to the second page which acts as a mailer and collects the info. In the header, it sends the information collected to me by email then it calls the payment gateway. In the body, it sums up the information previously sent and gives the client a link to the gateway
the third page is the gateway response. It lets the client know of any error or thanks them for the booking and resends me an email with the booking confirmation.
The piece of code I needed was:
Page 1: ask for the amount due which is saved as $charge
On page 2:
in header:
$amount=$_REQUEST['charge'];
in body - to show the amount to be paid:
<?php
$FIRSTNAME=$_REQUEST['firstname'];
$LASTNAME=$_REQUEST['lastname'];
$CHARGE=$_REQUEST['charge'];
echo <<<TEXT
<h3 style="text-align:left;padding-left:1em">Hello, $FIRSTNAME $LASTNAME, balance is $amount euros</h3>
TEXT;
?>
The payment platform seems to be working and the amount is now decided by the client without access to a database.

Do I receive callback from Paypal buy now button for all events?

I am currently testing the buy now button on a PHP website. Here is the code I have (more or less) :
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value="........"
<input type="image" src="https://www.paypalobjects.com/fr_CA/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - la solution de paiement en ligne la plus simple et la plus sécurisée !">
<img alt="" border="0" src="https://www.sandbox.paypalobjects.com/fr_CA/i/scr/pixel.gif" width="1" height="1">
<input name="notify_url" value="https://www.example.com/paypal_notifications.php" type="hidden">
</form>
The sandbox transaction is working (sending complete) but I don't know if I will get only a one-time message or updates.
Do I receive an event if the payment is revoked ― say ― a week later? (Is there a way to immediately revoke a payment from within a sandbox account?)
I am using only notify_url and not the IPN setting in the account because the account is used with more than one website (and I couldn't find it... :P).
The notify_url setting in a Web Checkout form overrides the profile IPN URI, so if a form doesn't specify a notify_url then the profile value will be used, but if a form does specify an address then the profile value will not be used. I appreciate this is confusing because the PayPal Profile page (where you specify the default IPN address) does not mention this, neither does PayPal's own documentation.
(To further frustrate things, PayPal's documentation still has screenshots and text describing the old (2005-2015) account management pages, they still haven't updated them).
Note that despite the name "Instant Payment Notifications", the messages are not actually Instant - in my experience there is a lag time of between 15 seconds and (rarely) up to 2 minutes before my code receives an IPN message. For this reason if you really need instant notification you should also use PDT to augment your IPN handler. PDT is where PayPal's web checkout process will redirect your customers back to a custom URL with an opaque Transaction ID in the querystring, which you can use to retrieve the actual transaction details in your own code when you handle the incoming request from the returning customer.
The IPN system is now decades-old, dating back to the late-1990s - consequently its design is a bit strange, and you will, in fact, receive multiple notifications for the same transaction - but it depends on the type of transaction. This is documented in PayPal's IPN documentation, but again, they don't give you all of the details and in many cases you have to learn through trial-and-error.
For example, if it's a straight-forward Web Checkout using PayPal's own checkout pages and the customer is paying with a credit card or PayPal account balance then you'll get a single notification informing you the transaction was successful and that's it. However if a customer pays by US ACH (aka eCheck) then you will receive multiple notifications because the clearing process takes a while: you'll first get an initial notification that a payment was made, but that it hasn't cleared yet, then you'll get another notification 2-3 days later notifying you if the payment cleared successfully (and your PayPal account actually has the funds) or if it failed.
I don't personally recommend using the PayPal Sandbox for more than trivial exercises because it fails to simulate all possible scenarios in real-life, and it's a pain to set-up. How seriously you take testing depends on how critical this code is to your business.
In short, and for PayPal in particular, don't be afraid to test-in-production, and make sure your code gracefully handles unusual messages and I strongly recommend recording and saving every incoming IPN message so you can get a better "feel" for the data you can process - again, because PayPal's documentation is lacking in many areas.

Paypal Security Flaw?

I have a the following form at the end of a booking process (simplified):
<form action="https://www.paypal.com/cgi-bin/webscr" name="paypalForm" method="post">
<input type="hidden" name="amount" value="<?=$price;?>">
<input type="hidden" name="business" value="business#email.co.uk">
<input type="hidden" name="notify_url" value="http://website.co.uk/ipn">
</form>
I have only left out things like address name etc. So when they pay via Paypal, I am using paypal IPN to mark them in the database as paid. However..
I have gone to the end of my booking system and viewed source of the webpage, modified the business email address and amount. I haven't tried a full transaction yet, but surely with the 'notify_url' in there Paypal with send an IPN message to my server and will mark the person off as paid? Isn't this terrible security? Surely this not how all paypal payments work, I must be missing something.
There are two things I can think of that might prevent this:
If I remove the "notify_url", will the IPN URL that I have set in paypal work instead? What value does paypal place on the hidden var notify_url, does it override the settings in the back end of paypal?
In my IPN code I could check for business and Amount. I don't currently, as I didn't read any where in the documentation that I should. But now, I am thinking that maybe it would be a terribly good idea.
There isn't any check that can be done by PayPal to know what the correct amount, or email address should be that was used, or that the IPN URL should only be used with a particular PayPal account. Your options would to be write in the additional checks like you have already mentioned. In additional to what you already stated about your 2 workarounds, a 3rd option would be to create a hosted or encrypted button on the fly using PayPal's BMCreateButton API. Then the buyer would only see the encrypted button code, they would not be able to view your HTML button code. Therefore they would not be able to modify any of the variables, or see what they are currently set to.

Paypal notify_url and return_url. Receiving variables without IPN using PHP

I am trying to set up a simple payment option to paypal, but am having some trouble/confusion with the return and notify URLS. I am fairly new to php and have accomplished this previously in asp, but I have now become lost.
SO my basic paypal form:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="PayPalForm" name="PayPalForm" target="_top">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="email#hotmail.com">
<input type="hidden" name="amount" value="0.01">
<input type="hidden" name="item_name" value="Composite Door">
<input type="hidden" name="item_number" value="<?php echo $orderID ?>">
<input type="hidden" name="currency_code" value="GBP">
<input type="hidden" name="cancel_return" value="http://www.mydomain.co.uk/paypal-notcompleted.php">
<input type="hidden" name="return" value="http://www.mydomain.co.uk/paypal-completed.php">
<input type="hidden" name="notify_url" value="http://www.mydomain.co.uk/paypal-completed.php">
</form>
<script>
document.PayPalForm.submit();
</script>
As you can see the form posts to paypal, and then returns depending on the outcome, if failed/cancelled it goes to paypal-notcompleted.php.
If its successful it goes to paypal-completed.php. And this is where I am unable to understand, I haven't set up an IPN, all I want to do is grab some of the variables paypal posts back to me, to run a simple insert query and display some details in a confirmation message to the customer.
Am I allowed to have the notify_url and return_url as the same page?
Why does paypal not post the full expected (as seen here: Notify url of Paypal ) back to the page?
I understand there is something to do with XML and such, but I just figured that I would be able to $_GET the variables that paypal sent back. Has anyone done it this way, can they tell me where I am going wrong?
To return details back to the your return URL you'll need to use PDT. It's very similar to IPN except it's intended for use with your return URL, while IPN is intended for use with a 3rd party IPN listener script on your server.
PDT is fine for simply displaying transaction to the user on the return URL page, but it's not recommended to do any any post-payment processing with PDT (ie. database updates, sending out email receipts, etc.) because there is no guarantee the user will make it back to this page, even with Auto-Return enabled in your PayPal account.
IPN will be triggered every time a transaction occurs regardless of whether or not the user makes it back to your site after completing payment.
The notify URL is used for IPN only, and it would override any setting you have in your PayPal profile for IPN. PDT needs to be configured in your PayPal account profile in order to get data returned to your return URL.
You're going to want to use different URL's for return and notify, otherwise that same code would run twice: once when the user returns to your site, and again from the PayPal IPN POST.
Payment Data Transfer (PDT)
The return and cancel_return urls are one-off Payment Data Transfer (PDT) calls primarily so the user completes the transaction on your site. It is only passing information to reasonably help your site fulfil that task. There is no guarantee that a buyer will not quit before returning, so you cannot rely upon being able to do any post-transaction processing using only these.
Instant Payment Notification (IPN)
notify_url is used by the Instant Payment Notification (IPN) process, and called with each change in the transaction status. It is meant to be a complete record of all actions taken during the transaction lifecycle, upon which you can rely to drive backend process, like accounting, order fulfilment or cancellation. The IPN process takes measures to ensure the integrity of the process.
Their purposes are different and thus the information and security involved is different. For pros and cons.
IPN messages can be severely delayed, so use all three variables
Note that while most IPN messages are sent within a few seconds of the PayPal transaction being completed, I have experienced delays of up to several hours, so they are reliable, but not necessarily timely.
I would suggest using all of return, return_cancel and notify_url, as the former two will return immediately, so that you can provide immediate feedback to the user, and update backend data/instigate fulfilment processes, but use the latter as a backup if the user quits PayPal before the being returned. Indicate to your buyers to return to your site to ensure timely processing of their order.
Just have to manage order status so that the IPN doesn't trigger fulfilment if the PDT has already done so, which is basically what you have to do to ensure that repeated Completed IPN messages don't retrigger fulfilment after the first.
Notify_url continues to be used for subsequent messages for the same transaction
IPN messages for the same transaction continue to go to the same notify_url address. I viewed our IPN history, and a Refund IPN message went to the original notify_url.
That continues, even if you change IPN preferences, as per https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNSetup/:
The IPN message is always sent to your notification URL unless you have disabled the preference to receive IPN messages. Even though you have not enabled receiving IPN messages in your Profile or you have reset your preference by turning off IPN messages, PayPal still sends IPN messages to the notification URL you specify for a specific payment. IPN messages not sent because you disabled the preference in your Profile will appear in the IPN history when you enable receiving IPNs. After they appear in the history, you can choose whether to resend them.
I am unsure of whether related transactions, like disputes, or subsequent subscription payments, will still use the original notify_url. Perhaps someone who actually knows can provide an answer.
your notify-url and return url both are different . your return url direct your customer after the successful payment with some return information. by the way notify url is to get the complete transaction details of your customers purchase and which can't be accessed by your customer and this is for your database or storage purpose.

Give PayPal buy now button special ID?

I have a service I am starting where it's paid. I want to give a PayPal payment a special id. The ID would be passed through IPN and I could read it so I can modify my mysql database with that special ID. If that all makes sense...
I am basically want to upgrade their account without having to do some complicated process which I have already tried where it would send the user the transaction ID and they would have to go to a special URL to change their account information.
See what I mean? How would I go about doing this?
Thanks,
Coulton
If anyone else has a question on how to do it, I've found a way to fix it. When making your button, include this:
<input type='hidden' name='notify_url' value='http://yourdomain.com/paypal/ipn.php?user_id=$user_id'>
So you can pass who has made the payment to the IPN via get. Simply use $_GET['user_id'] to get the data (in my case a user_id). You can pass any variables you wish!
I played around with this for ages before I have realized that you can only send the pre defined paypal variables and not make your own up.
These are listed here
https://www.paypal.com/cgi-bin/webscr?cmd=p/pdn/howto_checkout-outside
One you can use for a custom variable is called 'custom'
<input type="hidden" name="custom" value="<?=$twitId;?>">
You also need to ensure you use this button
<input type="hidden" name="cmd" value="_s-xclick">
You also need to turn on and set a URL for the Instant Payment Notification on PayPal
They call this as a listener but it really just sends the payment data to the paypal page.
Note this is not the URL the customer is returned to after payment completion as set in button preferences.
Retrieve the custom variable in PHP thus
$userID = $_POST[custom];
Full instructions here
http://www.brianmoreau.com/articles/paypal_buy_now_button_sending_custom_variables.php
Hope this saves you the many hours I spent on it.
This method also allows you to obtain the buyer details such as email and address and the transaction reference.
To view the full data paypal sends after payment by clicking on history, IPN history

Categories