This article presents a solution to track conversions from PayPal Instant Payment Notifications (IPN) in AdWords. The most common way to track PayPal payments is using a tracking pixel on the “thank-you” page that PayPal sends users to after completing a transaction, but this is error prone if the user doesn't return to the page or payment is later declined. After writing a tutorial exploring the new AdWords API Offline Conversion Tool, I was thinking of problems that could be solved using it and one idea was for tracking server-side conversions like IPN notifications.
Tracking Server-side Conversions with the Conversion Upload
With the offline conversion import, you can now send conversion events to AdWords from server-side code using the AdWords API. You can read my previous post to find out how it works, but I'm going to explain the solution to the present problem using the following steps:
- Capture the Google click id and store it in a cookie.
- Insert the click id into the
customparameter of a PayPal “Pay Now” button.
- Retrieve the click id from the
customparameter of a completed PayPal payment IPN.
- Save the click id and payment amount in a file.
- Retrieve the payments from the file and upload each conversion to AdWords.
There are several reasons why you should store the notification data instead of uploading the conversions while processing each IPN:
- You can't upload offline conversions too soon after a click: you need to wait four to six hours or else you'll get an error.
- You could loose the conversion data if the upload fails.
- PayPal prefers your IPN listener to respond quickly without running slow backend processes.
- It's better to batch AdWords API operations where possible.
Instead of using a file, you'll probably want to use a database or maybe a message queue in a production system to avoid any possible locking errors, but I'm using a file here to keep the explanation simple.
Extracting the Click Ids from the IPN Notifications
You now need to collect the conversions from the payment notifications sent by PayPal. We only want to report conversions for completed payments, so I'll start by checking if the IPN is for a completed payment:
You can extract the click id and payment amount from the
Next we need to extract the payment date:
This code converts the
payment_date parameter to a timestamp by matching it to a date format; the script also extracts the timezone as it can vary depending on the season.
Once the parameters have been extracted, you can append them to a file ready for uploading to AdWords. Here's the full script:
If this script runs correctly, you should end up with a file something like the following (headings added for clarity):
In the next section I'll show you how to upload these conversions.
Uploading the Conversions to AdWords
Before uploading the conversions, you need to create a new Import conversion type in AdWords, which is discussed in my previous article so I won't repeat it here. Once you have a conversion type, you can upload your conversions using the following script:
This script opens the file, creates an
OfflineConversionFeed for each row, and then uploads the conversions to AdWords; once the API call completes the script deletes the conversions file ready for the next batch of payment notifications.
A problem with this script is that you'll get an error if you try to import a too recent click. You can remove this problem by only uploading conversion events that happened at least six hours ago:
This version checks that the timestamp is at least six hours old, and stores newer conversions in the
$skippedConversions array. You can now drop the old file and place the skipped conversions into it:
This should run without any errors, but to protect your conversion data in case any unforeseen errors occur, you should use the AdWords API Partial Failure feature. This registers all your successful conversions and returns any that have failed. To use it, set the
partialFailure header then process the
partialFailureErrors property of the API call result:
This loops through each error—if there are any—extracts the conversion object, and uses it to reconstruct the original row from the file (some work is also done to parse the date into a timestamp). The script will then write these rows back to the file together with the skipped conversions.
Here's a full script that puts all of this together with additional boilerplate API access code: