Difference between revisions of "Extension talk:PayPal.php"

From Organic Design wiki
(Change source-code blocks to standard format)
 
(9 intermediate revisions by one other user not shown)
Line 1: Line 1:
 +
[[MW:Extension:PayPal]] is an extension for creating PayPal donation forms using a <paypal> tag. [http://www.rentacoder.com/RentACoder/SoftwareBuyers/ShowBuyerInfo.asp?lngAuthorId=1573573 PokerCoder] requested adding IPN support to the extension through [http://www.rentacoder.com/RentACoder/misc/BidRequests/ShowBidRequest.asp?lngBidRequestId=816040&txtForceRefresh=1129200723554297227 this RentACoder job] and has accepted [[User:Nad]]'s bid to complete the work.
 +
 
== Installation ==
 
== Installation ==
 
To install the extension, just save the code into your extensions directory as usual and include it from your LocalSettings.php file. You should also create a file of the same name as the extension but with the .log file-extension instead of .php (e.g. PayPal.log) and make it writable by the web server to allow IPN responses or debugging information to be logged there.
 
To install the extension, just save the code into your extensions directory as usual and include it from your LocalSettings.php file. You should also create a file of the same name as the extension but with the .log file-extension instead of .php (e.g. PayPal.log) and make it writable by the web server to allow IPN responses or debugging information to be logged there.
  
To test IPN, see [[PayPal]] for how to set up a paypal test environment, and then enable the IPN functionality and create your forms as in the following LocalSettings.php example:
+
To enable the IPN functionality and create your forms as in the following LocalSettings.php example:
{{code|<php>
+
<source lang="php">
 +
# Include the extension code
 
include('extensions/PayPal.php');
 
include('extensions/PayPal.php');
$wgPayPalIPN    = true; # Enable handling of IPN posts from PayPal
+
 
$wgUseAjax      = true; # Enable the Ajax updater to dynamically update the form totals after IPN post received
+
# Enable handling of IPN posts from PayPal
$wgPayPalTest  = 'aran@zenovia.net'; # <--------------- THIS IS YOUR TEST BUYER ACCOUNT
+
$wgPayPalIPN    = true;
 +
 
 +
# Enable the Ajax updater to dynamically update the form totals after IPN post received
 +
$wgUseAjax      = true;
 +
 
 +
# SEE SECTION BELOW FOR DETAILS ON SETTING UP PAYPAL SANDBOX
 +
$wgPayPalTest  = 'aran@zenovia.net';
 +
 
 +
# First form (paypal item_number = 1)
 
$ipbwiki_paypal[1] = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
 
$ipbwiki_paypal[1] = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
 
<input type="hidden" name="cmd" value="_xclick">
 
<input type="hidden" name="cmd" value="_xclick">
Line 20: Line 31:
 
alt="Make payments with PayPal - it\'s fast, free and secure!">
 
alt="Make payments with PayPal - it\'s fast, free and secure!">
 
</form>';
 
</form>';
 +
 +
# Second form (paypal item_number = 2)
 
$ipbwiki_paypal[2] = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
 
$ipbwiki_paypal[2] = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
 
<input type="hidden" name="cmd" value="_xclick">
 
<input type="hidden" name="cmd" value="_xclick">
Line 32: Line 45:
 
alt="Make payments with PayPal - it\'s fast, free and secure!">
 
alt="Make payments with PayPal - it\'s fast, free and secure!">
 
</form>';
 
</form>';
</php>}}
+
</source>
  
== Creating a form ==
+
== Rendering Forms ==
 
The following couple of lines of wikitext will render the two forms defined in LocalSettings above. The parameter supplied is the text which will be rendered along with the form (if the first characters of the text are a number followed by a space, then the number is treated as the number of the form which should be rendered). If IPN is enabled then this text should contain tokens $1, $2 and $3 which will be replaced respectively by total amount donated, total number of donations made and the current state of the transaction (if returning from paypal after purchase - empty otherwise).
 
The following couple of lines of wikitext will render the two forms defined in LocalSettings above. The parameter supplied is the text which will be rendered along with the form (if the first characters of the text are a number followed by a space, then the number is treated as the number of the form which should be rendered). If IPN is enabled then this text should contain tokens $1, $2 and $3 which will be replaced respectively by total amount donated, total number of donations made and the current state of the transaction (if returning from paypal after purchase - empty otherwise).
 
<pre>
 
<pre>
Line 41: Line 54:
 
<paypal>2 There have been $2 donations totalling $$1. $3</paypal>
 
<paypal>2 There have been $2 donations totalling $$1. $3</paypal>
 
</pre>
 
</pre>
 +
*''The $$1 is just to put a dollar symbol before the total amount donated''
  
 
== IPN Database Table ==
 
== IPN Database Table ==
The transactions are stored in a database table called ''templatePayPalIPN'' which is structured as follows:
+
The transactions are stored in a MediaWiki table called ''PayPalIPN''. This was originally planned to just contain an entry for each ''item_number'' holding the totals for its corresponding form, but a record of every transaction had to be maintained because there can be many indistinguishable IPN posts for a single transaction. The new table structure is as follows:
 
<pre>
 
<pre>
 
+------------+---------------+------+-----+---------+-------+
 
+------------+---------------+------+-----+---------+-------+
Line 71: Line 85:
 
+-------------------+---------------------------+----------+-------------------------------+------------+------------+
 
+-------------------+---------------------------+----------+-------------------------------+------------+------------+
 
</pre>
 
</pre>
 +
 +
== AJAX Updater ==
 +
After a transaction has been made from one of the forms, and the payer returns to the wiki after clicking the "return to merchant" link, the page will include a JS function to keep polling the server to check the status of the transaction that was just made. It will keep polling until the returned status is "Completed". The totals will not be updated until the transaction is completed - but note that the instant transactions are usually completed before the "return to merchant" link is clicked, but slower payments such as e-checks will remain in "pending" state for a few days.
 +
 +
== Setting up the PayPal test environment ==
 +
The paypal sandbox allows all operations done within the paypal site to be performed within a test environment. It's useful to have a wildcard email domain so you can use any number of email addresses for different test accounts etc.
 +
 +
To set up a paypal sandbox environment suitable to test the MediaWiki PayPal extension, you must first sign up as a developer at https://developer.paypal.com using the email address that your paypal forms are set to (use a different password, or change the form's to another address completely if you like, but ensure that your forms match the paypal developer login).
 +
 +
Next set up '''two''' test accounts at https://www.sandbox.paypal.com (the session will be logged in as the master account, and the test account gets created under that). One of the test accounts will act as '''merchant''' and the other as '''buyer'''. You'll need an email address for each (they can be imaginary, but I recommend they be real if you have a wild card email domain to create unlimited addresses under). Both accounts need to have their email addresses confirmed and must have a bank account added and confirmed before test transactions can be done, so you need to log in to each and go through those processes. Note that the emails which get sent during this process are not physically sent outside the sandbox environment - you must retrieve them from the developer site's "test emails" section.
 +
 +
Finally you need to tell the PayPal MediaWiki extension to use the test merchant account. To do this, set the ''$wgPayPalTest'' global variable to the email address of the '''merchant''' test account in your ''LocalSettings.php'' file, but don't change anything in your form definitions - these must stay set to the email of the master account which you used to log in to the main paypal developer site (which I personally prefer to keep the same as the real business email so the forms don't need to change when switching from testing to real).
 +
 +
