PayPal Refund Transaction Issue - php

I am working with PayPal refund payment gateway. My main objective is to refund amount to the user and in the same time I have to pay certain amount to another user. Here I am acting as a admin, suppose if I have 150$ that is credited to me via PayPal. I have the transaction Id of it.Now I need to return suppose 100 $ to user1 and I need to send 20$ to user2.
<?php
/**
*
*
* This PayPal API provides the functionality of Refunding Amount.
* Credentials are omitted from here for privacy purpose. To use it credentials are compulsory to provide.
*/
class PayPalRefund
{
private $API_Username, $API_Password, $Signature, $API_Endpoint, $version;
function __construct($mode = "sandbox")
{
if($mode == "live")
{
$this->API_Username = "sample#gmail.com";
$this->API_Password = "137301275897";
$this->Signature = "AoNBG1CB1212IgLS5QaKlVpODjsaTncPABthzh5N-Nzz511tOodumbgF0TvVDq";
$this->API_Endpoint = "https://api-3t.paypal.com/nvp";
}
else
{
$this->API_Username = "sample#gmail.com";
$this->API_Password = "137301275897";
$this->Signature = "AoNBG1CB1212IgLS5QaKlVpODjsaTncPABthzh5N-Nzz5t11OodumbgF0TvVDq";
$this->API_Endpoint = "https://api-3t.sandbox.paypal.com/nvp";
}
$this->version = "51.0";
}
/**
* This function actually Sends the CURL Request for Refund
* #param string - $requestString
* #return array - returns the response
*/
function sendRefundRequest($requestString)
{
$this->API_UserName = urlencode($this->API_Username);
$this->API_Password = urlencode($this->API_Password);
$this->API_Signature = urlencode($this->Signature);
$this->version = urlencode($this->version);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$reqStr = "METHOD=RefundTransaction&VERSION={$this->version}&PWD={$this->API_Password}&USER={$this->API_UserName}&SIGNATURE={$this->API_Signature}$requestString";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $reqStr);
// Get response from the server.
$curlResponse = curl_exec($ch);
if(!$curlResponse)
return array("ERROR_MESSAGE"=>"RefundTransaction failed".curl_error($ch)."(".curl_errno($ch).")");
// Extract the response details.
$httpResponseAr = explode("&", $curlResponse);
$aryResponse = array();
foreach ($httpResponseAr as $i => $value)
{
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1)
{
$aryResponse[$tmpAr[0]] = urldecode($tmpAr[1]);
}
}
if((0 == sizeof($aryResponse)) || !array_key_exists('ACK', $aryResponse))
return array("ERROR_MESSAGE"=>"Invalid HTTP Response for POST request ($reqStr) to {$this->API_Endpoint}");
return $aryResponse;
}
/**
* #param array $aryData
* #return array
*/
function refundAmount($aryData)
{
if(trim(#$aryData['currencyCode'])=="")
return array("ERROR_MESSAGE"=>"Currency Code is Missing");
if(trim(#$aryData['refundType'])=="")
return array("ERROR_MESSAGE"=>"Refund Type is Missing");
if(trim(#$aryData['transactionID'])=="")
return array("ERROR_MESSAGE"=>"Transaction ID is Missing");
$requestString = "&TRANSACTIONID={$aryData['transactionID']}&REFUNDTYPE={$aryData['refundType']}&CURRENCYCODE={$aryData['currencyCode']}";
if(trim(#$aryData['invoiceID'])!="")
$requestString = "&INVOICEID={$aryData['invoiceID']}";
if(isset($aryData['memo']))
$requestString .= "&NOTE={$aryData['memo']}";
if(strcasecmp($aryData['refundType'], 'Partial') == 0)
{
if(!isset($aryData['amount']))
{
return array("ERROR_MESSAGE"=>"For Partial Refund - It is essential to mention Amount");
}
else
{
$requestString = $requestString."&AMT={$aryData['amount']}";
}
if(!isset($aryData['memo']))
{
return array("ERROR_MESSAGE"=>"For Partial Refund - It is essential to enter text for Memo");
}
}
$resCurl = $this->sendRefundRequest($requestString);
return $resCurl;
}
}
?>
and
/**
*
*
* This PayPal API provides the functionality of Refunding Amount.
* Credentials are omitted from here for privacy purpose. To use it credentials are compulsory to provide.
*/
/*
* Currency Types
* ('USD', 'GBP', 'EUR', 'JPY', 'CAD', 'AUD')
*
* Refund Type
* ('Partial', 'Full')
*
* Transaction ID
* We can get the Transaction ID from IPN Response
*/
/*
* Partial Refund
*/
$aryData['transactionID'] = "7H123X43620BH3959058";
$aryData['refundType'] = "Partial"; //Partial or Full
$aryData['currencyCode'] = "USD";
$aryData['amount'] = 2.00;
$aryData['memo'] = "There Memo Detail entered for Partial Refund";
// $aryData['invoiceID'] = "xxxxxxxxxx";
//echo "<pre>";
//print_r($aryData);die;
$ref = new PayPalRefund("sandbox");
$aryRes = $ref->refundAmount($aryData);
if($aryRes['ACK'] == "Success")
echo "Amount Refunded Successfully";
else
echo "Error Refunding Amount";
echo "<pre>";
print_r($aryRes);
echo "</pre>";
?>
and I am getting Error Refunding amount:
Error Refunding Amount
Array
(
[TIMESTAMP] => 2014-05-23T07:13:21Z
[CORRELATIONID] => f42e83df6f52b
[ACK] => Failure
[VERSION] => 51.0
[BUILD] => 11110362
[L_ERRORCODE0] => 10007
[L_SHORTMESSAGE0] => Permission denied
[L_LONGMESSAGE0] => You do not have permission to refund this transaction
[L_SEVERITYCODE0] => Error
)

you need to obtain permission from the user who received the funds and then issue a refund on his behalf.
read this to find out how.
change
"scope":"INVOICING"
to
"scope":"REFUND"

Related

PayPal IPN Sent with 200 response but my database is not updating

I am trying to implement the PayPal IPN solution. I am checking the IPN History page of my saccount and all messages are being sent with a 200 response. The problem is that nothing in my DB is being updated or inserted.
My environment is:
PHP 7.4
Apache
CentOS 8
I also tried to log something to a file but I am failing to do so. This is the first time I try to implement the PayPal IPN and I am very confused.
This is my current code:
<?php
class PaypalIPN
{
/** #var bool Indicates if the sandbox endpoint is used. */
private $use_sandbox = false;
/** #var bool Indicates if the local certificates are used. */
private $use_local_certs = true;
/** Production Postback URL */
const VERIFY_URI = 'https://ipnpb.paypal.com/cgi-bin/webscr';
/** Sandbox Postback URL */
const SANDBOX_VERIFY_URI = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';
/** Response from PayPal indicating validation was successful */
const VALID = 'VERIFIED';
/** Response from PayPal indicating validation failed */
const INVALID = 'INVALID';
const DEBUG = true;
/**
* Sets the IPN verification to sandbox mode (for use when testing,
* should not be enabled in production).
* #return void
*/
public function useSandbox()
{
$this->use_sandbox = true;
}
/**
* Sets curl to use php curl's built in certs (may be required in some
* environments).
* #return void
*/
public function usePHPCerts()
{
$this->use_local_certs = false;
}
/**
* Determine endpoint to post the verification data to.
*
* #return string
*/
public function getPaypalUri()
{
if ($this->use_sandbox) {
return self::SANDBOX_VERIFY_URI;
} else {
return self::VERIFY_URI;
}
}
/**
* Verification Function
* Sends the incoming post data back to PayPal using the cURL library.
*
* #return bool
* #throws Exception
*/
public function verifyIPN()
{
if ( ! count($_POST)) {
throw new Exception("Missing POST Data");
}
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode('=', $keyval);
if (count($keyval) == 2) {
// Since we do not want the plus in the datetime string to be encoded to a space, we manually encode it.
if ($keyval[0] === 'payment_date') {
if (substr_count($keyval[1], '+') === 1) {
$keyval[1] = str_replace('+', '%2B', $keyval[1]);
}
}
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
}
// Build the body of the verification post request, adding the _notify-validate command.
$req = 'cmd=_notify-validate';
foreach ($myPost as $key => $value) {
$value = urlencode($value);
$req .= "&$key=$value";
}
// Post the data back to PayPal, using curl. Throw exceptions if errors occur.
$ch = curl_init($this->getPaypalUri());
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// This is often required if the server is missing a global cert bundle, or is using an outdated one.
if ($this->use_local_certs) {
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/cert/cacert.pem");
}
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'User-Agent: PHP-IPN-Verification-Script',
'Connection: Close',
));
$res = curl_exec($ch);
if ( ! ($res)) {
$errno = curl_errno($ch);
$errstr = curl_error($ch);
curl_close($ch);
throw new Exception("cURL error: [$errno] $errstr");
}
$info = curl_getinfo($ch);
$http_code = $info['http_code'];
if ($http_code != 200) {
throw new Exception("PayPal responded with http code $http_code");
}
curl_close($ch);
// Check if PayPal verifies the IPN data, and if so, return true.
if ($res == self::VALID) {
// crea el LOG
if($this->DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "IPN Verification: $req ". PHP_EOL, 3, 'ipn.log');
}
return true;
} else {
// crea el LOG
if($this->DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "IPN Verification: $req ". PHP_EOL, 3, 'ipn.log');
}
return false;
}
}
}
$ipn = new PaypalIPN();
// Use the sandbox endpoint during testing.
$ipn->useSandbox();
$verified = $ipn->verifyIPN();
if ($verified) {
/*
* Process IPN
* A list of variables is available here:
* https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNandPDTVariables/
*/
$payment_amount = $_POST['mc_gross'];
$payment_status = $_POST['payment_status'];
$custom = $_POST['custom'];
$payer_email = $_POST['payer_email'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$item_name = $_POST['item_name'];
$payment_currency = $_POST['mc_currency'];
$item_number = $_POST['item_number'];
if($payment_amount >= '20') {
// Donation is $20 or higher, so let's add 20% to the coins.
$coins = $payment_amount*10*1.2;
}
else {
// Donation is less than $20, no bonus.
$coins = $payment_amount*10;
}
// Add E. Coins
$acc = new PDO("sqlsrv:Server=myhost;Database=mydb", "myusr", "mypass");
$add = $acc->prepare("UPDATE CashAccount SET Cash = Cash + :coins WHERE ID = :account");
$add->bindParam(':coins', $coins, PDO::PARAM_INT);
$add->bindParam(':account', $custom, PDO::PARAM_STR);
$add->execute();
// Log the donation
$db = new PDO("sqlsrv:Server=myhost;Database=mydb", "myusr", "mypass");
$method = 'PayPal';
$query = $db->prepare("INSERT INTO logs (Account, Amount, Coins, Method, Date, Email) VALUES (:account, :amount, :coins, :method, GETDATE(), :email)");
$query->bindParam(':account', $custom, PDO::PARAM_STR);
$query->bindParam(':amount', $payment_amount, PDO::PARAM_INT);
$query->bindParam(':coins', $coins, PDO::PARAM_INT);
$query->bindParam(':method', $method, PDO::PARAM_STR);
$query->bindParam(':email', $payer_email, PDO::PARAM_STR);
$query->execute();
}
// Reply with an empty 200 response to indicate to paypal the IPN was received correctly.
header("HTTP/1.1 200 OK");
I also enbled IPN Notifications in my Business/Sandbox accounts and updated the URL to http://example.com/paypal_ipn.php
Here is my IPN History from the PayPal sandbox.
Maybe someone here can point me to the right direction.
Where have you looked for your ipn.log file?
PHP may not have write permissions to the current directory.
What happens if you turn on errors/warnings and access your IPN listener from a browser? Does it print errors to the screen, about not being able to open ipn.log for writing?
You may need to use an absolute path to a directory PHP does have permissions to write to, for example:
error_log("This is a message!", 3, "/tmp/ipn.log");

PayPal sandbox DoExpressCheckout API always returns 10422 or 10486 when only paying by a credit card

I'm a EC manager. PayPal payment in production works without problems, but there is a problem in development (sandbox environment).
As mentioned in the title, DoExpressCheckout API via PHP always returns 10422 or 10486 error codes when only paying by a credit card. This means it works correctly when sandbox account's PayPal balance is enough to pay for an item.
I suspect there are problems in my sandbox account setting or my php code.
Is there anyone have clues to a solution to this problem?
My PHP code here.
<?php
/** DoExpressCheckoutPayment NVP example; last modified 08MAY23.
*
* Complete an Express Checkout transaction.
*/
require_once('paypal_configure.php'); // API settings
// Set request-specific fields.
$environment = ENVIRONMENT; // sandbox
$paymentType = urlencode("Authorization"); // or 'Sale' or 'Order'
$currencyID = urlencode(CURRENCY);
// Set parameter
$token = urlencode($argv[1]);
$payerID = urlencode($argv[2]);
$paymentAmount = urlencode($argv[3]);
$invNum = urlencode($argv[4]);
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
function PPHttpPost($methodName_, $nvpStr_) {
global $environment;
// Set up your API credentials, PayPal end point, and API version.
$API_UserName = urlencode(API_USERNAME);
$API_Password = urlencode(API_PASSWORD);
$API_Signature = urlencode(API_SIGNATURE);
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment || "beta-sandbox" === $environment) {
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('51.0');
// setting the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Set the curl parameters.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if(!$httpResponse) {
exit('$methodName_ failed: '.curl_error($ch).'('.curl_errno($ch).')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
/**
* This example assumes that a token was obtained from the SetExpressCheckout API call.
* This example also assumes that a payerID was obtained from the SetExpressCheckout API call
* or from the GetExpressCheckoutDetails API call.
*/
// Add request-specific fields to the request string.
$nvpStr = "&TOKEN=$token&PAYERID=$payerID&PAYMENTACTION=$paymentType&AMT=$paymentAmount&CURRENCYCODE=$currencyID";
$nvpStr .= "&INVNUM=$invNum";
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('DoExpressCheckoutPayment', $nvpStr);
// result
$resAck = strtoupper($httpParsedResponseAr["ACK"]);
$resTime = urldecode($httpParsedResponseAr["TIMESTAMP"]);
if( $resAck == "SUCCESS" || $resAck == "SUCCESSWITHWARNING" ) {
// get result
$resCode = "10000";
$resMsg = "_";
$resTranid = urldecode($httpParsedResponseAr["TRANSACTIONID"]);
$resAmount = urldecode($httpParsedResponseAr["AMT"]);
}
else {
// get result
$resCode = $httpParsedResponseAr["L_ERRORCODE0"];
$resMsg = mb_ereg_replace(" ","###SPACE###",urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]));
$resTranid = "_";
$resAmount = "_";
}
// return text
$rtnText = "";
$rtnText = $resAck;
$rtnText .= " ".$resCode;
$rtnText .= " ".$resMsg;
$rtnText .= " ".$resTranid;
$rtnText .= " ".$resAmount;
$rtnText .= " ".$token;
$rtnText .= " ".$payerID;
$rtnText .= " ".$invNum;
$rtnText .= " ".$resTime;
$rtnText .= "\n";
echo $rtnText;
exit(0);
?>
Sometimes sandbox accounts get screwed up. Try creating a fresh sandbox buyer account and make sure to add a credit card to it during that process.

How to manage PayPal subscriptions using the API?

Does anyone know how to manage PayPal subscriptions using their API? I've read that I can use ManageRecurringPaymentsProfileStatus to cancel, suspend and reactivate subscriptions, but I haven't been able to find a method to get the IDs so I'm unable to use it.
This page says to use the method CreateRecurringPaymentsProfile's response which contains the ID, although I'm not creating the subscriptions using the API so I wouldn't be able to do this.
Is there a API method to only get the IDs? Thanks.
Paypal direct payment..please change credential as your sand box provided...
<?php
/** DoDirectPayment NVP example; last modified 08MAY23.
*
* Process a credit card payment.
*/
$environment = 'sandbox'; // or 'beta-sandbox' or 'live'
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
function PPHttpPost($methodName_, $nvpStr_) {
global $environment;
// Set up your API credentials, PayPal end point, and API version.
$API_UserName = urlencode('debash_1332929919_biz_api1.gmail.com');
$API_Password = urlencode('1332929952');
$API_Signature = urlencode('AIiPJKMw38NGZuaiDaeLWrH9x.WBAK4WXf1vh9.Y.YxEM-4DlbDLMEVe');
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment || "beta-sandbox" === $environment) {
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('51.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if(!$httpResponse) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
// Set request-specific fields.
$paymentType = urlencode('Sale'); // or 'Sale'
$firstName = urlencode('Debashis');
$lastName = urlencode('Banerjee');
$creditCardType = urlencode('visa');
$creditCardNumber = urlencode('4860795409505688');
$expDateMonth = '3';
// Month must be padded with leading zero
$padDateMonth = urlencode(str_pad($expDateMonth, 2, '0', STR_PAD_LEFT));
$expDateYear = urlencode('2017');
$cvv2Number = urlencode('111');
$address1 = urlencode('Kaikala');
$address2 = urlencode('Hooghly');
$city = urlencode('Kaikala');
$state = urlencode('WB');
$zip = urlencode('712405');
$country = urlencode('IN'); // US or other valid country code
$amount = urlencode('71');
$currencyID = urlencode('USD'); // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Add request-specific fields to the request string.
$nvpStr = "&PAYMENTACTION=$paymentType&AMT=$amount&CREDITCARDTYPE=$creditCardType&ACCT=$creditCardNumber".
"&EXPDATE=$padDateMonth$expDateYear&CVV2=$cvv2Number&FIRSTNAME=$firstName&LASTNAME=$lastName".
"&STREET=$address1&CITY=$city&STATE=$state&ZIP=$zip&COUNTRYCODE=$country&CURRENCYCODE=$currencyID";
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('DoDirectPayment', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
exit('Direct Payment Completed Successfully: '.print_r($httpParsedResponseAr, true));
} else {
exit('DoDirectPayment failed: ' . print_r($httpParsedResponseAr, true));
}
?>
please visit https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/library_code
Thanks

PayPal Adaptive Payments Error: API credentials are incorrect. Error Code: 520003 [duplicate]

I have stored the customers paypal email address in database and I want to send them money using that email address. I am using PHP.
Anyone please suggest how to do that.
I was looking for the same issue, here's what is working for me.
Tested in 'sandbox' mode and using NVP (instead of SOAP).
Your server must support CURL, in order to verify it use:
<?php
echo 'curl extension/module loaded/installed: ';
echo ( !extension_loaded('curl')) ? 'no' : 'yes';
echo "<br />\n";
phpinfo(INFO_MODULES); // just to be sure
?>
If is not loaded or installed ask to your hostmaster or get it here, otherwise go ahead:
<?php
// code modified from source: https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt
// documentation: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_api_masspay
// sample code: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/library_code
// eMail subject to receivers
$vEmailSubject = 'PayPal payment';
/** MassPay NVP example.
*
* Pay one or more recipients.
*/
// For testing environment: use 'sandbox' option. Otherwise, use 'live'.
// Go to www.x.com (PayPal Integration center) for more information.
$environment = 'sandbox'; // or 'beta-sandbox' or 'live'.
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
function PPHttpPost($methodName_, $nvpStr_)
{
global $environment;
// Set up your API credentials, PayPal end point, and API version.
// How to obtain API credentials:
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_NVPAPIBasics#id084E30I30RO
$API_UserName = urlencode('my_api_username');
$API_Password = urlencode('my_api_password');
$API_Signature = urlencode('my_api_signature');
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment || "beta-sandbox" === $environment)
{
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('51.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if( !$httpResponse)
{
exit("$methodName_ failed: " . curl_error($ch) . '(' . curl_errno($ch) .')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value)
{
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1)
{
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr))
{
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
// Set request-specific fields.
$emailSubject = urlencode($vEmailSubject);
$receiverType = urlencode('EmailAddress');
$currency = urlencode('USD'); // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Receivers
// Use '0' for a single receiver. In order to add new ones: (0, 1, 2, 3...)
// Here you can modify to obtain array data from database.
$receivers = array(
0 => array(
'receiverEmail' => "user1#paypal.com",
'amount' => "20.00",
'uniqueID' => "id_001", // 13 chars max
'note' => " payment of commissions"), // I recommend use of space at beginning of string.
1 => array(
'receiverEmail' => "user2#paypal.com",
'amount' => "162.38",
'uniqueID' => "A47-92w", // 13 chars max, available in 'My Account/Overview/Transaction details' when the transaction is made
'note' => " payoff of what I owed you" // space again at beginning.
)
);
$receiversLenght = count($receivers);
// Add request-specific fields to the request string.
$nvpStr="&EMAILSUBJECT=$emailSubject&RECEIVERTYPE=$receiverType&CURRENCYCODE=$currency";
$receiversArray = array();
for($i = 0; $i < $receiversLenght; $i++)
{
$receiversArray[$i] = $receivers[$i];
}
foreach($receiversArray as $i => $receiverData)
{
$receiverEmail = urlencode($receiverData['receiverEmail']);
$amount = urlencode($receiverData['amount']);
$uniqueID = urlencode($receiverData['uniqueID']);
$note = urlencode($receiverData['note']);
$nvpStr .= "&L_EMAIL$i=$receiverEmail&L_Amt$i=$amount&L_UNIQUEID$i=$uniqueID&L_NOTE$i=$note";
}
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('MassPay', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
exit('MassPay Completed Successfully: ' . print_r($httpParsedResponseAr, true));
}
else
{
exit('MassPay failed: ' . print_r($httpParsedResponseAr, true));
}
?>
Good luck!
What you're looking for is DoMassPay from the PayPal official code samples, not easy to guess that name :P
They have added sample code to their website:
https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt

How to send money to paypal using php

I have stored the customers paypal email address in database and I want to send them money using that email address. I am using PHP.
Anyone please suggest how to do that.
I was looking for the same issue, here's what is working for me.
Tested in 'sandbox' mode and using NVP (instead of SOAP).
Your server must support CURL, in order to verify it use:
<?php
echo 'curl extension/module loaded/installed: ';
echo ( !extension_loaded('curl')) ? 'no' : 'yes';
echo "<br />\n";
phpinfo(INFO_MODULES); // just to be sure
?>
If is not loaded or installed ask to your hostmaster or get it here, otherwise go ahead:
<?php
// code modified from source: https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt
// documentation: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_api_masspay
// sample code: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/library_code
// eMail subject to receivers
$vEmailSubject = 'PayPal payment';
/** MassPay NVP example.
*
* Pay one or more recipients.
*/
// For testing environment: use 'sandbox' option. Otherwise, use 'live'.
// Go to www.x.com (PayPal Integration center) for more information.
$environment = 'sandbox'; // or 'beta-sandbox' or 'live'.
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
function PPHttpPost($methodName_, $nvpStr_)
{
global $environment;
// Set up your API credentials, PayPal end point, and API version.
// How to obtain API credentials:
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_NVPAPIBasics#id084E30I30RO
$API_UserName = urlencode('my_api_username');
$API_Password = urlencode('my_api_password');
$API_Signature = urlencode('my_api_signature');
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment || "beta-sandbox" === $environment)
{
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('51.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if( !$httpResponse)
{
exit("$methodName_ failed: " . curl_error($ch) . '(' . curl_errno($ch) .')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value)
{
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1)
{
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr))
{
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
// Set request-specific fields.
$emailSubject = urlencode($vEmailSubject);
$receiverType = urlencode('EmailAddress');
$currency = urlencode('USD'); // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Receivers
// Use '0' for a single receiver. In order to add new ones: (0, 1, 2, 3...)
// Here you can modify to obtain array data from database.
$receivers = array(
0 => array(
'receiverEmail' => "user1#paypal.com",
'amount' => "20.00",
'uniqueID' => "id_001", // 13 chars max
'note' => " payment of commissions"), // I recommend use of space at beginning of string.
1 => array(
'receiverEmail' => "user2#paypal.com",
'amount' => "162.38",
'uniqueID' => "A47-92w", // 13 chars max, available in 'My Account/Overview/Transaction details' when the transaction is made
'note' => " payoff of what I owed you" // space again at beginning.
)
);
$receiversLenght = count($receivers);
// Add request-specific fields to the request string.
$nvpStr="&EMAILSUBJECT=$emailSubject&RECEIVERTYPE=$receiverType&CURRENCYCODE=$currency";
$receiversArray = array();
for($i = 0; $i < $receiversLenght; $i++)
{
$receiversArray[$i] = $receivers[$i];
}
foreach($receiversArray as $i => $receiverData)
{
$receiverEmail = urlencode($receiverData['receiverEmail']);
$amount = urlencode($receiverData['amount']);
$uniqueID = urlencode($receiverData['uniqueID']);
$note = urlencode($receiverData['note']);
$nvpStr .= "&L_EMAIL$i=$receiverEmail&L_Amt$i=$amount&L_UNIQUEID$i=$uniqueID&L_NOTE$i=$note";
}
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('MassPay', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
exit('MassPay Completed Successfully: ' . print_r($httpParsedResponseAr, true));
}
else
{
exit('MassPay failed: ' . print_r($httpParsedResponseAr, true));
}
?>
Good luck!
What you're looking for is DoMassPay from the PayPal official code samples, not easy to guess that name :P
They have added sample code to their website:
https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt

Categories