function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Medieval  Tech GuyMedieval Tech Guy 

Using PHP to execute upsert()

I'm attempting to create a php file which serves both as an IPN listner to recieve payment information from paypal, and to perform and upsert() to salesforce with the collected information. I believe that I have the gyst of the IPN listner down, as well as creating the connection to salesforce. However, I am having some trouble setting up the upsert() portion of the code. I have been looking online, and found some tutorials on this, but most of them are unclear, and usually related to databases, rather then updating from a single record (i.e. http://wiki.developerforce.com/page/Salesforce_PHP_Upsert_Tutorial). Below is the code I have come up with so far. Right now I am lost as to how to create an object with the contact's information that salesforce will be able to read using the upsert() command. Will the below code execute correctly to create a new contact in salesforce?

 

<?php
// Revision Notes
// 11/04/11 - changed post back url from https://www.paypal.com/cgi-bin/webscr to https://ipnpb.paypal.com/cgi-bin/webscr
// For more info see below:
// https://www.x.com/content/bulletin-ip-address-expansion-paypal-services
// "ACTION REQUIRED: if you are using IPN (Instant Payment Notification) for Order Management and your IPN listener script is behind a firewall that uses ACL (Access Control List) rules which restrict outbound traffic to a limited number of IP addresses, then you may need to do one of the following:
// To continue posting back to https://www.paypal.com to perform IPN validation you will need to update your firewall ACL to allow outbound access to *any* IP address for the servers that host your IPN script
// OR Alternatively, you will need to modify your IPN script to post back IPNs to the newly created URL https://ipnpb.paypal.com using HTTPS (port 443) and update firewall ACL rules to allow outbound access to the ipnpb.paypal.com IP ranges (see end of message)."


// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';

foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}

// post back to PayPal system to validate

$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";

// If testing on Sandbox use:
// $header .= "Host: www.sandbox.paypal.com:443\r\n";
$header .= "Host: ipnpb.paypal.com:443\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

// If testing on Sandbox use:
//$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
$fp = fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);

// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$address_city = $_POST['address_city'];
$address_country = $_POST['address_country'];
$address_state = $_POST['address_state'];
$address_status = $_POST['address_status'];
$address_street = $_POST['address_street'];
$address_zip = $_POST['address_zip'];
$payment_date = $_POST['payment_date'];
$payment_fee = $_POST['payment_fee'];
$payment_gross = $_POST['payment_gross'];
$payment_status = $_POST['payment_status'];


if (!$fp) {
// HTTP ERROR
}
else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if ($payment_status = "Completed") {
$wsdl = 'enterprise-wsdl.xml';
$user = 'example@epixa.com';
$pass = 'supersecure';
$token = '*****';

$client = new SforceEnterpriseClient();
$client->createConnection($wsdl);
$client->login($user, $pass . $token);

 

$sObject = new sObject();
$sObject->type = 'Contact';
$sObject->Account_Name = $first_name + $last_name;
$sObject->Address_City = $address_city;
$sObject->Address_Country = $address_country;
$sObject->Address_State = $address_state;
$sObject->Address_Street = $address_street;
$sObject->Address_Zip = $address_zip;

client.upsert('Account Name', $sObject);



}
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment

}

}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation

$mail_From = "From: me@mybiz.com";
$mail_To = "*****";
$mail_Subject = "INVALID IPN";
$mail_Body = $req;

foreach ($_POST as $key => $value){
$emailtext .= $key . " = " .$value ."\n\n";
}

mail($mail_To, $mail_Subject, $emailtext . "\n\n" . $mail_Body, $mail_From);

}
}
fclose ($fp);
}
?>

Park Walker (TAGL)Park Walker (TAGL)

There are a few of things you should be aware of with respect to the Salesforce API. The first is that you need to use the proper field names for the object that you are going to be creating. You can find them in the standard objects section of the API documentation. This includes the foreign key field passed in the upsert call. 

 

The second is understanding how data is stored and used in Salesforce. A Contact record created without a link to an Account is considered private and not visible by anyone other than the creator or someone with Read All Data permissions. If you are dealing strictly with individuals you may want to look at 'Person Accounts' in the online help to see if that's a more appropriate fit. Otherwise, you will need to create an account first and then set the contact's AccountId to the id value returned by the insert/upsert call. You may want to check with the Salesforce administrator to see what they are looking for.

 

The third item is that there are a lot of Robert Smith's in the world. Using a person's name as a foreigh key is certain to make a mess of your database. Email address would certainly be a better choice.

 

Park

Medieval  Tech GuyMedieval Tech Guy

