PayPal IPN Listener WordPress Without Using Plugin
- Article
- Comment (7)
Introduction
PayPal IPN Listener WordPress Without Using Plugin. PayPal ipn will be sent you to validate each transactions. You can validate the transaction details with help of it. For IPN things,it will be sent you indirectly. Your website users can’t see it. So, this is private and hidden notification to you from PayPal.
Let’s begin with receiving Hidden URL and IPN functionality. It might be easy to receive it via wp-ajax.php file you can pass additional parameter to receive it. like this.
`http://yoursite.com/wp-admin/wp-ajax.php?action=kv_paypal_ipn`.
you can write the functionality like this. Let’s hook the function.
add_action( 'wp_ajax_kv_paypal_ipn', 'kv_paypal_ipn_callback' ); add_action( ‘wp_ajax_nopriv_kv_paypal_ipn’, ‘kv_paypal_ipn_callback’ ); function kv_paypal_ipn_callback() { // here we can verify and validate the transactions. }
The above one is a simple one to handle the ajax function on your own. We need debugging options to see if, any problem encounters in the middle. so define a constant for debugging,
define("DEBUG", 1);
And we need a constant to change the sandbox to live. So lets create one more constant for it.
define("USE_SANDBOX", 1);
Here is the sandbox and live switching thing,
if(USE_SANDBOX == true) { $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr"; } else { $paypal_url = "https://www.paypal.com/cgi-bin/webscr"; }
PayPal IPN Listener
We need log file to check the debugging things. so create log file.
define("LOG_FILE", "./ipn.log");
Now, we can retrieve all the $_POST parameter and its entire things.
$raw_post_data = file_get_contents('php://input');
This might be array of parameters. let’s explode and add cmd validator with it.
$raw_post_array = explode('&', $raw_post_data); $myPost = array(); foreach ($raw_post_array as $keyval) { $keyval = explode ('=', $keyval); if (count($keyval) == 2) $myPost[$keyval[0]] = urldecode($keyval[1]); } // read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-validate'; if(function_exists('get_magic_quotes_gpc')) { $get_magic_quotes_exists = true; } foreach ($myPost as $key => $value) { if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&$key=$value"; }
Let’s begin the cURL to get connection and validate it.
$ch = curl_init($paypal_url); if ($ch == FALSE) { return FALSE; } curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array( ‘User-Agent: PHP-IPN-Verification-Script’, ‘Connection: Close’ )); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
Suppose,if it has any error or problem we need to report it to log file.
if(DEBUG == true) { curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLINFO_HEADER_OUT, 1); }
cURL connection timeout and close function.
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
Getting result and either success of failure to create log.
$res = curl_exec($ch); if (curl_errno($ch) != 0){ // cURL error if(DEBUG == true) { error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE); } curl_close($ch); exit; } else { // Log the entire HTTP response if debug is switched on. if(DEBUG == true) { error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE); error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE); } curl_close($ch); } $tokens = explode("\r\n\r\n", trim($res)); $res = trim(end($tokens));
Here, after you can validate the things with help of $res
. With the help of following code,you can log the results either success or failure, than we will do further database things.
if (strcmp ($res, "VERIFIED") == 0) { if(DEBUG == true) { error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE); } } else if (strcmp ($res, "INVALID") == 0) { if(DEBUG == true) { error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE); } }
That’s it. You can make this as plugin or you can simply put this function on your theme functions.php
and make it working for you.
PayPal IPN Listener WordPress Without Using Plugin
If you need to store the values in Database, you can save it with below code.
global $wpdb; $ipnTable = $wpdb->prefix.'IPN_table'; $pack_id = $post_arr['item_number1']; $wp_user_id = 2; $wpdb->insert($ipnTable, array('pack_id' => $pack_id,'wp_user_id' => $wp_user_id));
This is a sample code to save it.
How do I insert the IPN message into the wordpress database?
I have updated my article. Please check it again and there I said an example to make it record in database
Your tutorial needs updating, the call needs to be to ‘admin-ajax.php’ and the hook should begin with ‘wp_ajax_nopriv_’ for use with non logged in users.
admin-ajax.php?action=kv_paypal_ipn
add_action( ‘wp_ajax_nopriv_kv_paypal_ipn’, ‘kv_paypal_ipn_callback’ );
Source i used
https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)
With the above edits its now working perfectly with paypals ipn sim.
Updated,
Thank you Daniel
oh and another edit. user agent is required now.
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
‘User-Agent: PHP-IPN-Verification-Script’,
‘Connection: Close’
));
Whan I use this as a plugin, then what is my IPN URL
http://yoursite.com/wp-admin/wp-ajax.php?action=kv_paypal_ipn
Is it add like this?
Yes I forget to mention it in the article, let me update it there.