Integrating a Desktop application with Pay Pal in c++

July 3, 2018

Introduction

This article was written following a need to integrate PayPal Express Checkout in a c++ Win32 application.

 

Background

I was thinking about integration in the background without any website other than the payment page as part of a desktop application in c++. Would it be possible to following the following scenario:

  1.  Generate the invoice / sale and via REST API obtain some sort of unique ID for the transaction to come.

  2. Redirect to Paypal web site to a ad-hoc payment page, using the unique ID.

  3. In the background, check every few minutes, via REST API, if the payment was made.

The Solution

I have found a way and created a Proof of Concept (POC) for a built-in payment processing engine which allows you to accept payments from any credit card holder (regardless of being a PayPal customer) and pay for unlocking a software product or for specific features.

To process payments you need to apply as a PayPal developer and obtain your own PayPal credentials. You will then receive 2 sets of credentials. One for tests ("sandbox") and the other for real life.

First you should test the Sandbox to test the API.

I have created a PayPal class with one "init()" used for both "sandbox" and real life transactions.

 

Void InitPayPal(BOOL Sandbox, LPTSTR User, LPTSTR password, LPTSTR signature, LPTSTR successUrl, LPTSTR failedURL)

 

Sandbox – indicates whether you are testing your integration using PayPal's Sandbox account, or going live.

User – your PayPal user name

Password – your PayPal password

Signature – you PayPal signature

successUrl – a url leading to a web page which you wish to be shown after successful payment.

failedURL – a url leading to a web page which you wish to be shown after failed / cancalled payment.

The InitPayPal() function is straight forward:

 

void InitPayPal(BOOL Sandbox, LPTSTR User, LPTSTR password, LPTSTR signature, LPTSTR successUrl, LPTSTR failedURL, LPWSTR ProductName)

{

   m_sandbox = Sandbox;

   m_user = User;

   m_password = password;

   m_signature = signature;

   m_SuccessURL = successUrl;

   m_FailureURL = failedURL;

   m_ProductName = ProductName;

   CUR_CHAR = L"$";

   SYSTEMTIME st;

   GetSystemTime(&st);

   g_tPayStart = CTime(st);

   InitilizedPaypal = TRUE;

}

 

Initiating a payment

When you wish to initiate a payment from your program, you call the following function which I wrote which generally build a string (ExpChkoutStr) and use the following PayPal API call:

For all HTTP communication, I used The WinHTTP class was developed by Cheng Shi. 

Here is how I send the initial request to the PayPal servers:

 

// Send string to PayPal server WinHttpClient WinClient1(ExpChkoutStr.GetBuffer()); WinClient1.SetRequireValidSslCertificates(false); // Now we get PayPal's response: WinClient1.SendHttpRequest(L"GET"); httpResponseContent1 = WinClient1.GetResponseContent(); CString strTransactionRet = UrlDecode(httpResponseContent1.c_str());

 

As you can see we are sending PayPal a long string we generate using another function. This function combined the credentials, the nature of the requested transaction, additional details all into a single string.

 

CString result;

result = (m_sandbox) ? PAYPAL_SANDBOX_HTTPS :

PAYPAL_REAL_HTTPS;

result += Q_USER;

result += m_user;

result += AND_PASSWORD;

result += m_password;

result += AND_SIGNATURE;

result += m_signature;

result += AND_PAYMENTAMOUNT;

result += strAmount;

result += L"&METHOD=SetExpressCheckout";

result += AND_RETURN_URL;

result += m_SuccessURL;

result += AND_CANCEL_URL;

result += m_FailureURL;

result += AND_VERSION;

result += L"&NOSHIPPING=1";

result += L"&ADDROVERRIDE=0&BRANDNAME=Secured Globe, Inc.";

result += L"&PAYMENTREQUEST_0_DESC=";

result += L"Item name: " + strUnits + L"(" + UnitName + L") "; result += L"Price: " + strAmount;

result += L"&NOTETOBUYER=Here you can add a note to the buyer";

 

Now, result will hold the string to be sent in the previous code block.

We then examine the result we have received back from PayPal:

The result from the PayPal server is a "token" used to figure out a one-time web page (LinkToOpen ) that must be opened in order for the end user to confirm the purchase:

 

// Extract token from response CString sToken = ExtractElement(strTransactionRet, L"TOKEN");

if (sToken == L"")

{

   wprintf(L"Internal error: (Paypal):

   no token was generated (%s)", strTransactionRet);

   MessageBox(NULL, L"Internal payment processing error", L"", MB_OK);   

   return FALSE;

}

CString LinkToOpen = (m_sandbox) ? SANDBOX_PAYPAL_CHECKOUT : REAL_PAYPAL_CHECKOUT; LinkToOpen += L"&token="; LinkToOpen += sToken;

 

To extract elements from the PayPal server response, we wrote this small function:

 

CString ExtractElement(CString EntireString, CString ElementName)

{

   CString result = L"";

   CString WhatToFind = ElementName + L"=";

   int foundToken = EntireString.Find(WhatToFind);

   if (foundToken > -1)

   {

      int EndToken = EntireString.Find(L"&", foundToken);

      if (EndToken != -1)

      {

         result = EntireString.Mid(foundToken + ElementName.GetLength()+1, EndToken - foundToken - ElementName.GetLength()-1);

      }

   }

   return result;

}

 

Invoking a one-time web page

The next step is to open the default web browser with a one-time generated secure web page hosted by the PayPal server:

 

STARTUPINFO si;

PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));

si.cb = sizeof(si);

ZeroMemory(&pi, sizeof(pi));

CString command_line;

command_line.Format(L"cmd.exe /c start \"link\" \"%s\" ", LinkToOpen);

 

if (!CreateProcess(

   NULL, // No module name (use command line)

   command_line.GetBuffer(),

   NULL, // Process handle not inheritable

   NULL, // Thread handle not inhberitable

   FALSE, // Set handle inheritance to FALSE

   NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, // No creation flags

   NULL, // Use parent's environment block

   NULL, // Use parent's starting directory

   &si, // Pointer to STARTUPINFO structure

   &pi) // Pointer to PROCESS_INFORMATION structure )

{

   wprintf(L"CreateProcess failed (%d).\n", GetLastError());

   // At this stage you would want to mark this transaction as "failed"

   return FALSE;

}

 

Then the rest is to maintain a small database of all pending transactions and follow up each of them until it is either succeed, failed, cancelled or if a timeout has passed.

 

User Interface

We have used a minimal UX integrated in our small DRM component, which looks like this:

 

 

Then the one-time web page will look like this:

 

 

 

Examples are from a real product Datattoo Recovery.

 

 

Please reload

Featured Posts

Integrating a Desktop application with Pay Pal in c++

July 3, 2018

1/4
Please reload

Recent Posts

March 14, 2017

Please reload

Archive
Please reload

Search By Tags
Follow Us
  • Facebook Basic Square
  • Twitter Basic Square
  • Google+ Basic Square

© 2008-2018 Secured Globe Inc.