To make a test transaction first go to your form and click the button like usual. If it asks you to log into the developer site first, you need to log in to this with your master email address, then go back to the form and click buy again, this time it should take you to a normal looking paypal buy screen, at the top it should have in a large font the email address of the '''merchant''' test account you created. In the login form at the bottom, enter the email address and password of the '''buyer''' test account you created. Proceed with the transaction as normal and then click "return to merchant" when done.
 +
 +
If the transaction has worked correctly, you'll see the total update in the forms text (this could take a few seconds depending on the type of transaction and how long it takes paypal to validate it). If it has not worked, then the log file you should have created when following the installation instructions of the MediaWiki PayPal extension will hopefully be of some help.
 +
 +
== IPN Developer Resources ==
 +
'''I'''nstant '''P'''ayment '''N'''otification, included with Website Payment products, Express Checkout, and Standard Checkout, is available to PayPal Premier and Business members. Instant Payment Notification allows you to integrate your PayPal payments with your website's back-end operations, so that you get immediate notification and authentication of any PayPal payments and disputes you may receive.
 +
 +
When a customer makes a payment to you, PayPal will post a notification to your server at a URL you specify. Included in this notification will be all of your customer's payment information (e.g. customer name, amount) as well as a piece of encrypted code. When your server receives a notification, it will then post the information, including the encrypted code, back to a secure PayPal URL. PayPal will authenticate the transaction by checking the encrypted string. This post-back of the IPN data to PayPal prevents "spoofing," so you can be sure that the IPN came from PayPal. Upon verification, PayPal will send confirmation of its validity back to your server.
 +
