Apr 22, 2013

UniFi and Paypal Integration

Introduction

This deployment example is to demonstrate how you can integration UniFi hotspot with (1) Paypal Pro account and (2) Paypal Standard account. This is for demonstration ONLY and focuses on functionality feasibility. We will NOT support the example scripts. The example shall NOT be used in the production network. The reader of this document is expected to have HTML/PHP knowledge and are familiar with Paypal services. This is an EXAMPLE, please don’t just simply apply, think through first and make sure every line is properly modified according to your environment.
The example here was developed against Paypal Sandbox which is a test environment provided by Paypal for developers. This shall provide the same UI/API interface as the normal Paypal website. If not, then you will need to check with Paypal.

Architecture Diagram


Paypal Pro Integration

Paypal Pro account incorporates a poweful API that allows UniFi controller to leverage with directly. Comparing to integrating with Paypal Standard, which will be discussed later, Paypal Pro provides benefits such as easy setup and easy maintenance. It is supported in the UniFi controller hotspot configuration. The convenience however comes with a price that there is a monthly fee you need to pay (to Paypal not to us).

Part I. Preparing Paypal Account

  1. Goto Paypal Sandbox website, https://developer.paypal.com/
  2. "Test Accounts" > "New test account" > "Preconfigured"
  3. "Account Type" > "Website Payments Pro"
  4. See if you want to change the auto-generated "Password"
  5. "Create Account"
  6. You can now see an account being setup in the Test Accounts page, choose that and click "Enter Sanbox Test Site"
  7. A new window being brought up, "Login" with the password you set
  8. Goto "My Account" > "Profile" tab
  9. Under "Account Information" > choose "Request API credentials"
  10. Choose "Option 1 - Paypal API" > "Setting up API permissions and credentials"
  11. Then under "Option 2 - Request API credentials to create your own API username and password.", choose "View API Signatures".
  12. Make a copy of the "API Username", "API Password" and "Signature", that's all you need to get Paypal Pro going.

Part II. Preparing Controller

  1. Create a guest WLAN (check "Guest Policy" in the Wireless Configurations page of the WLAN)
  2. "Settings" > "Guest Control"
  3. In "Guest Policies" panel > "Enable Guest Portal"
  4. "Authentication" > "Hotspot"
  5. check "Enable Portal Customization"
  6. In "Hotspot" panel > check "Payment", "Enable payment-based authorization (PayPal Website Payment Pro required)"
  7. In the Paypal Username, Password and Signature, copy and paste those you obtained from Paypal website.
  8. Since I am using Paypal Sandbox for testing purposes, I will check "Use PayPal Sandbox". In the production controller and Paypal integration, you don't check this.

Part III. Preparing Wireless Access Plans

  1. This example illustrates the minimal changes in order to setup your customized wireless plan.
  2. The default plans in UniFi configuration are (1) 8-Hour Pass for $5.99 (2) Day Pass for $8.99. Let’s say you want to setup changes these to (1) 4-Hour Pass for $1.99 (2) 8-Hour Pass for $2.99 and (3) Day Pass for $5.99.
  3. We have enabled portal customization which is stored in the [UniFi root directory]\data\portal directory. There are at least 2 files that need to be modified in order to achieve this: index.html and bundle\messages.properties.
  4. index.html has the user interface. Open it and search for the section "Please select the package of your choice".
  5. In that section, we will add another plan for 4-Hour Pass and modify the other plans into the revised amounts. Since package-1 is used by 8-Hour plan, package-2 is used by Day Pass plan and package-3 is used by the Free Trial, we will use package-4 for the 4-Hour Pass plan.
    <div class="options-box">
    <pre><input type="radio" value="4" name="package" id="package-4" checked="checked" /><label for="package-4">4-Hour Pass - $1.99</label>
    <input type="radio" value="1" name="package" id="package-1" /><label for="package-1">8-Hour Pass - $2.99</label>
    <input type="radio" value="2" name="package" id="package-2" /><label for="package-2">Day Pass $5.99</label>
    </div>
    
  6. bundle\messages.properties defines the content of a package. Open it and the file should have enough self-explanatory comments.
  7. Modify the charging amount for the package-1 (8-Hour) to $2.99 and package-2 (1-Day) to $5.99.
  8. Add a new package for 4-Hour.
    ## package 4
    package.4.amount=1.99
    package.4.hours=4
    package.4.name=Essential 4HR
    package.4.charged_as=Hotspot 4-Hour Wifi
    
  9. Now you are all set.

