BEFORE TO TRY WITH THESE EXAMPLES YOU SHOULD CHANGE SOME THINGS
* Into the source code of the example in procedure Purchase() YOU SHOULD CHANGE
firstname.lastname@example.org with your own sandbox email address.
* Into the script ipn.php replace these values:
$to_address = 'email@example.com';
$from_address = 'firstname.lastname@example.org';
$from_name = 'av-soft.com';
$confirmation_subject = 'Payment Confirmation';
EXAMPLES PAYPAL IPN
1. What is the PayPal IPN service?
2. What is the PayPal Sandbox?
3. Using IPN with the OLM from a Delphi application
4. The Example 1
5. Additional details
6. The example 2
What is the PayPal IPN service?
The PayPal IPN (Instant Payment Notification) is a message service that notifies the events associated with a PayPal transaction. This notification is sent to an URL specified for you, called "The Listener" which is responsible for processing transactions achieved in your PayPal account. At this way, when a transaction is processed (e.g. a payment to your account), your URL instantly will receive all related information with this operation.
There are two ways to specify the URL listener in order to inform to PayPal where should be send the IPN messages.
1. Select Instant Payment Notification into your account profile, then specify the URL listener and check [x]Activate it.
2. Dinamically, including the URL listener together with each payment request, e.g. from a [Pay Now] button.
In our example we use the second option, specifying the URL Listener together with the payment request.
For more information download the IPN Guide from this link: https://cms.paypal.com/cms_content/US/en_US/files/developer/IPNGuide.pdf
What is the PayPal Sandbox?
When the listener is being implemented, which in our case is a php script (ipn.php), it is necessary to test and debug it like any other piece of software, and these tests can not be done using our real PayPal account (PayPal Live ). To that end, PayPal has a separate place is called the sandbox, where you can test using fictitious accounts.
o create fictitious accounts must first create an account on the PayPal Sandbox. This is the link where you can do it:
Create your account using a different email address than your actual PayPal account. Once you have created your account click "Test Accounts"
Then create at least two accounts, one to simulate the venderdor and one for the buyer. The vendor must be a Busines account, and the buyer a Personal account. See an example in the image below:
You can learn more by downloading the Sandbox User Guide from the following link:
Using IPN with the OLM from a Delphi application
The idea is to put a button [Pay Now] in the registration form of the application that when clicked by the user it is redirected to the PayPal site for payment. Once finished the payment, PayPal automatically sends an Instant Message to your Listener with all information related to the payment. Our Listener is the ipn.php script and this should be located into the OLM folder on our site. Then ipn.php verifies the information received and modify the corresponding record (Paid = Y) if the operation has been "Completed" or putting (Paid = P) if the status is "Pending".
Some few seconds after the payment, the user can click on the button [Activate] to activate the application. We see that this method is fully automatic, no need to send the installcode to the developer then wait for the registration key. The user simply makes the payment and has its registered application ready to use. In addition, ipn.php will send an email to you with all relevant information. In the case of having the status "Pending", you should check the transaction in your PayPal account, then when the transaction is completed you should go to the OLM control panel and edit the corresponding record setting (Paid = Y) in order to allow to the user activate the application with the [Activate] button.
Most normal PayPal payments haves the status "Completed", but using the Sandbox can be the opposite, the most with the status "Pending".
The example 1
In this example we have placed several buttons with different registration kinds, each with its price as shown below:
There are four elements involved in the example:
1. Delphi Application.
2. The script ipn.php (the listener) located in the OLM folder of our site.
3. The script prices.php located in the OLM folder of our site.
4. A text file with the prices for each of the buttons, located in the OLM folder on our site. Its name is formed by the AppID with txt extension. In our case '12310. txt '. In this way, when you change this file also changes the prices without touching the application. This file can be created using Windows Notepad or the text editor you normally use. Below you can see the file's contents 12310.txt of our example using the Notepad:
The amounts correspond to the settings for each of the buttons you've placed. Whenever you want to change prices must edit this file and upload it to the OLM folder of your site replacing the existing one.
Before explaining more details see running our example. When this runs the first time will enter directly into the registration form that looks like the image below:
Let's click on the [Start Trial] and see the result of the operation:
After start the trial period, you will see the registration buttons:
Now let's click the button [90 days]. The code used is as follows:
procedure TRegForm.Btn90Click(Sender: TObject);
Purchase(90,1,'TestApp 90 days registration');
'&custom='+inttostr(days)), nil, nil, SW_SHOWMAXIMIZED);
Parameters have the following meanings:
days: Days of the new period to register (90 in the example)
idx: Index (0 .. 4) of the amount to be used, 1 in our example that corresponds to the amount of 25.15 (see file appid.txt).
product: Product description, in our example 'TestApp registration 90 days".
The values passed to the PayPal site are:
1. The URL of the PayPal server (In this case the SandBox)
Note that after the tests made with SandBox, in the final version of your application, you must replace the SandBox URL by the live PayPal URL https://www.paypal.com/cgi-bin/webscr
2. The vendor email address
3. The URL of our Listener
4. The source type of the request sent to PayPal. In this case from a button click.
5. Name of the Item (product sold)
item_name = "+product
in our case 'TestApp 90 days registration'
6. Transaction amount
this code assigns to the variable price the amount value corresponding to the idx index, in our case 25.15. The avfloat2str function converts the floating value of the sum to two decimal format, always using the dot as decimal separator. FormatFloat can not use here because it uses the decimal separator Windows configuration that varies for each country.
7. The currency code
8. Item Number. We use this variable to pass the three required values that later we will need into ipn.php to identify the record in the OLM. These three values are the InstallCode, the AppID and the price index, separated by the "|" character.
9. Custom is a variable pass-through that allows the developer to pass any value that deem appropriate, in this case we pass the days for the new period.
Clicking the button [90 days] we are redirected to the PayPal Sandbox in order to make the payment:
Enter your fictitious email Personal with the appropriate password then click on [Log In]. Then next screen is displayed:
Click on [Pay Now] then the payment is accomplished and the next screen is displayed:
Now the payment was finished. Wait some seconds and see if the email was sent to you by ipn.php with information about the payment.
Payment received from User
Transaction result: NO_ERROR
Total amount: 25.15 USD
Payment Type: instant
Payment status: Pending
Pending reason: paymentreview
Payment date: 19:13:34 Feb 09, 2011 PST
Transaction ID: 0BL35875YB607512V
Transaction Type: web_accept
Transaction Fee: 1.03
Total handling amount:
Total shipping amount:
Receiver Id: K3CEMHUWHBLC2
Receiver email: email@example.com
Item name: TestApp 90 days registration
Item number: A2D0FB3CB909|12310|1
Verify sign: Aunr11ygbUpo21nDKjl6DT0GFOVqAoVEU3KPLYYcT36q0kgWm5BsS1wx
Transaction subject: 90
Last name: User
Address city: San Jose
Address country: United States
Residence country: US
Address state: CA
Address status: confirmed
Address street: 1 Main St
Address zip: 95131
Address name: Test User
Payer ID: D8QJ77BWFW94W
Payer status: verified
Payer email: firstname.lastname@example.org
Let's see how it has changed the corresponding record in the OLM:
We see that fields (Days = 90) who are the days of the new period to activate (Paid = P) which mean "Pending", indicates that for some reason payment has not been completed and is under review and the "Other" field contains the most important fields of transaction.
Then we go into the OLM control panel http://av-soft.com/olm51/s5cp.com and change the corresponding record setting (Paid = Y) so that the user can activate the new period. Select the appropriate option as shown in the picture below then click on the [Save Record].
Now the user can activate the new period by clicking on the [activate] button.
After receiving the message 'Registration activated' we can see the new registration status, now with "Temporary 120 days - 120 days left". What happened? the new period should be of 90 days?
What happens is that we use the method OnlineRenew2 () to activate the new period. There are three ways to activate the new period:
1. Using the method OnlineRenew(). Thus begins a new period as specified without rescuing the remaining days of the previous period. In this case the result would have been "temporary 90 days - 90 days left. "
2. Using the method OnlineRenew2 (). Thus the days of the new period are added to the remaining days of the previous period (in this case the 30-day trial period), so get the result (30 +90) = 120 "Temporary 120 days - 120 days left" .
3. This option also uses OnlineRenew() but does not allow the user to activate the new period before it has completely consumed the previous one, so in this case will wait the remaining 30 days before to allow to the user to activate the new period of 90 days. The code used is as follows:
if (keydata.KeyType = Trial) then AVLock.OnlineRenew(0)
else if (keydata.KeyType = Temporal) then
if (keydata.DaysLeft = 0) or (keydata.Status = expired)
end else showmessage('You have '+inttostr(keydata.DaysLeft)+' days remaining '+
'on your actual period, so please press this button when the current period expires');
For more information see the section (Using AVLock SIMPLE > Basic Concepts > How to register your application using the OLM).
Some additional details
As we have seen the prices are stored in the file appid.txt (e.g. 12310.txt). These prices are read from the Delphi application using the script prices.php. The code used in the example is:
with Form1 do begin
for i:=0 to 4 do prices[i]:=0;
phpfile := avlock.OlmPath+ '/prices.php';
postdata := inttostr(AVLock.AppID);
s := trim(OnlineRequest(phpfile, postdata, avlock.EncryptionKey2, avlock.WebHost));
arr := explode('|', s, 0);
for i:=0 to (length(arr)-1) do begin
if avisnum(arr[i]) then prices[i]:=avstr2float(arr[i]);
the item price and the index (position in the list) are passed through the PayPal payment request and forwarded to the script ipn.php via the PayPal IPN message after the payment were accomplished.
Also the ipn.php script get again the price reading it from the file appid.txt (e.g. 12310.txt) and the value obtained is compared with the one received from the IPN message, if do not match, the operation is aborted and the email received will have the corresponding error message: "AMOUNT MISMATCH. "
The new version of RegMonitor shows the transaction data stored in the Other field as separate fields (one per line), as shown in the image below:
The example 2
This example implements discount coupons. The registration form instead of buttons uses radio buttons.
For each coupon you must create a file with the name of the coupon and txt extension. The contents of this file is a code that determines what action to take. You can create two types of coupons, discounts and free registration. Below are some example files we have implemented and are housed in http://av-soft.com/olm51
Coupon File Content Actión to apply
------ ---------- ------- -----------------
AX125C AX125C.txt F365 Free Registration by 365 days
NM12RA NM12RA.txt P25 Price with 25% OFF
451KLJ 451KLJ.txt P50 Price with 50% OFF
Along with the sample files are included the coupon files. Remember that these will take effect after be placed in the folder of the OLM.
We see below how applying the coupon NM12RA (content = P25) prices fell by 25%
Below we can see how to apply the coupon AX125C (content F365) the application is automatically registered for a period of 365 days. You see that we put the coupon code 'P' for price discounts and 'F' for free registration. When you put 'P' the number determines the discount rate to apply and when using 'F' number determines the number of days to register for free.
When using a 'F' coupon, does not need the activation since this process is done automatically, all you have to do is enter the coupon and click on [Apply].
When using a ´P´coupon, by clicking on [Apply] will reduce prices to pay. Then you have to pay with the button [Pay Now], then activate with the button [Activate], as we did in Example 1.