*[https://www.paypal.com/IntegrationCenter/ic_ipn.html IPN at PayPal Integration Center]
 +
*[http://www.paypal.com/us/cgi-bin/webscr?cmd=p/pdn/article_pdn_intro-outside IPN Introduction for Developers]
 +
*[http://designertuts.com/paypal-ipn-receiving-instant-payments-in-your-web-application/ DesignerTuts Tutorial]
 +
*[https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/ipn-manual-outside IPN Manual]
 +
*[https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/ipn-techview-outside IPN Technical Overview]
 +
*[https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/ipn-code-outside Instant Code Samples]
 +
*[https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/ipn-techniques-outside IPN Techniques]
 +
*[http://www.superfreaker.com/paypal/inventory.asp Basic Inventory Management Using IPN]
 +
*[http://www.eliteweaver.co.uk/testing/ipntest.php IPN Test Environment]
 +
*[http://www.paypal-tech.com/SG2/scriptparse.php IPN PHP Script Generator]
 +
*[http://www.eliteweaver.co.uk/testing/ipntest.php?mode=_fetch-help Good IPN tech info]
 +
*[https://www.paypal.com/helpcenter/main.jsp;jsessionid=HJYGzrhnBSnHTFvBB1JLFSrVq5FGw7LT49RVPCr34y3J3LPDlphh!-1839041657?t=solutionTab&ft=homeTab&ps=&target=_parent&solutionId=10768&locale=en_US&_dyncharset=UTF-8&countrycode=US&cmd=_help&serverInstance=9003 What's the difference between IPN and PDT?]

Latest revision as of 18:11, 22 May 2015

MW:Extension:PayPal is an extension for creating PayPal donation forms using a <paypal> tag. PokerCoder requested adding IPN support to the extension through this RentACoder job and has accepted User:Nad's bid to complete the work.

Installation

To install the extension, just save the code into your extensions directory as usual and include it from your LocalSettings.php file. You should also create a file of the same name as the extension but with the .log file-extension instead of .php (e.g. PayPal.log) and make it writable by the web server to allow IPN responses or debugging information to be logged there.

To enable the IPN functionality and create your forms as in the following LocalSettings.php example:

# Include the extension code
include('extensions/PayPal.php');

# Enable handling of IPN posts from PayPal
$wgPayPalIPN    = true;

# Enable the Ajax updater to dynamically update the form totals after IPN post received
$wgUseAjax      = true;

# SEE SECTION BELOW FOR DETAILS ON SETTING UP PAYPAL SANDBOX
$wgPayPalTest   = 'aran@zenovia.net';

# First form (paypal item_number = 1)
$ipbwiki_paypal[1] = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="aran@organicdesign.co.nz">
<input type="hidden" name="item_name" value="Donation">
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="cn" value="Optional Comments">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="tax" value="0">
<input type="hidden" name="bn" value="PP-DonationsBF">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" name="submit"
	alt="Make payments with PayPal - it\'s fast, free and secure!">
</form>';

# Second form (paypal item_number = 2)
$ipbwiki_paypal[2] = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="aran@organicdesign.co.nz">
<input type="hidden" name="item_name" value="Other thing">
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="cn" value="Optional Comments">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="tax" value="0">
<input type="hidden" name="bn" value="PP-DonationsBF">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" name="submit"
	alt="Make payments with PayPal - it\'s fast, free and secure!">
</form>';

Rendering Forms

The following couple of lines of wikitext will render the two forms defined in LocalSettings above. The parameter supplied is the text which will be rendered along with the form (if the first characters of the text are a number followed by a space, then the number is treated as the number of the form which should be rendered). If IPN is enabled then this text should contain tokens $1, $2 and $3 which will be replaced respectively by total amount donated, total number of donations made and the current state of the transaction (if returning from paypal after purchase - empty otherwise).

<paypal>There have been $2 donations totalling $$1. $3</paypal>

<paypal>2 There have been $2 donations totalling $$1. $3</paypal>
  • The $$1 is just to put a dollar symbol before the total amount donated

IPN Database Table

The transactions are stored in a MediaWiki table called PayPalIPN. This was originally planned to just contain an entry for each item_number holding the totals for its corresponding form, but a record of every transaction had to be maintained because there can be many indistinguishable IPN posts for a single transaction. The new table structure is as follows:

+------------+---------------+------+-----+---------+-------+
| Field      | Type          | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| ipn_id     | varchar(32)   | NO   | PRI |         |       | 
| ipn_date   | tinytext      | YES  |     | NULL    |       | 
| ipn_item   | int(11)       | NO   |     |         |       | 
| ipn_from   | tinytext      | YES  |     | NULL    |       | 
| ipn_amount | decimal(10,0) | YES  |     | NULL    |       | 
| ipn_status | tinytext      | YES  |     | NULL    |       | 
+------------+---------------+------+-----+---------+-------+

Here is an example of the tables content after it has been populated with some paypal sandbox transactions made from the form examples shown above:

+-------------------+---------------------------+----------+-------------------------------+------------+------------+
| ipn_id            | ipn_date                  | ipn_item | ipn_from                      | ipn_amount | ipn_status |
+-------------------+---------------------------+----------+-------------------------------+------------+------------+
| 6C047440J05621040 | 15:11:38 Dec 12, 2007 PST |        1 | donations@organicdesign.co.nz |         22 | Completed  | 
| 23M49673DB6083320 | 17:00:51 Dec 12, 2007 PST |        1 | donations@organicdesign.co.nz |          8 | Completed  | 
| 18183268SP9363925 | 17:03:16 Dec 12, 2007 PST |        1 | donations@organicdesign.co.nz |         33 | Completed  | 
| 7U934835WE0858113 | 17:06:54 Dec 12, 2007 PST |        1 | donations@organicdesign.co.nz |         21 | Completed  | 
| 68W35106NH479463N | 17:16:52 Dec 12, 2007 PST |        1 | donations@organicdesign.co.nz |         12 | Completed  | 
| 83A03941MM395870F | 17:19:33 Dec 12, 2007 PST |        1 | donations@organicdesign.co.nz |         22 | Completed  | 
| 44384998LU7025730 | 17:22:12 Dec 12, 2007 PST |        1 | donations@organicdesign.co.nz |         22 | Pending    | 
| 3Y781051NB0709135 | 17:37:27 Dec 12, 2007 PST |        2 | donations@organicdesign.co.nz |         44 | Completed  | 
+-------------------+---------------------------+----------+-------------------------------+------------+------------+

AJAX Updater

After a transaction has been made from one of the forms, and the payer returns to the wiki after clicking the "return to merchant" link, the page will include a JS function to keep polling the server to check the status of the transaction that was just made. It will keep polling until the returned status is "Completed". The totals will not be updated until the transaction is completed - but note that the instant transactions are usually completed before the "return to merchant" link is clicked, but slower payments such as e-checks will remain in "pending" state for a few days.

Setting up the PayPal test environment

The paypal sandbox allows all operations done within the paypal site to be performed within a test environment. It's useful to have a wildcard email domain so you can use any number of email addresses for different test accounts etc.

To set up a paypal sandbox environment suitable to test the MediaWiki PayPal extension, you must first sign up as a developer at https://developer.paypal.com using the email address that your paypal forms are set to (use a different password, or change the form's to another address completely if you like, but ensure that your forms match the paypal developer login).

Next set up two test accounts at https://www.sandbox.paypal.com (the session will be logged in as the master account, and the test account gets created under that). One of the test accounts will act as merchant and the other as buyer. You'll need an email address for each (they can be imaginary, but I recommend they be real if you have a wild card email domain to create unlimited addresses under). Both accounts need to have their email addresses confirmed and must have a bank account added and confirmed before test transactions can be done, so you need to log in to each and go through those processes. Note that the emails which get sent during this process are not physically sent outside the sandbox environment - you must retrieve them from the developer site's "test emails" section.

Finally you need to tell the PayPal MediaWiki extension to use the test merchant account. To do this, set the $wgPayPalTest global variable to the email address of the merchant test account in your LocalSettings.php file, but don't change anything in your form definitions - these must stay set to the email of the master account which you used to log in to the main paypal developer site (which I personally prefer to keep the same as the real business email so the forms don't need to change when switching from testing to real).

To make a test transaction first go to your form and click the button like usual. If it asks you to log into the developer site first, you need to log in to this with your master email address, then go back to the form and click buy again, this time it should take you to a normal looking paypal buy screen, at the top it should have in a large font the email address of the merchant test account you created. In the login form at the bottom, enter the email address and password of the buyer test account you created. Proceed with the transaction as normal and then click "return to merchant" when done.

If the transaction has worked correctly, you'll see the total update in the forms text (this could take a few seconds depending on the type of transaction and how long it takes paypal to validate it). If it has not worked, then the log file you should have created when following the installation instructions of the MediaWiki PayPal extension will hopefully be of some help.

IPN Developer Resources

Instant Payment Notification, included with Website Payment products, Express Checkout, and Standard Checkout, is available to PayPal Premier and Business members. Instant Payment Notification allows you to integrate your PayPal payments with your website's back-end operations, so that you get immediate notification and authentication of any PayPal payments and disputes you may receive.

When a customer makes a payment to you, PayPal will post a notification to your server at a URL you specify. Included in this notification will be all of your customer's payment information (e.g. customer name, amount) as well as a piece of encrypted code. When your server receives a notification, it will then post the information, including the encrypted code, back to a secure PayPal URL. PayPal will authenticate the transaction by checking the encrypted string. This post-back of the IPN data to PayPal prevents "spoofing," so you can be sure that the IPN came from PayPal. Upon verification, PayPal will send confirmation of its validity back to your server.