Part IV. Test if Everything Works

  1. You can test it out by creating another Paypal Sandbox buyer account.
  2. After associating to a guest WLAN, see if the controller redirects you to custom portal page where you can pay for wireless plan (using sandbox buyer account).
  3. See if your business account has received the payment
  4. See if the controller allows guest access for that account after payment.
  5. Verify in the controller hotspot manager to determine if the time allocated for this guest is correct.

Paypal Standard Integration

Paypal Standard account is free of charge and therefore Paypal has more limitation on its capability. One of the limitations is that Paypal standard does not allow APIs. In other words, you cannot hook UniFi controller directly to a Paypal Standard account like the way we do it for Paypal Pro account. In order for this to work, you will need (1) an external web server as portal (2) to leverage Paypal Instant Payment Notification (IPN) service to integrate with UniFi hotspot with Paypal Standard account.
The implication of this integration is more on setup and maintenance efforts since one more entity is introduced in the architecture therefore the extra complexity. The example presented here is to demonstrate how a Paypal standard account can be integrated with UniFi Hotspot, we do not actually own the external web server piece. Note that we (as in Ubiquiti UniFi team) only make sure our UniFi controller interface to the external portal is functional correctly. It is owner’s responsibility to ensure that this external server is working smoothly and all errors have been properly handled.
We would like to thank JustTech and mmaxmal, their posts inspired the writing of this deployment example. We also hope this article can help those who in need.

