I am searching for how to use the PayPal IPN (Instant Payment Notification) from past 2 weeks and couldn't understand how exactly to use it in my code.
I am using the following HTML code to create a PayPal button
button.html
<form name="paypalForm" action="paypal.php" method="post">
<input type="hidden" name="id" value="123">
<input type="hidden" name="CatDescription" value="20Percents (12 Credits)">
<input type="hidden" name="payment" value="10">
<input type="hidden" name="key" value="<? echo md5(date("Y-m-d:").rand()); ?>">
<input TYPE="image" SRC="http://www.coachsbr.com/images/site/paypal_button.gif" name="paypal" value="Payment via Paypal" >
</form>
And, the following code to process the payment and verify it
paypal.php
<?php
require_once('paypal.class.php'); // include the class file
$p = new paypal_class; // initiate an instance of the class
$p->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; // testing paypal url
//$p->paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; // paypal url
// setup a variable for this script (ie: 'http://www.micahcarrick.com/paypal.php')
$this_script = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
// if there is not action variable, set the default action of 'process'
if (empty($_GET['action'])) $_GET['action'] = 'process';
switch ($_GET['action']) {
case 'process': // Process and order...
$CatDescription = $_REQUEST['CatDescription'];
$payment = $_REQUEST['payment'];
$id = $_REQUEST['id'];
$key = $_REQUEST['key'];
$p->add_field('business', 'info#aoptrading.com');
$p->add_field('return', $this_script.'?action=success');
$p->add_field('cancel_return', $this_script.'?action=cancel');
$p->add_field('notify_url', $this_script.'?action=ipn');
$p->add_field('item_name', $CatDescription);
$p->add_field('amount', $payment);
$p->add_field('key', $key);
$p->add_field('item_number', $id);
$p->submit_paypal_post(); // submit the fields to paypal
//$p->dump_fields(); // for debugging, output a table of all the fields
break;
case 'success': // Order was successful...
echo "<br/><p><b>Payment Successful.</b><br /></p>";
foreach ($_POST as $key => $value) { echo "$key: $value<br>"; }
break;
case 'cancel': // Order was canceled...
echo "<br/><p><b>The order was canceled!</b></p><br />";
foreach ($_POST as $key => $value) { echo "$key: $value<br>"; }
break;
case 'ipn': // Paypal is calling page for IPN validation...
if ($p->validate_ipn()) {
// For this example, we'll just email ourselves ALL the data.
$dated = date("D, d M Y H:i:s", time());
$subject = 'Instant Payment Notification - Recieved Payment';
$to = 'info#aoptrading.com'; // your email
$body = "An instant payment notification was successfully recieved\n";
$body .= "from ".$p->ipn_data['payer_email']." on ".date('m/d/Y');
$body .= " at ".date('g:i A')."\n\nDetails:\n";
$headers = "";
$headers .= "From: Test Paypal \r\n";
$headers .= "Date: $dated \r\n";
$PaymentStatus = $p->ipn_data['payment_status'];
$Email = $p->ipn_data['payer_email'];
$id = $p->ipn_data['item_number'];
if($PaymentStatus == 'Completed' or $PaymentStatus == 'Pending'){
$PaymentStatus = '2';
}else{
$PaymentStatus = '1';
}
foreach ($p->ipn_data as $key => $value) { $body .= "\n$key: $value"; }
fopen("http://www.virtualphoneline.com/admins/TestHMS.php?to=".urlencode($to)."&subject=".urlencode($subject)."&message=".urlencode($body)."&headers=".urlencode($headers)."","r");
}
break;
}
?>
An extra class file: (can be found here) http://pastebin.com/auCdYhaR
The code is working fine, but I am having big issue now, I am trying to validate whether the payment is successful or not from the following lines and doing the action (adding 10 credits to the database for the user on session).
case 'success': // Order was successful...
echo "<br/><p><b>Payment Successful.</b><br /></p>";
foreach ($_POST as $key => $value)
{
/*echo "$key: $value<br>";*/
// Do the required action, **add 10 credits in the database for the user on session**
}
break;
Finally, the issue is when I click on the button from button.html page it redirects to the Paypal.php page and when I enter my PayPal login details, payment is successful
THERE COMES A SMALL LITTLE TEXT -> RETURN TO THE SENDER'S WEBSITE I NEED TO CLICK ON IT, WHEN I CLICK ON IT, IT WILL BRING ME BACK TO PAYPAL.PHP PAGE AND THEN THE CASE 'SUCCESS' IS FIRED. IF I MAKE THE PAYMENT AND JUST CLOSE THE PAYPAL PAGE WITHOUT CLICKING ON RETURN TO THE SENDER'S WEBSITE AND DIDN'T WAIT TILL THE PAGE PAYPAL.PHP LOADS WEBSITE COULDN'T VERIFY THE PAYMENT AND COULDN'T ADD THE CREDITS.
HOW CAN I AUTOMATE THIS PROCESS AND ADD CREDITS UPON SUCCESSFUL PAYMENT NOT UPON SUCCESSFUL RETURN TO THE PAGE PAYPAL.PHP.
THANKS
It sounds to me like you're confusing PDT and IPN. PDT works by sending data to your return URL, but that is not the recommended way to handle post-payment processing tasks.
That's where IPN comes into play, which is a silent POST of data to your listener URL regardless of whether or not the user makes it back to your return URL. That way that code will always run no matter what (assuming you've got everything configured correctly.)
Sounds to me like you're sort of mixing the two and getting mixed results because of it.
Related
I'm trying to add a PHP form to a website I'm working on. Not real familiar with PHP, but I've put the file in the upload folder in the CMS.
I think I've linked the jQuery and other files correctly and I've edited the PHP file putting in emails etc. This one also calls on another PHP validation file.
Anyway it shows up normally and I can fill it out but it goes to a 404 page and doesn't work.
My question is, what linking convention do I use to link to the php file and is it in the right place? I use cPanel where the CMS is installed.
Instead of putting: action="url([[root_url]]/uploads/scripts/form-to-email.php"
should I just put: action="uploads/scripts/form-to-email.php"?
The page in question is here: www.edelweiss-web-design.com.au/captainkilowatt/
Also, anyone know a good captcha I can integrate with it...? Thanks!
<div class="contact-form">
<h1>Contact Us</h1>
<form id="contact-form" method="POST" action="uploads/scripts/form-to-email.php">
<div class="control-group">
<label>Your Name</label>
<input class="fullname" type="text" name="fullname" />
</div>
<div class="control-group">
<label>Email</label>
<input class="email" type="text" name="email" />
</div>
<div class="control-group">
<label>Phone (optional)</label>
<input class="phone" type="text" name="phone" />
</div>
<div class="control-group">
<label>Message</label>
<textarea class="message" name="message"></textarea>
</div>
<div id="errors"></div>
<div class="control-group no-margin">
<input type="submit" name="submit" value="Submit" id="submit" />
</div>
</form>
<div id='msg_submitting'><h2>Submitting ...</h2></div>
<div id='msg_submitted'><h2>Thank you !<br> The form was submitted Successfully.</h2></div>
</div>
Here is the php:
<?php
/*
Configuration
You are to edit these configuration values. Not all of them need to be edited.
However, the first few obviously need to be edited.
EMAIL_RECIPIENTS - your email address where you want to get the form submission.
*/
$email_recipients = "contact#edelweiss-web-design.com.au";//<<=== enter your email address here
//$email_recipients = "mymanager#gmail.com,his.manager#yahoo.com"; <<=== more than one recipients like this
$visitors_email_field = 'email';//The name of the field where your user enters their email address
//This is handy when you want to reply to your users via email
//The script will set the reply-to header of the email to this email
//Leave blank if there is no email field in your form
$email_subject = "New Form submission";
$enable_auto_response = true;//Make this false if you donot want auto-response.
//Update the following auto-response to the user
$auto_response_subj = "Thanks for contacting us";
$auto_response ="
Hi
Thanks for contacting us. We will get back to you soon!
Regards
Captain Kilowatt
";
/*optional settings. better leave it as is for the first time*/
$email_from = ''; /*From address for the emails*/
$thank_you_url = 'http://www.edelweiss-web-design.com.au/captainkilowatt.html';/*URL to redirect to, after successful form submission*/
/*
This is the PHP back-end script that processes the form submission.
It first validates the input and then emails the form submission.
The variable $_POST contains the form submission data.
*/
if(!isset($_POST['submit']))
{
// note that our submit button's name is 'submit'
// We are checking whether submit button is pressed
// This page should not be accessed directly. Need to submit the form.
echo "error; you need to submit the form!".print_r($_POST,true);
exit;
}
require_once "http://edelweiss-web-design.com.au/captainkilowatt/upload/scripts/formvalidator.php";
//Setup Validations
$validator = new FormValidator();
$validator->addValidation("fullname","req","Please fill in Name");
$validator->addValidation("email","req","Please fill in Email");
//Now, validate the form
if(false == $validator->ValidateForm())
{
echo "<B>Validation Errors:</B>";
$error_hash = $validator->GetErrors();
foreach($error_hash as $inpname => $inp_err)
{
echo "<p>$inpname : $inp_err</p>\n";
}
exit;
}
$visitor_email='';
if(!empty($visitors_email_field))
{
$visitor_email = $_POST[$visitors_email_field];
}
if(empty($email_from))
{
$host = $_SERVER['SERVER_NAME'];
$email_from ="forms#$host";
}
$fieldtable = '';
foreach ($_POST as $field => $value)
{
if($field == 'submit')
{
continue;
}
if(is_array($value))
{
$value = implode(", ", $value);
}
$fieldtable .= "$field: $value\n";
}
$extra_info = "User's IP Address: ".$_SERVER['REMOTE_ADDR']."\n";
$email_body = "You have received a new form submission. Details below:\n$fieldtable\n $extra_info";
$headers = "From: $email_from \r\n";
$headers .= "Reply-To: $visitor_email \r\n";
//Send the email!
#mail(/*to*/$email_recipients, $email_subject, $email_body,$headers);
//Now send an auto-response to the user who submitted the form
if($enable_auto_response == true && !empty($visitor_email))
{
$headers = "From: $email_from \r\n";
#mail(/*to*/$visitor_email, $auto_response_subj, $auto_response,$headers);
}
//done.
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
{
//This is an ajax form. So we return success as a signal of succesful processing
echo "success";
}
else
{
//This is not an ajax form. we redirect the user to a Thank you page
header('Location: '.$thank_you_url);
}
?><?php
/*
Configuration
You are to edit these configuration values. Not all of them need to be edited.
However, the first few obviously need to be edited.
EMAIL_RECIPIENTS - your email address where you want to get the form submission.
*/
$email_recipients = "contact#edelweiss-web-design.com.au";//<<=== enter your email address here
//$email_recipients = "mymanager#gmail.com,his.manager#yahoo.com"; <<=== more than one recipients like this
$visitors_email_field = 'email';//The name of the field where your user enters their email address
//This is handy when you want to reply to your users via email
//The script will set the reply-to header of the email to this email
//Leave blank if there is no email field in your form
$email_subject = "New Form submission";
$enable_auto_response = true;//Make this false if you donot want auto-response.
//Update the following auto-response to the user
$auto_response_subj = "Thanks for contacting us";
$auto_response ="
Hi
Thanks for contacting us. We will get back to you soon!
Regards
Captain Kilowatt
";
/*optional settings. better leave it as is for the first time*/
$email_from = ''; /*From address for the emails*/
$thank_you_url = 'http://www.edelweiss-web-design.com.au/captainkilowatt.html';/*URL to redirect to, after successful form submission*/
/*
This is the PHP back-end script that processes the form submission.
It first validates the input and then emails the form submission.
The variable $_POST contains the form submission data.
*/
if(!isset($_POST['submit']))
{
// note that our submit button's name is 'submit'
// We are checking whether submit button is pressed
// This page should not be accessed directly. Need to submit the form.
echo "error; you need to submit the form!".print_r($_POST,true);
exit;
}
require_once "http://www.edelweiss-web-design.com.au/captainkilowatt/upload/scripts/formvalidator.php";
//Setup Validations
$validator = new FormValidator();
$validator->addValidation("fullname","req","Please fill in Name");
$validator->addValidation("email","req","Please fill in Email");
//Now, validate the form
if(false == $validator->ValidateForm())
{
echo "<B>Validation Errors:</B>";
$error_hash = $validator->GetErrors();
foreach($error_hash as $inpname => $inp_err)
{
echo "<p>$inpname : $inp_err</p>\n";
}
exit;
}
$visitor_email='';
if(!empty($visitors_email_field))
{
$visitor_email = $_POST[$visitors_email_field];
}
if(empty($email_from))
{
$host = $_SERVER['SERVER_NAME'];
$email_from ="forms#$host";
}
$fieldtable = '';
foreach ($_POST as $field => $value)
{
if($field == 'submit')
{
continue;
}
if(is_array($value))
{
$value = implode(", ", $value);
}
$fieldtable .= "$field: $value\n";
}
$extra_info = "User's IP Address: ".$_SERVER['REMOTE_ADDR']."\n";
$email_body = "You have received a new form submission. Details below:\n$fieldtable\n $extra_info";
$headers = "From: $email_from \r\n";
$headers .= "Reply-To: $visitor_email \r\n";
//Send the email!
#mail(/*to*/$email_recipients, $email_subject, $email_body,$headers);
//Now send an auto-response to the user who submitted the form
if($enable_auto_response == true && !empty($visitor_email))
{
$headers = "From: $email_from \r\n";
#mail(/*to*/$visitor_email, $auto_response_subj, $auto_response,$headers);
}
//done.
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
{
//This is an ajax form. So we return success as a signal of succesful processing
echo "success";
}
else
{
//This is not an ajax form. we redirect the user to a Thank you page
header('Location: '.$thank_you_url);
}
?>
I've added the php file.
So, in the action part, when I submit the form, it no longer gives me a 404 but takes me to a blank page with the 'form-to-email.php' page. However, the script is not working from what I can tell. Again, I know html and css, and little javascipt, but how php is meant to work...?
What am I doing wrong?
I would suggest using one of the modules for CMS instead of trying to build form in PHP from scratch. It is much more safer to use CMS buildin functions and that is the point of using the CMS in the first place. For CMS made simple the formbuilder module is here:
http://dev.cmsmadesimple.org/projects/formbuilder
Thanks for all the comments.
I found another form with a captcha (PHP) and preserved the whole structure by uploading it as is into CMSMS uploads folder.
I then used iframe to embed the form on my page, changed a couple of little details with the CSS and wording, and bob's your uncle, it works just fine.
For anyone interested, I used: www.html-form-guide.com/contact-form/creating-a-contact-form.html
This is free and I am certainly not trying to spam as I am in no way affiliated with this site or any sites associated with it.
I have found lots of questions for this topic, but none seems to answer my question...
NB. Using Larry Ullman's Blog at http://www.larryullman.com/2012/11/28/creating-a-form-for-handling-payments-with-stripe/
Trying to use
$amount = $_REQUEST['amount'];
instead of
$amount = 23400; //EXAMPLE ONLY
But the value of $_REQUEST['amount']; is being ignored?
<?php
// Check for a form submission:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Stores errors:
$errors = array();
// Need a payment token:
if (isset($_POST['stripeToken'])) {
$token = $_POST['stripeToken'];
$StripeAmount = $_REQUEST['amount']; // $20, in cents
// Check for a duplicate submission, just in case:
// Uses sessions, you could use a cookie instead.
if (isset($_SESSION['token']) && ($_SESSION['token'] == $token)) {
$errors['token'] = 'You have apparently resubmitted the form. Please do not do that.';
} else { // New submission.
$_SESSION['token'] = $token;
}
} else {
$errors['token'] = 'The order cannot be processed. Please make sure you have JavaScript enabled and try again.';
}
// Set the order amount somehow:
// $20, in cents
$amount = $_REQUEST['amount']; // in cents
// Validate other form data!
// If no errors, process the order:
if (empty($errors)) {
// create the charge on Stripe's servers - this will charge the user's card
try {
// Include the Stripe library:
// Assumes you've installed the Stripe PHP library using Composer!
require_once('stripe/init.php');
// set your secret key: remember to change this to your live secret key in production
// see your keys here https://manage.stripe.com/account
\Stripe\Stripe::setApiKey(STRIPE_PRIVATE_KEY);
// Charge the order:
$charge = \Stripe\Charge::create(array(
"amount" => $amount, // amount in cents, again
"currency" => "aud",
"source" => $token,
"description" => $email
)
);
// Check that it was paid:
if ($charge->paid == true) {
$OrderID = $_GET['order_id']; //reference from shop OrderId
$txn_id = $_GET['id']; //transaction number form payment Gateway
$objBooking->updateVisitorOrderRecord($OrderID, $txn_id);
header('location:visitor_payment_thanks.php');
} else { // Charge was not paid!
header('location:visitor_payment_error.php');
}
} catch (\Stripe\Error\Card $e) {
// Card was declined.
$e_json = $e->getJsonBody();
$err = $e_json['error'];
$errors['stripe'] = $err['message'];
} catch (\Stripe\Error\ApiConnection $e) {
// Network problem, perhaps try again.
} catch (\Stripe\Error\InvalidRequest $e) {
// You screwed up in your programming. Shouldn't happen!
} catch (\Stripe\Error\Api $e) {
// Stripe's servers are down!
} catch (\Stripe\Error\Base $e) {
// Something else that's not the customer's fault.
}
} // A user form submission error occurred, handled below.
} // Form submission.
// Set the Stripe key:
// Uses STRIPE_PUBLIC_KEY from the config file.
echo '<script type="text/javascript">Stripe.setPublishableKey("' . STRIPE_PUBLIC_KEY . '");</script>';
?>
<h1>Buy This Thing</h1>
<form action="buy.php" method="POST" id="payment-form">
<?php // Show PHP errors, if they exist:
if (isset($errors) && !empty($errors) && is_array($errors)) {
echo '<div class="alert alert-error"><h4>Error!</h4>The following error(s) occurred:<ul>';
foreach ($errors as $e) {
echo "<li>$e</li>";
}
echo '</ul></div>';
}?>
<div id="payment-errors"></div>
<span class="help-block">You can pay using: Mastercard, Visa, American Express, JCB, Discover, and Diners Club.</span>
<div class="alert alert-info"><h4>JavaScript Required!</h4>For security purposes, JavaScript is required in order to complete an order.</div>
<label>Card Number</label>
<input type="text" size="20" autocomplete="off" class="card-number input-medium">
<span class="help-block">Enter the number without spaces or hyphens.</span>
<label>CVC</label>
<input type="text" size="4" autocomplete="off" class="card-cvc input-mini">
<label>Expiration (MM/YYYY)</label>
<input type="text" size="2" class="card-expiry-month input-mini">
<span> / </span>
<input type="text" size="4" class="card-expiry-year input-mini">
<button type="submit" class="btn" id="submitBtn">Submit Payment</button>
</form>
<script src="buy.js"></script>
Thx Guys
I emailed STRIPE and based on feedback, the issue was that I should have been using SESSIONS....
PHP Manual Page on Session Handling
I create a new payment gateway in cscart. After get success result from payment gateway cs cart redirect it to checkout page and show incomplete checkout.Please help me to solve this issue.
Because you did not provide any code, I made an example code for processing the response:
if ($mode == 'return') {
// this means, that the payment processor returned from 3rd party checkout page
$order_info = fn_get_order_info($_REQUEST['order_id'], true);
// you should have a response code (this section depends on your payment gateway)
if ($_REQUEST['response_code'] == "S") {
// the transaction was successful!
$pp_response['order_status'] = 'P';
$pp_response['transaction_id'] = $_REQUEST['transaction_id'];
$pp_response["reason_text"] = $_REQUEST['response_code'] . ": " . $_REQUEST['transaction_id']);
fn_finish_payment($_REQUEST['order_id'], $pp_response, false);
fn_order_placement_routines('route', $_REQUEST['order_id']);
} else {
// the transaction was NOT successful!
$pp_response['order_status'] = 'N';
$pp_response['transaction_id'] = $_REQUEST['transaction_id'];
$pp_response["reason_text"] = $_REQUEST['response_code'] . ": " . $_REQUEST['transaction_id']);
fn_order_placement_routines('route', $_REQUEST['order_id'], false);
}
}
The key "functions" are: fn_finish_payment() and fn_order_placement_routines(). If you did not finish the payment, you will be redirected to the checkout page, because this means, something went wrong.
I have implemented a paypal ipn process. I want to retrieve some data from the ipn and save it in a database table. The problem is it doesn´t work. I used the part of the procedure from a tutorial http://tutorialzine.com/2010/05/donation-center-php-mysql-paypal-api/
Nelow is the code I have used.
ipn.php
<?php
require "paypal_integration_class/paypal.class.php";
require "config.php";
require "connect.php";
$p = new paypal_class;
$p->paypal_url = $payPalURL;
if ($p->validate_ipn()) {
if($p->ipn_data['payment_status']=='Completed')
{
$amount = $p->ipn_data['mc_gross'] - $p->ipn_data['mc_fee'];
mysql_query(" INSERT INTO dc_donations (transaction_id,donor_email,amount,original_request)
VALUES (
'".esc($p->ipn_data['txn_id'])."',
'".esc($p->ipn_data['payer_email'])."',
".(float)$amount.",
'".esc(http_build_query($_POST))."'
)");
}
}
function esc($str)
{
global $link;
return mysql_real_escape_string($str,$link);
}
?>
connect.php
/* Database config */
$db_host = "localhost";
$db_user = "egesachi_ipn";
$db_pass = "lollipop";
$db_database = "egesachi_ipn";
/* End config */
$link = #mysql_connect($db_host,$db_user,$db_pass) or die('Unable to establish a DB connection');
mysql_set_charset('utf8');
mysql_select_db($db_database,$link);
?>
config.php
<?php
// Fill your PayPal email below.
// This is where you will receive the donations.
$myPayPalEmail = 'ben#center.org';
// The paypal URL:
$payPalURL = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
// Your goal in USD:
$goal = 100;
// Demo mode is set - set it to false to enable donations.
// When enabled PayPal is bypassed.
$demoMode = false;
if($demoMode)
{
$payPalURL = 'demo_mode.php';
}
?>
paypal_integration_class/paypal.class.php
Below is the URL where the script above is from.
http://www.phpclasses.org/package/2249-PHP-Process-Paypal-payment-interactions.html
class paypal_class {
var $last_error; // holds the last error encountered
var $ipn_log; // bool: log IPN results to text file?
var $ipn_log_file; // filename of the IPN log
var $ipn_response; // holds the IPN response from paypal
var $ipn_data = array(); // array contains the POST values for IPN
var $fields = array(); // array holds the fields to submit to paypal
function paypal_class() {
// initialization constructor. Called when class is created.
$this->paypal_url = 'https://www.paypal.com/cgi-bin/webscr';
$this->last_error = '';
$this->ipn_log_file = 'ipn_log.txt';
$this->ipn_log = true;
$this->ipn_response = '';
// populate $fields array with a few default values. See the paypal
// documentation for a list of fields and their data types. These defaul
// values can be overwritten by the calling script.
$this->add_field('rm','2'); // Return method = POST
$this->add_field('cmd','_xclick');
}
function add_field($field, $value) {
// adds a key=>value pair to the fields array, which is what will be
// sent to paypal as POST variables. If the value is already in the
// array, it will be overwritten.
$this->fields["$field"] = $value;
}
function submit_paypal_post() {
// this function actually generates an entire HTML page consisting of
// a form with hidden elements which is submitted to paypal via the
// BODY element's onLoad attribute. We do this so that you can validate
// any POST vars from you custom form before submitting to paypal. So
// basically, you'll have your own form which is submitted to your script
// to validate the data, which in turn calls this function to create
// another hidden form and submit to paypal.
// The user will briefly see a message on the screen that reads:
// "Please wait, your order is being processed..." and then immediately
// is redirected to paypal.
echo "<html>\n";
echo "<head><title>Processing Payment...</title></head>\n";
echo "<body onLoad=\"document.form.submit();\">\n";
echo "<center><h3>Please wait, your order is being processed...</h3></center>\n";
echo "<form method=\"post\" name=\"form\" action=\"".$this->paypal_url."\">\n";
foreach ($this->fields as $name => $value) {
echo "<input type=\"hidden\" name=\"$name\" value=\"$value\">";
}
echo "</form>\n";
echo "</body></html>\n";
}
function validate_ipn() {
// parse the paypal URL
$url_parsed=parse_url($this->paypal_url);
// generate the post string from the _POST vars aswell as load the
// _POST vars into an arry so we can play with them from the calling
// script.
$post_string = '';
foreach ($_POST as $field=>$value) {
$this->ipn_data["$field"] = $value;
$post_string .= $field.'='.urlencode($value).'&';
}
$post_string.="cmd=_notify-validate"; // append ipn command
// open the connection to paypal
$fp = fsockopen($url_parsed[host],"80",$err_num,$err_str,30);
if(!$fp) {
// could not open the connection. If loggin is on, the error message
// will be in the log.
$this->last_error = "fsockopen error no. $errnum: $errstr";
$this->log_ipn_results(false);
return false;
} else {
// Post the data back to paypal
fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n");
fputs($fp, "Host: $url_parsed[host]\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($post_string)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n");
// loop through the response from the server and append to variable
while(!feof($fp)) {
$this->ipn_response .= fgets($fp, 1024);
}
fclose($fp); // close connection
}
if (eregi("VERIFIED",$this->ipn_response)) {
// Valid IPN transaction.
$this->log_ipn_results(true);
return true;
} else {
// Invalid IPN transaction. Check the log for details.
$this->last_error = 'IPN Validation Failed.';
$this->log_ipn_results(false);
return false;
}
}
function log_ipn_results($success) {
if (!$this->ipn_log) return; // is logging turned off?
// Timestamp
$text = '['.date('m/d/Y g:i A').'] - ';
// Success or failure being logged?
if ($success) $text .= "SUCCESS!\n";
else $text .= 'FAIL: '.$this->last_error."\n";
// Log the POST variables
$text .= "IPN POST Vars from Paypal:\n";
foreach ($this->ipn_data as $key=>$value) {
$text .= "$key=$value, ";
}
// Log the response from the paypal server
$text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;
// Write to log
$fp=fopen($this->ipn_log_file,'a');
fwrite($fp, $text . "\n\n");
fclose($fp); // close file
}
function dump_fields() {
// Used for debugging, this function will output all the field/value pairs
// that are currently defined in the instance of the class using the
// add_field() function.
echo "<h3>paypal_class->dump_fields() Output:</h3>";
echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">
<tr>
<td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td>
<td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td>
</tr>";
ksort($this->fields);
foreach ($this->fields as $key => $value) {
echo "<tr><td>$key</td><td>".urldecode($value)." </td></tr>";
}
echo "</table><br>";
}
}
paypal html checkout form
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<!-- Identify your business so that you can collect the payments. -->
<input type="hidden" name="business"
value="ben#egesachildrencenter.org">
<!-- Specify a Donate button. -->
<input type="hidden" name="cmd" value="_donations">
<!-- Specify details about the contribution -->
<input type="hidden" name="item_name" value="<?php echo $sponsored; ?>">
<input type="hidden" name="item_number" value="<?php echo $pupilid; ?>">
<input type="hidden" name="amount" value="25.00">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="return" value="http://www.center.org/pap/needy.php">
<input type="hidden" name="notify_url" value="http://www.center.org/pap/ipn.php">
<!-- Display the payment button. -->
<input type="image" name="submit" border="0"
src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif"
alt="PayPal - The safer, easier way to pay online">
<img alt="" border="0" width="1" height="1"
src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" >
</form>
Please help me to find where I am going wrong or suggest another way of achieving th same result. Thanks.
I am looking to be able to take the info from the PayPal IPN post, and use certain items to update my database. This is the current code I have for my ipn.php
<?php
// tell PHP to log errors to ipn_errors.log in this directory
ini_set('log_errors', true);
ini_set('error_log', dirname(__FILE__).'/ipn_errors.log');
// intantiate the IPN listener
include('ipnlistener.php');
$listener = new IpnListener();
// tell the IPN listener to use the PayPal test sandbox
$listener->use_sandbox = true;
// try to process the IPN POST
try {
$listener->requirePostMethod();
$verified = $listener->processIpn();
} catch (Exception $e) {
error_log($e->getMessage());
exit(0);
}
if ($verified) {
$errmsg = ''; // stores errors from fraud checks
// 1. Make sure the payment status is "Completed"
if ($_POST['payment_status'] != 'Completed') {
// simply ignore any IPN that is not completed
exit(0);
}
// 2. Make sure seller email matches your primary account email.
if ($_POST['receiver_email'] != 'PRIMARY EMAIL ADDRESS') {
$errmsg .= "'receiver_email' does not match: ";
$errmsg .= $_POST['receiver_email']."\n";
}
// 3. Make sure the currency code matches
if ($_POST['mc_currency'] != 'USD') {
$errmsg .= "'mc_currency' does not match: ";
$errmsg .= $_POST['mc_currency']."\n";
}
// 4. Ensure the transaction is not a duplicate.
mysql_connect('localhost', '[DB_USER]', '[DB_PW') or exit(0);
mysql_select_db('DB_NAME') or exit(0);
$txn_id = mysql_real_escape_string($_POST['txn_id']);
$sql = "SELECT COUNT(*) FROM orders WHERE txn_id = '$txn_id'";
$r = mysql_query($sql);
if (!$r) {
error_log(mysql_error());
exit(0);
}
$exists = mysql_result($r, 0);
mysql_free_result($r);
if ($exists) {
$errmsg .= "'txn_id' has already been processed: ".$_POST['txn_id']."\n";
}
if (!empty($errmsg)) {
// manually investigate errors from the fraud checking
$body = "IPN failed fraud checks: \n$errmsg\n\n";
$body .= $listener->getTextReport();
mail('NOTIFICATION EMAIL ADDRESS', 'IPN Fraud Warning', $body);
} else {
<?php
$csvData = file_get_contents($_POST['custom']);
$csvNumColumns = 3;
$csvDelim = ";";
$data = array_chunk(str_getcsv($csvData, $csvDelim), $csvNumColumns);
?>
// add this order to a table
$user_id = mysql_real_escape_string($_POST['item_name']);
$credit_amount = mysql_real_escape_string($_POST['item_number']);
$type = mysql_real_escape_string($_POST['custom']);
$sql = "INSERT INTO TABLE_NAME VALUES
(NULL, '$user_id', '$credit_amount', '$type')";
if (!mysql_query($sql)) {
error_log(mysql_error());
exit(0);
}
}
} else {
// manually investigate the invalid IPN
mail('NOTIFICATION EMAIL ADDRESS', 'Invalid IPN', $listener->getTextReport());
}
?>
This seemed to work fine when testing it with PayPal Sandbox's IPN testing service and I could enter in the needed values for item_name, item_number, and custom (or when using the below code)
<form name="_xclick" action="https://www.sandbox.paypal.com/cgi-bin/webscr"
method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="SANDBOX EMAIL ADDRESS">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="amount" value="9.99">
<input type="hidden" name="custom" value="<?=$this->package['0']['delivered'];?>"
<input type="hidden" name="item_name" value="<?=$_SESSION["user_id"]?>"
<input type="hidden" name="item_number" value="<?=$this->package['0']['number'];?>"
<input type="hidden" name="return" value="WEBSITE_URL/success">
<input type="hidden" name="notify_url" value="WEBSITE_URL/ipn.php">
<input type="image" src="http://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"
border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
However I soon realized that it would be much better for the 'item_name' to be something recognizable by the customer, rather than having it be defined as the 'user_id'. Is it possible to have the 'custom' pass through defined as all 3 of the variables that I need, separating them within the PayPal button with semicolons (as seem below)
<input type="hidden" name="custom" value="<?=$_SESSION["user_id"]?>;<?=$this->package['0']['number'];?>;<?=$this->package['0']['delivered'];?>"
then using something like
<?php
$csvData = file_get_contents($_POST['custom']);
$csvNumColumns = 3;
$csvDelim = ";";
$data = array_chunk(str_getcsv($csvData, $csvDelim), $csvNumColumns);
?>
to give me separate variables that can then be defined as 'user_id', 'credit_amount', and 'type'
once these variables are separated and defined, they are to be posted to the database, however, if there is already a column within the table that has the same 'user_id' as is trying to be posted AS WELL AS the same 'type' that is trying to be posted, then it should only update that row (the row already within the table before the attempted addition) by ADDING the 'credit_amount' to the corresponding 'credit_amount' cell in the old row.
You can pass multiple values, and have them populated into a single variable such as the variable "custom". There would not be an issue with this. I have done this myself as well in the past. When I coded this, I used the | to separate the values, and then had my IPN parse out the values within my IPN script.