Thanks for the help. I'm modifying the code to create an account first where IsPerson = 'true'. How does the upsert() command identify which type of record to update/create (i.e. account/contact etc.)?

Park Walker (TAGL)Park Walker (TAGL)

It looks at the type field on the sObject that you send. You'll probably want to take a look at the API documentation before going too much further. The code examples will only get you so far.

 

Park

Medieval  Tech GuyMedieval Tech Guy

After some work, paypal confirms a successfull IPN sending, but the information never arives in Salesforce. Is there any way to check and see if the IPN listner has attempted to login in salesforce?

 

Updated Code:

 

<?php
// Revision Notes
// 11/04/11 - changed post back url from https://www.paypal.com/cgi-bin/webscr to https://ipnpb.paypal.com/cgi-bin/webscr
// For more info see below:
// https://www.x.com/content/bulletin-ip-address-expansion-paypal-services
// "ACTION REQUIRED: if you are using IPN (Instant Payment Notification) for Order Management and your IPN listener script is behind a firewall that uses ACL (Access Control List) rules which restrict outbound traffic to a limited number of IP addresses, then you may need to do one of the following:
// To continue posting back to https://www.paypal.com to perform IPN validation you will need to update your firewall ACL to allow outbound access to *any* IP address for the servers that host your IPN script
// OR Alternatively, you will need to modify your IPN script to post back IPNs to the newly created URL https://ipnpb.paypal.com using HTTPS (port 443) and update firewall ACL rules to allow outbound access to the ipnpb.paypal.com IP ranges (see end of message)."


// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';

foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}

// post back to PayPal system to validate

$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";

// If testing on Sandbox use:
$header .= "Host: www.sandbox.paypal.com:443\r\n";
//$header .= "Host: ipnpb.paypal.com:443\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

// If testing on Sandbox use:
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
//$fp = fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);

// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$address_city = $_POST['address_city'];
$address_country = $_POST['address_country'];
$address_state = $_POST['address_state'];
$address_status = $_POST['address_status'];
$address_street = $_POST['address_street'];
$address_zip = $_POST['address_zip'];
$payment_date = $_POST['payment_date'];
$payment_fee = $_POST['payment_fee'];
$payment_gross = $_POST['payment_gross'];
$payment_status = $_POST['payment_status'];


if (!$fp) {

$mail_From = "From: me@mybiz.com";
$mail_To = "*******";
$mail_Subject = "HTTP ERROR";
$mail_Body = $req;
// HTTP ERROR
}
else {

// Reciept verification

$mail_From = "From: me@mybiz.com";
$mail_To = "********";
$mail_Subject = "Successfull login";
$mail_Body = $req;

foreach ($_POST as $key => $value){
$emailtext .= $key . " = " .$value ."\n\n";


fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if ($payment_status = "Completed") {
$wsdl = 'sf.xml';
$user = '*******';
$pass = '*****';
$token = '*******';

$client = new SforceEnterpriseClient();
$client->createConnection($wsdl);
$client->login($user, $pass . $token);

$sObject = new sObject();
$sObject->IsPersonAccount = 'true'
$sObject->Type = 'Account';
$sObject->FirstName = $first_name;
$sObject->LastName = $last_name;
$sObject->PersonEmail = $payer_email;


upsertResult = client.upsert('Email', $sObject);

$sObject1 = new sObject1();
$sObject1->AccountID = upsertResult;
$sObject1->Type = 'Contact';
$sObject1->FirstName = $first_name;
$sObject1->LastName = $last_name;
$sObject1->Email = $payer_email;
$sObject1->IsPersonAccount = 'true'
$sObject1->MailingCity = $address_city;
$sObject1->MailingCountry = $address_country;
$sObject1->MailingState = $address_state;
$sObject1->MailingStreet = $address_street;
$sObject1->MailingPostalCode = $address_zip;

client.upsert('Email', $sObject1);

$sObject2 = new sObject2();
$sObject2->DonationName = $txn_id;
$sObject2->OrganizationName = $sObject->FirstName $sObject->LastName;
$sObject2->Amount = $payment_amount;
$sObject2->CloseDate = $payment_date;
$sObject2->Stage = 'Posted';
$sObject2->DonationRecordType = 'Donation';

client.upsert('DonationName', $sObject2);



}
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment

}

}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation

$mail_From = "From: me@mybiz.com";
$mail_To = "********";
$mail_Subject = "INVALID IPN";
$mail_Body = $req;

foreach ($_POST as $key => $value){
$emailtext .= $key . " = " .$value ."\n\n";
}

mail($mail_To, $mail_Subject, $emailtext . "\n\n" . $mail_Body, $mail_From);

}
}
fclose ($fp);
}
?>