Part I. Prepare the external portal website (Apache, PHP, UniFi example portal)

  1. This example is based on Windows 2008. Windows 7 should work also. A Linux user should be able to leverage these steps fairly easy (Steps can be found here UniFi_and_Paypal_Integration#Integrating_UniFi_and_Paypal_Standard_on_Ubuntu_11.04 ). Also, this external web server machine needs an Internet IP address (for later Paypal IPN service to post back) or port forwarding needs to be enabled on the firewall.
  2. Install an Apache web server which can be downloaded from http://httpd.apache.org. We use httpd-2.2.22-win32-x86-openssl-0.9.8t.msi. In this example, the apache server is installed on the same machine that is also running controller.
  3. To verify if the Apache has been installed successfully, open a web browser and give the localhost url 127.0.0.1. You should see a string “It works!” that indicates Apache server has been installed successfully.
  4. Now go to UniFi FAQ, http://wiki.ubnt.com/UniFi_FAQ, search for “portal_sample.zip (if running 2.2.0)” and download the file. (This article was built based on modifying this sample project, however, we have also put the end result portal files online, see Part IV for its download link.)
  5. Extract its contents into the Apache htdocs/guest folder. In my computer, that will be "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs\guest". By default there is no guest folder, so you will need to create a sub-folder guest under htdocs. When enabling external portal, the controller does not look at the default htdocs directory but the guest directory underneath it.
  6. The example uses php format for index file. Therefore, we need to install PHP. Go to PHP for Windows website, http://windows.php.net/download. According to the website, it has a sidenote says "Do NOT use VC9 version with apache.org binaries", thus we are installing the PHP5.2 which is VC6 version.
    1. Our installation (described below) is mostly based on the instructions provided on "http://www.thesitewizard.com/php/install-php-5-apache-windows.shtml"
    2. We downloaded the zip file of the Thread Safe one. (I tried PHP5 installer at first but Apache doesn’t like it..)
    3. Extract it into C:\php folder
    4. make a copy of php.ini from php.ini-recommended
    5. You can modify this .ini file based on your needs.
    6. In php.ini, we need to un-comment the following lines
      • extension=php_openssl.dll (need this for paypal)
      • extension=php_curl.dll (need this for controller)
    7. Also add "C:\php\ext\" to the Windows Path environment variable.
  7. Goto Apache2.2/conf folder and open httpd.conf.
    1. Modify the httpd.conf file
    2. add LoadModule php5_module "c:/php/php5apache2_2.dll" note “/” instead of “\”
    3. add AddType application/x-httpd-php .php
    4. add PHPIniDir "c:/php"
    5. add "index.php’’ in the DirectoryIndex line
    6. Save httpd.conf file and then restart Apache service.
  8. Open a browser with localhost/guest as URL. If everything works smoothly, you shall see the Welcome! Free Wireless Internet..., this is the default content that provided in the example index.php.

Part II. Prepare Paypal

  1. The example here is based on Paypal Sandbox which is a test environment provided by Paypal for developers. This shall provide the same UI/API interface as the normal paypal website. If not, then you will need to check with Paypal.
  2. Sign up an account on https://developer.paypal.com/
  3. In “Test Accounts” tab > “New Test Account” > “Preconfigured”
  4. “Account Type” chooses “Seller (Use to represent yourself as the merchant)” which is the Standard one. Fill-in all entries and then “Create Account”
  5. Now you shall see that newly created account in the summary page.
  6. Click “Enter Sandbox Test Site”, a new windows should be brought up. Use the password you gave earlier to login.
  7. The next step is to create the “Buy Now” button for the WLAN charging plans
  8. Let’s say we are going to create 3 different charging plans
    • 8-Hour Pass for $4.99
    • 1-Day Pass for $7.99
    • 3-Day Pass for $12.99
  9. Goto “My Account” > “Profile”
  10. Under “Selling Preferences”, choose “My Save Buttons” > “Sample Buy Now Button” > “Action” > “Edit Button”.
  11. Item Name: Wireless Pass
  12. Customize Button: “Add drop-down menu with price/option”
    1. Name of Drop-down Menu: Wireless Access Plan
      • Input menu option name and price: 8-Hour Pass / $4.99
      • Input menu option name and price: 1-Day Pass / $7.99
      • Input menu option name and price: 3-Day Pass / $12.99
    2. click “Done”
    3. click “Save Changes”
  13. You will be redirected to the auto generated button code. This piece of code can also be viewed from “My Save Buttons” > “Wireless Pass” (this is the new name of the ‘Buy Now’ button we just gave above) > “Action” > “View Code”.
  14. Copy the generated code and paste it into the index.php file. In here, we put it under terms-of-use paragraph. The html design part is beyond the scope of this article.
  15. If you access the guest portal page now, it should look like below.
  16. Now, the other trick here is to use Paypal IPN (Instant Payment Notification) service to notify our portal that it has received a payment which in turn notifies UniFi controller to enable wireless pass for this guy. That way everything is automated.
  17. The details of the scripts is in part 3. Before we go into that part, there is one more thing needs to be done: we need to tell Paypal that we want IPN service and which script that Paypal should notify to.
    1. “My Account” > “Profile” > “Instant Payment Notification Preferences”
    2. Notification URL, put your server’s IP or domain name and whatever script name that you are going to used for IPN processing. Note that since this Paypal talking to your server, you will need a public IP, or a private IP with port forwarding. In this example, we are using a L3 controller in the AWS, ''http://ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com/guest/paypal_ipn.php''
    3. “Receive IPN messages (Enabled)” > “Save”
  18. Now we are going to put every pieces together.

Part III. Preparing the Controller

  1. In “Settings” > “Guest Controler”, “Guest Policies” > “Authentication” choose “External Portal Server”
  2. “Custom portal” > IP address > your web server
  3. click “Apply”

Part IV. Integration

  1. The example described below can be downloaded at http://www.ubnt.com/downloads/unifi/2.3.2/portal_sample_paypal.zip. If you have an improved version of the example and would like to contribute back, we are more than happy to add that. Please let us know, you can send me (UBNT-David) a private message through the UBNT forum.
  2. In short, the whole process goes like this
    1. a user connects to the guest WLAN
    2. the controller redirects her/him to the external portabl website, the redirection post contains the MAC of this newly connected device
    3. In the external web server, this user can see “Terms of Use” agreement, and also a Paypal “Buy Now” button.
    4. The “Buy Now” button has a drop box that contains all possible wireless plan options.
    5. The user chooses one of the wireless plans and the click “Buy Now” button.
    6. The user got redirected to the Paypal website.
    7. In the Paypal website, the user can pay with her/his credit card as a guest or pay with her/his Paypal account (if s/he has one).
    8. Once the user submitted her/his payment, the Paypal generates an IPN message and post it to the external portal website you setup.
    9. The IPN message contains payment information and client MAC information.
    10. The portal site receives this IPN, it validates with Paypal to make sure that this message is not fake. If the message is valid, the portal site parses the IPN message and proceed.
    11. First to make sure that the payment has completed.
    12. If the payment is good, the portal site notifies the controller to grant access for the specified device (the MAC address passed in IPN) and for how long (based on the payment option received in IPN).
    13. The user can now access the internet.
  3. To process Paypal IPN, we need to develop a script that handles Paypal IPN, this script is the attached paypal_ipn.php. This script is developed based upon the example provided in Paypal Instant Payment Notification Guide.
  4. Make sure that openssl extension is enabled (see part I) in PHP. Otherwise you can’t communicate with the Paypal. Also curl extension for talking to the controller.
  5. Another thing is that we need to pass the MAC address along this process: external portal to the paypal and then reported back through paypal IPN. That way the system knows who just paid and we can enable access for the right device.
  6. The first thing is to pass the MAC address of the guest device.
    1. Earlier we have pasted the “Buy Now” button code in the index.php file, we now add one more hidden field.
      <input type="hidden" name="custom" value="<?php echo $_GET['id']; ?>">
      
    2. Now when a user clicks “Buy Now” button, its MAC address will be passed to the Paypal site in the “custom” field which will be included into the IPN message that Paypal generates.
  7. We will now take a look at the script that processes Paypal IPN message.
    1. The script is based on the example script provided in the Paypal IPN guide and we modify the needed parts to make it work with UniFi controller.
    2. The first thing is to distinguish between Paypal Sandbox and normal Paypal to know where to validate the IPN message.
      if($_POST['test_ipn'] == 1) {
      $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); 
      } else {
      $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30); 
      }
      
    3. The next is to handle HTTP error (if there is one) when dealing with Paypal. This piece will get executed when there is a communication issue between your portal server and Paypal. In here, we will write this error into a log file; in reality, you probably need to do something (such as try again or notify the admin to manually grant guest access for the user).
      if (!$fp) { // HTTP ERROR
      $myFile = "log.txt";
      $fh = fopen($myFile, 'a') or die("can't open file");
      fwrite($fh, "\n[".date('m/d/Y h:i:s a', time())."] "."HTTP ERROR while processing validation from Paypal\n".$errno."\n".$errstr."\n");
      fclose($fh);
      }
      
    4. The next part should be straightforward, the script verifies the payment. If it is good, it then extract how much time to grant this guest access and the MAC address of the guest device.
      if (strcmp ($_POST['payment_status'], "Completed") == 0)
      {
      // Check which plan did this guest choose
      if (strcmp ($_POST['option_selection1'], "8-Hour Pass") == 0) {
      $granted_time = 8*60;
      } else if (strcmp ($_POST['option_selection1'], "1-Day Pass") == 0) {
      $granted_time = 24*60;
      } else if (strcmp ($_POST['option_selection1'], "3-Day Pass") == 0) {
      $granted_time = 72*60;
      } else {
      // TODO: unknown amount; should not happen
      $granted_time = 0;
      }
      // extract the MAC address of the device
      $mac_addr = $_POST['custom'];
      }
      
    5. The script then notifies the controller, this is wrapped in a function, guest_authorize. In this function, the curl component is being utilized to communicate with the controller.
      // Notify controller to enable wlan access for this device
      guest_authorize($mac_addr, $granted_time);
      
      function guest_authorize($mac, $minutes)
      {
      $username = 'admin';
      $password = 'admin';
      $baseurl = 'https://ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:8443';
      
      /**
      * Initialize the cURL session
      */
      $ch = curl_init();
      
      // prepare cookie file
      $cookie_file_path = "unifi_cookie.txt";
      $fp = fopen ($cookie_file_path , "wb");
      fclose ($fp);
      
      // log into the controller
      curl_setopt($ch, CURLOPT_URL, $baseurl.'/login');
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
      curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
      curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      curl_setopt($ch, CURLOPT_POST, 1);
      $postfield = array( "login" => "login", "username" => $username, "password" => $password );
      curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfield, '', '&'));
      $contents = curl_exec ($ch);
      
      // grant guest access
      curl_setopt($ch, CURLOPT_URL, $baseurl.'/api/cmd/stamgr');
      curl_setopt($ch, CURLOPT_POST, 1);
      $jsonfield = array( "cmd" => "authorize-guest", "mac" => $mac, "minutes" => $minutes );
      curl_setopt($ch, CURLOPT_POSTFIELDS, 'json='.urlencode(json_encode($jsonfield)));
      $contents = curl_exec ($ch);
      
      /**
      * Close cURL session
      */
      curl_close ($ch); 
      }
      
    6. Note that we only demonstrates the successful transaction part. the script does not really handle (only writes into a log file) if the IPN is Invalid or if the payment failed. These errors handling mechanisms are critical in the production system.
    7. Now everything is all set. We can proceed to test.
  8. Part V. Test if Everything Works

    1. You can test it out by creating another Paypal Sandbox buyer account.
    2. After associating to a guest WLAN, see if the controller redirects you to the external porta l site where you can pay for wireless plan (using sandbox buyer account).
    3. Choose a plan and click “Buy Now” button, you should be directed to the Paypal site.
    4. Complete the payment.
    5. See if your business account has received the payment
    6. See if your business account has successfully sent the IPN message.
    7. See if the controller now allows guest access for that account after payment.
    8. Verify in the controller hotspot manager to determine if the time allocated for this guest is correct.

    Integrating UniFi and Paypal Standard on Ubuntu 11.04

    Below steps are posted by FreenetAntennas (Thank you) in http://forum.ubnt.com/showthread.php?t=52824,
    1. Install Apache2
      • sudo apt-get upgrade
      • sudo apt-get install apache2
      • You will find there is no htdocs folder by default. The web pages are found at /var/www.
      • sudo mkdir /var/www/guest
      • Extract the files in portal_sample_paypal.zip to /var/www/guest
    2. Public Access; so PayPal can access your paypal_ipn.php file
      • You have to modify your firewall rules to allow access to port 80 on your server.
      • WARNING: PayPal will not talk to ports other than 80 (http) and 443 (https).
    3. Install openssl
      • This was not necessary - it was already installed
      • To check what is installed...
        • Create the file /var/www/info.php
        • Open that file and type this command: <?php phpinfo(); ?>
        • Save that file
        • Open your favorite browser and open that file (ex: http://localhost/info.php)
        • Now you will see the Information about your PHP installation
        • In my case openssl was already there
    4. Install curl
      • sudo apt-get install curl libcurl3 libcurl3-dev php5-curl php5-mcrypt
      • edit /etc/php5/apache2/php.ini and add this line: extension=curl.so
      • sudo /etc/init.d/apache2 restart
      • Check the PHP information page again, you will find PHP-CURL installed
    5. Modify httpd.conf
      • Was not necessary to do this
    6. Part II Prepare PayPal
      • This went as UBNT-David described
      • ... but to make the buyer experience better, I added a re-direct back to a Success page after the buyer completes the purchase.
        • Add the attached file as /www/var/guest/success.htm
        • In the PayPal sandbox: Seller ->My Account -> Profile -> Selling Preferences -> Website Payment Preferences ...
        • Auto return = On
        • Return URL: http://<ip of your apache2 server>/guest/success.htm
    7. Editing the sample paypal_ipn.php file
      • In function guest_authorize(), change $username and $password to match the username/password login for your UniFi controller
      • change baseurl to 'localhost:8443' (assuming your PayPal gateway and the UniFi controller are on the same host )
      • Edit the sections that look similar to this so that the text being compared matches the purchase options you setup in PayPal.
      • strcmp ($_POST['option_selection1'], "8-Hours") == 0
      • and edit the $granted_time values to match the number of minutes being purchased.
      • Don't forget to add this line as in UBNT-David's document:
        • <input type="hidden" name="custom" value="<?php echo $_GET['id']; ?>">
    8. Create files and Change Permissions
      • As I did all operations as root, I had to manually do the following:
      • sudo touch /var/www/guest/log.txt
      • sudo chmod 777 /var/www/guest/log.txt
      • sudo touch /var/www/guest/unifi_cookie.txt
      • sudo chmod 777 /var/www/guest/unifi_cookie.txt

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Computer Tricks and Tips