Accepting Online Payments via Paypal - Express Checkout Method

Paypal is the most preferred way to send and receive payments online. Here, I'm putting together a guide on how to receive payments online via paypal - via their Express Checkout Method. I'm assuming the reader to have knowledge in PHP.

The Payment with Express Checkout Uses Request - Response Method, or  a client-server model in which your website is a client of the PayPal server. Your website should send Request(s) with necessary parameters to the Paypal API and the paypal API will Respond to your Request with the appropriate Response.

And the steps involved are as follows

  1. Register yourself with Paypal
  2. Paypal provides sandbox environment, where you may test your website's payment proceedings. It is advised to test your website in this sandbox before actually deploying it. It is also very easy to switch your website from the sandbox environment to the actual environment. I will explain the switching later in this tutorial. To access the sandbox environment, goto Paypal Developer site and login with your paypal credentials.
  3. After logging in, goto Applications tab and choose Sandbox Accounts. Here you may create sandbox accounts for testing purposes.
  4. Create two sandbox accounts. One will be used to receive payments and the other to pay. It is advised to create two Business Accounts. You may also add the initial balance in your account for testing purposes, say $1000! You may login to Sandbox Account and change additional settings, like currency, as per your requirements
  5. Now, on Applications/Sandbox accounts page, click on the sandbox account into which you want to receive payments and click on Profile. In the following window, click on API Credentials. You will require these for your website.
  6. In your website code, define variables as follows :
    $url = 'https://api-3t.sandbox.paypal.com/nvp';
    $url1 = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
    $apiUsername = "[your api username]";
    $apiPassword = "[your api password]";
    $apiSignature = "[your api signature]";
    $currencyID='[currency code - refer here for codes], Eg:USD';
    $version = '94.0';
    $returnURL = "http://url/to/call/upon/success.php";
    $cancelURL = "http://url/to/call/upon/cancel.php";
    Remember to keep these credentials in a safe place, preferably outside the public folder and use require_once to get them into your payment page.
  7. Now you need to initialize your transaction with paypal by sending a POST request to the Paypal server. The PHP CURL comes handy here.
    $amount = $_POST['amount']; //transaction amount

    //Set up curl
    $curl_connection = curl_init($url);
    curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 1);

    //set post request parameters
    $post_param[] = 'USER='.urlencode($apiUsername);
    $post_param[] = 'PWD='.urlencode($apiPassword);
    $post_param[] = 'SIGNATURE='.urlencode($apiSignature);
    $post_param[] = 'VERSION='.urlencode($version);
    $post_param[] = 'PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("Sale");
    $post_param[] = 'PAYMENTREQUEST_0_AMT='.urlencode($amount);
    $post_param[] = 'PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($currencyID);
    $post_param[] = 'RETURNURL='.urlencode($returnURL);
    $post_param[] = 'CANCELURL='.urlencode($cancelURL);
    $post_param[] = 'METHOD='.urlencode("SetExpressCheckout");

    //make post request string from the array $post_param
    $post_string = implode ('&', $post_param);

    //set the curl option - post parameters to the above $post_string
    curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);

    //perform the curl call
    $result = curl_exec($curl_connection);

    //close connection
    curl_close($curl_connection);
  8. Now $result will contain the response from the paypal server. We will now parse this response and extract the parameters passed from paypal.
    $params = explode('&', $result);
    $parsedArray=array();
    foreach ($params as $value)
    {
    $tmp = explode('=', $value);
    $parsedArray[urldecode($tmp[0])] = urldecode($tmp[1]);
    }
    The $parsedArray will now contain the response in the form $parsedArray['key']='value'
  9. You may want to log each and every request and response to and to and from paypal for debugging, troubleshooting or customer care etc.
    file_put_contents("paymentLog.txt", json_encode($parsedArray)."\n",FILE_APPEND);
  10. If everything goes fine, the paypal response will contain a key 'ACK' with value 'Success'. Also, paypal will issue a token for this transaction. Now you have to redirect your customer to the paypal page with this token as a parameter. You may do this redirection in anyway, I'm using the Javascript method for its simplicity.
    if($parsedArray['ACK']=="Success")
    {
    $cmd = urlencode("_express-checkout");
    echo "<html><script type='text/javascript'>window.location='$url1?cmd=$cmd&token=$token';</script></html>";</script></html>";
    }
    else
    {
    //you may log the failure here
    die("Failed");
    }
  11. Now the Customer will be redirected to the paypal page and he will perform the payment authorization there and after the customer finishes these steps, paypal will invoke $returnURL with another set of response parameters. If the customer cancels the transaction, paypal will invoke $cancelURL with the corresponding response parameters.
  12. Now in your $returnURL page (Eg: success.php),you have to write the code to handle the call from paypal as you still haven't received the money. For this you need to perform additional requests. You will do those here. First, you may log all calls to this page.
    file_put_contents("paymentLog.txt", json_encode($_REQUEST)."\n",FILE_APPEND);
  13. The call from paypal will have the same token issued before and a payer id. You will require these to get the details of the payer. You may do that by another doing request to the paypal api, we perform another CURL for this.
    $token = trim($_REQUEST['token']);
    $payerID = trim($_REQUEST['PayerID']);

    //setup curl
    $ch = curl_init($url);
    curl_setopt($ch,CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch,CURLOPT_POST,true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

    //set up post parameters
    $post_param[] = 'USER='.urlencode($apiUsername);
    $post_param[] = 'PWD='.urlencode($apiPassword);
    $post_param[] = 'SIGNATURE='.urlencode($apiSignature);
    $post_param[] = 'VERSION='.urlencode($version);
    $post_param[] = 'TOKEN='.urlencode($token);
    $post_param[] = 'PAYERID='.urlencode($payerID);
    $post_param[] = 'METHOD='.urlencode("GetExpressCheckoutDetails");

    //make post string from $post_param array
    $postString = implode('&', $post_param);
    //set the curl post options to $postString
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);

    //execute the curl
    $result = curl_exec($ch);
    //close connection
    curl_close($ch);

    //parse the response from paypal
    $params = explode('&', $result);
    $parsedArray=array();
    foreach ($params as $value)
    {
    $tmp = explode('=', $value);
    $parsedArray[urldecode($tmp[0])] = urldecode($tmp[1]);
    }

    //log the response
    file_put_contents("paymentLog.txt", json_encode($parsedArray)."\n",FILE_APPEND);
    The response from paypal will contain various details of the payee, like Name, shipping address etc. You may refer the paymentLog in the above step to know more.
  14. Again, if everything goes fine, paypal will return a key 'ACK' with value 'Success'. Now we have to do another request, to actually do the payment. Again, we will use curl for the same.
    if($parsedArray['ACK']=="Success")
    { //setup curl
    $ch1 = curl_init($url);
    curl_setopt($ch1,CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch1,CURLOPT_POST,true);
    curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, true);

    //setup post params
    $post_param[] = 'USER='.urlencode($apiUsername);
    $post_param[] = 'PWD='.urlencode($apiPassword);
    $post_param[] = 'SIGNATURE='.urlencode($apiSignature);
    $post_param[] = 'VERSION='.urlencode($version);
    $post_param[] = 'TOKEN='.urlencode($parsedArray['TOKEN']);
    $post_param[] = 'PAYERID='.urlencode($parsedArray['PAYERID']);
    $post_param[] = 'PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("Sale");
    $post_param[] = 'PAYMENTREQUEST_0_AMT='.urlencode($parsedArray['PAYMENTREQUEST_0_AMT']);
    $post_param[] = 'PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($currencyID);
    $post_param[] = 'METHOD='.urlencode("DoExpressCheckoutPayment");

    $postString = implode('&', $post_param);
    curl_setopt($ch1, CURLOPT_POSTFIELDS, $postString);

    //execute
    $result1 = curl_exec($ch1);
    curl_close($ch1);

    //parse response
    $params = explode('&', $result1);
    $parsedArray=array();
    foreach ($params as $value)
    {
    $tmp = explode('=', $value);
    $parsedArray[urldecode($tmp[0])] = urldecode($tmp[1]);
    }

    //log response file_put_contents("paymentLog.txt", json_encode($parsedArray)."\n",FILE_APPEND);
    }
  15. If everything goes fine, you will again receive key 'ACK' with value 'Success' and the transaction is complete. You have finally received your money from the customer and you may acknowledge the customer with a message. You will also receive a Transaction ID, which you may provide to the customer.
    if($parsedArray['ACK']=="Success")
    {
    $ppTS = $parsedArray['TIMESTAMP'];
    $ppCorrelation = $parsedArray['CORRELATIONID'];
    $ppACK=$parsedArray['ACK'];
    $token = $parsedArray['TOKEN'];
    $payerID = $parsedArray['PayerID'];
    $transactionID = $parsedArray['PAYMENTINFO_0_TRANSACTIONID'];
    $amt = $parsedArray['PAYMENTINFO_0_AMT'];
    //refer paymentLog.txt in the step before for more parameters

    echo "Received your payment Successfully. Transaction ID : $transactionID ";
    }
  16. Now, if the customer had cancelled the transaction, paypal will redirect him to $cancelURL (Eg: cancel.php). You may write the code to handle the same here.
    //log file_put_contents("paymentLog.txt", json_encode($_REQUEST)."\n",FILE_APPEND);
    $token = $_REQUEST['TOKEN'];
    echo "<html>

    <body>
    <center>
    <h3>Transaction Failed. Token ID : $token</h3>
    For further enquiries, contact our customer support with this token id.

    <srtong><a href='index.php'>Back to Home</a></strong>
    </center>
    </body>
     
    </html>";
  17. It is to be noted that we are using Five files here. The First one is to store the api details (see Step 6). You have to 'require_once' this file in all the remaining files. The Second will be the starting point of your payment(Eg: pay.php), code from Step 7 to 10 goes into this page. The Third file is the file specified in $returnURL (Eg: success.php). Code from Step 12 to 15 goes into this page. And the Fourth file, the one specified in $cancelURL (Eg: cancel.php) handles cancelled transaction(Step 16). Fifth file is the paymentLog.txt which logs all steps in the payment.
  18. To change the environment from sandbox to the actual one, you just have to edit the urls and credentials in the First file. For Example Substitute www.paypal.com for www.sandbox.paypal.com and so on. You will also have to set the API Credentials and you may have to change some settings in the actual paypal site(like enabling the express transaction method in profiles/my selling tools, getting the API credentials etc) depending on your country.
  19. You may test your site by making payments from your second sandbox account and verifying its reception in your other sandbox account. If you are encountering any error, the log file (paymentLog.txt) may aid you in debugging. More Details may be found here.


