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 ;)

No comments:

Post a Comment