Don't forget to leave your comments ;)

Sending SMS and Making Calls from your Website Programatically - Part 2 - Handling Incoming Calls and Messages

This post assumes that you have read the part 1 of this series, which covered making calls and sending messages programatically from twilio. This part will cover the handling of incoming messages and phone calls.


  1. Login to your twilio account and goto the 'Numbers' section. Here you can see all the numbers that you have registered with twilio and those you can use with twilio.
  2. Click on any of the listed numbers
  3. On the following page, you will see a textbox under Voice and another text box under Messaging section. Enter the URL to your page in this box so that twilio will invoke this page on receiving a call or message to the number you have selected.(Like a Landing URL or Call back reference). You may set the method to invoke your page(GET/POST), in the following drop down box.
  4. You may write the code to handle your call/message in this landing page. Try
    file_put_contents("test.txt",json_encode($_REQUEST));
    in your landing script so that you may see the various parameters passed to your page from twilio upon receiving a call or message, and you may use these parameters according to your logic.
  5. You may optionally echo an xml (twiml) formatted string for twilio to respond to the incoming call or message. For example,  
    $toPhone = $_REQUEST['From']; //sender's number
    $content = "Thank you for your response. Your sms response : ".$_REQUEST['Body'];
    //xml response
    echo '<?xml version="1.0" encoding="UTF-8"?><Response><Sms from="$twilio_number" to="$toPhone">'.$content.'</Sms></Response>';
    will acknowledge the sms sender with another message. 
PS: If you are having a trial account with twilio, you will only have limited permissions. You can call/text the numbers verified with twilio only.

Sending SMS and Making Calls from your Website Programatically - Part 1

There may be many ways to send/receive SMS or to make phone calls programatically. Here, I'm explaining the twilio method.  I assume the reader to have knowledge on PHP, web designing and hosting.

This guide is divided into two parts, part 1 covers outgoing calls and messages and part 2 covers handling of incoming calls and messages.


Using Twilio

Twilio is a Cloud Service which enables a programmer to send/receive messages, make/receive phone calls etc, programatically. Steps for setting up twilio are as follows.
  1. Sign Up/Register with twilio (Its FREE!!). You may need to verify your account by typing in a verification     code which you will receive via SMS. After this step, you will get your first twilio phone number.
  2. Now you will be taken to a test drive area, from where you may perform a test drive of the various features offered by twilio. You may do an optional test drive and then proceed to your account.
  3. On the Dashboard Section, you will see an Account SID and AUTH Token(This one will be masked by dots, click on the lock icon to reveal the token). You will need these two for making calls and sending messages.
  4. Install Twilio library to your web server or download the php source file from here and include the file into your code, as follows
    require_once '/path/to/twilio-php/Services/Twilio.php';
  5. Copy these two to your PHP code as follows
    $twilio_sid = "your twilio sid here";
    $twilio_token = "your twilio auth token";
    $twilio_number = "your twilio number here";

  6. Initialize twilio services as follows
    $client = new Services_Twilio($twilio_sid, $twilio_token);
  7. Now, you need to create an xml file(termed TwiML) for twilio, which gives twilio directions for what to do. An example is given below 
  8. <response>
          <say voice="woman">Hello World</say>
    </response>
    A complete reference to the various options available may be found here
  9. Making a Call : the following php code segments makes a call
    $toPhone = +911234567890;
    $call = $client->account->calls->create("$twilio_number", "$toPhone", "path to xml file", array());
    echo $call->sid;
    The statement performs a call and provides us a SID which can uniquely identify the call.
  10. Sending an SMS: This is similar to making a call
    $message = $client->account->sms_messages->create("$twilio_number", "$toPhone", "Hello World", array());
    echo $message->sid;
    This also returns a unique SID
  11. Additional Parameters may be passed to create method via 'array()'. Like, array("Parameter_1" => "value","Parameter_2" => "value") and so on. More references can be found here
    1. Calls
    2. SMS
    Example:
    $call = $client->account->calls->create("$twilio_number", "$toPhone", "path/to/xml", array("Record" => 'true',"StatusCallback" => "http://domain.com/landingPage.php"));
The Part 2 of this post will detail on how to handle incoming calls and messages via Twilio.