Monday, June 3, 2013

how to integrate paypal adaptive chained delay payment in php

create a paypalplatform.php
paste below code :
--------------------------------------------------------------------------------------------------------------

<?php
 /********************************************
 PayPal Adaptive Payments API Module
 
 Defines all the global variables and the wrapper functions
 ********************************************/
 define('PROXY_HOST', '127.0.0.1');
 define('PROXY_PORT' , '808');

 define('Env', 'sandbox');

 //------------------------------------
 // PayPal API Credentials
 // Replace <API_USERNAME> with your API Username
 // Replace <API_PASSWORD> with your API Password
 // Replace <API_SIGNATURE> with your Signature
 //------------------------------------
 define('API_UserName','tesssstneeraj_api1.techwave.com');
 define('API_Password','LAPBXMsssFLSBJE6YNA');
 define('API_Signature','AFcWxV21Css7fd0v3bYYYRCpSSRl31Ad8Viro.7-xWcAo2Kkq0koTD7rFO');
 // AppID is preset for sandbox use
 //   If your application goes live, you will be assigned a value for the live
 //   environment by PayPal as part of the live onboarding process.
 define('API_AppID','APP-80W284485P519543T');

 if (Env == "sandbox")
 {

  define('API_Endpoint','https://svcs.sandbox.paypal.com/AdaptivePayments');
 }
 else
 {
  define('API_Endpoint','https://svcs.paypal.com/AdaptivePayments');
}

 define('USE_PROXY',false);

 if (session_id() == "")
  session_start();

 function generateCharacter () {
  $possible = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
  return $char;
 }

 function generateTrackingID () {
 $GUID = generateCharacter().generateCharacter().generateCharacter();
 $GUID .=generateCharacter().generateCharacter().generateCharacter();
 $GUID .=generateCharacter().generateCharacter().generateCharacter();
 return $GUID;
 }

 /*
 '-------------------------------------------------------------------------------
 ' Purpose: Prepares the parameters for the Refund API Call.
 '   The API credentials used in a Pay call can make the Refund call
 '   against a payKey, or a tracking id, or to specific receivers of a payKey or
 '   a tracking id that resulted from the Pay call.
 '
 '   A receiver itself with its own API credentials can make a Refund call against
 '   the transactionId corresponding to their transaction.
 '   The API credentials used in a Pay call cannot use transactionId to issue a refund
 '   for a transaction for which they themselves were not the receiver.
 '
 '   If you do specify specific receivers, you must provide the amounts as well.
 '   If you specify a transactionId, then only the receiver of that transactionId
 '   is affected. Therefore the receiverEmailArray and receiverAmountArray should
 '   have 1 entry each if you do want to give a partial refund.
 ' Inputs:
 '
 ' Conditionally Required:
 '  One of the following:  payKey or trackingId or trasactionId or
 '                         (payKey and receiverEmailArray and receiverAmountArray) or
 '                         (trackingId and receiverEmailArray and receiverAmountArray)
 '                         or (transactionId and receiverEmailArray
 '                         and receiverAmountArray)
 ' Returns:
 '  The NVP Collection object of the Refund call response.
 '------------------------------------------------------------------------------------
 */
 function CallRefund( $payKey, $transactionId, $trackingId,
          $receiverEmailArray, $receiverAmountArray )
 {
  /* Gather the information to make the Refund call.
   The variable nvpstr holds the name-value pairs.
  */

  $nvpstr = "";

  // conditionally required fields
  if ("" != $payKey)
  {
   $nvpstr = "payKey=" . urlencode($payKey);
   if (0 != count($receiverEmailArray))
   {
    reset($receiverEmailArray);
    while (list($key, $value) = each($receiverEmailArray))
    {
     if ("" != $value)
     {
      $nvpstr .= "&receiverList.receiver(" . $key . ").email=" . urlencode($value);
     }
    }
   }
   if (0 != count($receiverAmountArray))
   {
    reset($receiverAmountArray);
    while (list($key, $value) = each($receiverAmountArray))
    {
     if ("" != $value)
     {
      $nvpstr .= "&receiverList.receiver(" . $key . ").amount=" . urlencode($value);
     }
    }
   }
  }
  elseif ("" != $trackingId)
  {
   $nvpstr = "trackingId=" . urlencode($trackingId);
   if (0 != count($receiverEmailArray))
   {
    reset($receiverEmailArray);
    while (list($key, $value) = each($receiverEmailArray))
    {
     if ("" != $value)
     {
      $nvpstr .= "&receiverList.receiver(" . $key . ").email=" . urlencode($value);
     }
    }
   }
   if (0 != count($receiverAmountArray))
   {
    reset($receiverAmountArray);
    while (list($key, $value) = each($receiverAmountArray))
    {
     if ("" != $value)
     {
      $nvpstr .= "&receiverList.receiver(" . $key . ").amount=" . urlencode($value);
     }
    }
   }
  }
  elseif ("" != $transactionId)
  {
   $nvpstr = "transactionId=" . urlencode($transactionId);
   // the caller should only have 1 entry in the email and amount arrays
   if (0 != count($receiverEmailArray))
   {
    reset($receiverEmailArray);
    while (list($key, $value) = each($receiverEmailArray))
    {
     if ("" != $value)
     {
      $nvpstr .= "&receiverList.receiver(" . $key . ").email=" . urlencode($value);
     }
    }
   }
   if (0 != count($receiverAmountArray))
   {
    reset($receiverAmountArray);
    while (list($key, $value) = each($receiverAmountArray))
    {
     if ("" != $value)
     {
      $nvpstr .= "&receiverList.receiver(" . $key . ").amount=" . urlencode($value);
     }
    }
   }
  }

  /* Make the Refund call to PayPal */
  $resArray = hash_call("Refund", $nvpstr);

  /* Return the response array */
  return $resArray;
 }

 /*
 '------------------------------------------------------------------------------------
 ' Purpose: Prepares the parameters for the PaymentDetails API Call.
 '   The PaymentDetails call can be made with either
 '   a payKey, a trackingId, or a transactionId of a previously successful Pay call.
 ' Inputs:
 '
 ' Conditionally Required:
 '  One of the following:  payKey or transactionId or trackingId
 ' Returns:
 '  The NVP Collection object of the PaymentDetails call response.
 '------------------------------------------------------------------------------------
 */
 function CallPaymentDetails( $payKey, $transactionId, $trackingId )
 {
  /* Gather the information to make the PaymentDetails call.
   The variable nvpstr holds the name-value pairs.
  */

  $nvpstr = "";

  // conditionally required fields
  if ("" != $payKey)
  {
   $nvpstr = "payKey=" . urlencode($payKey);
  }
  elseif ("" != $transactionId)
  {
   $nvpstr = "transactionId=" . urlencode($transactionId);
  }
  elseif ("" != $trackingId)
  {
   $nvpstr = "trackingId=" . urlencode($trackingId);
  }

  /* Make the PaymentDetails call to PayPal */
  $resArray = hash_call("PaymentDetails", $nvpstr);

  /* Return the response array */
  return $resArray;
 }

 /*
 '------------------------------------------------------------------------------------
 ' Purpose: Prepares the parameters for the Pay API Call.
 ' Inputs:
 '
 ' Required:
 '
 ' Optional:
 '
 ' Returns:
 '  The NVP Collection object of the Pay call response.
 '------------------------------------------------------------------------------------
 */
 function CallPay( $actionType, $cancelUrl, $returnUrl, $currencyCode,
     $receiverEmailArray, $receiverAmountArray, $receiverPrimaryArray,
     $receiverInvoiceIdArray, $feesPayer, $ipnNotificationUrl, $memo,
     $pin, $preapprovalKey, $reverseAllParallelPaymentsOnError,
     $senderEmail, $trackingId )
 {

  /* Gather the information to make the Pay call.
   The variable nvpstr holds the name-value pairs.
  */



  // required fields
  $nvpstr = "actionType=" . urlencode($actionType) . "&currencyCode=";
  $nvpstr .= urlencode($currencyCode) . "&returnUrl=";
  $nvpstr .= urlencode($returnUrl) . "&cancelUrl=" . urlencode($cancelUrl);

  if (0 != count($receiverAmountArray))
  {

   reset($receiverAmountArray);

   while (list($key, $value) = each($receiverAmountArray))
   {
    if ("" != $value)
    {
     $nvpstr .= "&receiverList.receiver(" . $key . ").amount=" . urlencode($value);
    }
   }
  }

  if (0 != count($receiverEmailArray))
  {
   reset($receiverEmailArray);
   while (list($key, $value) = each($receiverEmailArray))
   {
    if ("" != $value)
    {
     $nvpstr .= "&receiverList.receiver(" . $key . ").email=" . urlencode($value);
    }
   }
  }

  if (0 != count($receiverPrimaryArray))
  {
   reset($receiverPrimaryArray);
   while (list($key, $value) = each($receiverPrimaryArray))
   {
    if ("" != $value)
    {
     $nvpstr = $nvpstr . "&receiverList.receiver(" . $key . ").primary=" .
             urlencode($value);
    }
   }
  }

  if (0 != count($receiverInvoiceIdArray))
  {
   reset($receiverInvoiceIdArray);
   while (list($key, $value) = each($receiverInvoiceIdArray))
   {
    if ("" != $value)
    {
     $nvpstr = $nvpstr . "&receiverList.receiver(" . $key . ").invoiceId=" .
               urlencode($value);
    }
   }
  }

  // optional fields
  if ("" != $feesPayer)
  {
   $nvpstr .= "&feesPayer=" . urlencode($feesPayer);
  }

  if ("" != $ipnNotificationUrl)
  {
   $nvpstr .= "&ipnNotificationUrl=" . urlencode($ipnNotificationUrl);
  }

  if ("" != $memo)
  {
   $nvpstr .= "&memo=" . urlencode($memo);
  }

  if ("" != $pin)
  {
   $nvpstr .= "&pin=" . urlencode($pin);
  }

  if ("" != $preapprovalKey)
  {
   $nvpstr .= "&preapprovalKey=" . urlencode($preapprovalKey);
  }

  if ("" != $reverseAllParallelPaymentsOnError)
  {
   $nvpstr .= "&reverseAllParallelPaymentsOnError=";
   $nvpstr .= urlencode($reverseAllParallelPaymentsOnError);
  }

  if ("" != $senderEmail)
  {
   $nvpstr .= "&senderEmail=" . urlencode($senderEmail);
  }

  if ("" != $trackingId)
  {
   $nvpstr .= "&trackingId=" . urlencode($trackingId);
  }

  /* Make the Pay call to PayPal */
$resArray = hash_call("Pay", $nvpstr);

  /* Return the response array */
  return $resArray;
 }

 /*
 '---------------------------------------------------------------------------
 ' Purpose: Prepares the parameters for the PreapprovalDetails API Call.
 ' Inputs:
 '

 ' Required:
 '  preapprovalKey:A preapproval key that identifies the agreement
 '                 resulting from a previously successful Preapproval call.
 ' Returns:
 '  The NVP Collection object of the PreapprovalDetails call response.
 '---------------------------------------------------------------------------
 */
 function CallPreapprovalDetails( $preapprovalKey )
 {
  /* Gather the information to make the PreapprovalDetails call.
   The variable nvpstr holds the name-value pairs.
  */

  // required fields
  $nvpstr = "preapprovalKey=" . urlencode($preapprovalKey);

  /* Make the PreapprovalDetails call to PayPal */
  $resArray = hash_call("PreapprovalDetails", $nvpstr);

  /* Return the response array */
  return $resArray;
 }

 /*
 '---------------------------------------------------------------------------
 ' Purpose: Prepares the parameters for the Preapproval API Call.
 ' Inputs:
 '
 ' Required:
 '
 ' Optional:
 '
 ' Returns:
 '  The NVP Collection object of the Preapproval call response.
 '---------------------------------------------------------------------------
 */
 function CallPreapproval( $returnUrl, $cancelUrl, $currencyCode,
        $startingDate, $endingDate, $maxTotalAmountOfAllPayments,
        $senderEmail, $maxNumberOfPayments, $paymentPeriod, $dateOfMonth,
        $dayOfWeek, $maxAmountPerPayment, $maxNumberOfPaymentsPerPeriod, $pinType )
 {
  /* Gather the information to make the Preapproval call.
   The variable nvpstr holds the name-value pairs.
  */

  // required fields
  $nvpstr = "returnUrl=" . urlencode($returnUrl) . "&cancelUrl=" . urlencode($cancelUrl);
  $nvpstr .= "&currencyCode=" . urlencode($currencyCode) . "&startingDate=";
  $nvpstr .= urlencode($startingDate) . "&endingDate=" . urlencode($endingDate);
  $nvpstr .= "&maxTotalAmountOfAllPayments=" . urlencode($maxTotalAmountOfAllPayments);

  // optional fields
  if ("" != $senderEmail)
  {
   $nvpstr .= "&senderEmail=" . urlencode($senderEmail);
  }

  if ("" != $maxNumberOfPayments)
  {
   $nvpstr .= "&maxNumberOfPayments=" . urlencode($maxNumberOfPayments);
  }

  if ("" != $paymentPeriod)
  {
   $nvpstr .= "&paymentPeriod=" . urlencode($paymentPeriod);
  }

  if ("" != $dateOfMonth)
  {
   $nvpstr .= "&dateOfMonth=" . urlencode($dateOfMonth);
  }

  if ("" != $dayOfWeek)
  {
   $nvpstr .= "&dayOfWeek=" . urlencode($dayOfWeek);
  }

  if ("" != $maxAmountPerPayment)
  {
   $nvpstr .= "&maxAmountPerPayment=" . urlencode($maxAmountPerPayment);
  }

  if ("" != $maxNumberOfPaymentsPerPeriod)
  {
   $nvpstr .= "&maxNumberOfPaymentsPerPeriod=" . urlencode($maxNumberOfPaymentsPerPeriod);
  }

  if ("" != $pinType)
  {
   $nvpstr .= "&pinType=" . urlencode($pinType);
  }

  /* Make the Preapproval call to PayPal */
  $resArray = hash_call("Preapproval", $nvpstr);

  /* Return the response array */
  return $resArray;
 }

 /**
   '----------------------------------------------------------------------------------
   * hash_call: Function to perform the API call to PayPal using API signature
   * @methodName is name of API method.
   * @nvpStr is nvp string.
   * returns an associative array containing the response from the server.
   '----------------------------------------------------------------------------------
 */
 function hash_call($methodName, $nvpStr)
 {
  //declaring of global variables
  global $API_Endpoint, $API_UserName, $API_Password, $API_Signature, $API_AppID;
  global $USE_PROXY, $PROXY_HOST, $PROXY_PORT;

  $API_Endpoint .= API_Endpoint."/" .$methodName;

  //setting the curl parameters.
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL,$API_Endpoint);
  curl_setopt($ch, CURLOPT_VERBOSE, 1);

  //turning 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 HTTP Headers
  curl_setopt($ch, CURLOPT_HTTPHEADER,  array(
  'X-PAYPAL-REQUEST-DATA-FORMAT: NV',
  'X-PAYPAL-RESPONSE-DATA-FORMAT: NV',
  'X-PAYPAL-SECURITY-USERID: ' . API_UserName,
  'X-PAYPAL-SECURITY-PASSWORD: ' .API_Password,
  'X-PAYPAL-SECURITY-SIGNATURE: ' . API_Signature,
  'X-PAYPAL-SERVICE-VERSION: 1.3.0',
  'X-PAYPAL-APPLICATION-ID: ' . API_AppID
 
  ));

    //if USE_PROXY constant set to TRUE in Constants.php,
    //then only proxy will be enabled.
  //Set proxy name to PROXY_HOST and port number to PROXY_PORT in constants.php
  if($USE_PROXY)
   curl_setopt ($ch, CURLOPT_PROXY, $PROXY_HOST. ":" . $PROXY_PORT);

  // RequestEnvelope fields
  $detailLevel = urlencode("ReturnAll"); // See DetailLevelCode in the WSDL
                                         // for valid enumerations
  $errorLanguage = urlencode("en_US");  // This should be the standard RFC
                                        // 3066 language identification tag,
                                        // e.g., en_US

 // NVPRequest for submitting to server
 $nvpreq = "requestEnvelope.errorLanguage=$errorLanguage&requestEnvelope";
 $nvpreq .= "detailLevel=$detailLevel&$nvpStr";

  //setting the nvpreq as POST FIELD to curl
  curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

  //getting response from server
  $response = curl_exec($ch);

  //converting NVPResponse to an Associative Array
  $nvpResArray=deformatNVP($response);

  $nvpReqArray=deformatNVP($nvpreq);

  $_SESSION['nvpReqArray']=$nvpReqArray;

  if (curl_errno($ch))
  {
   // moving to display page to display curl errors
     $_SESSION['curl_error_no']=curl_errno($ch) ;
     $_SESSION['curl_error_msg']=curl_error($ch);

     //Execute the Error handling module to display errors.
  }
  else
  {
    //closing the curl
    curl_close($ch);
  }

  return $nvpResArray;
 }

 /*'----------------------------------------------------------------------------
  Purpose: Redirects to PayPal.com site.
  Inputs:  $cmd is the querystring
  Returns:
 -------------------------------------------------------------------------------
 */
 function RedirectToPayPal ( $cmd )
 {
  // Redirect to paypal.com here
  global $Env;

  $payPalURL = "";

  if (Env == "sandbox")
  {
   $payPalURL = "https://www.sandbox.paypal.com/webscr?" . $cmd;
  }
  else
  {
   $payPalURL = "https://www.paypal.com/webscr?" . $cmd;
  }

  header("Location: ".$payPalURL);
 }


 /*'----------------------------------------------------------------------------
   * This function will take NVPString and convert it to an Associative Array
   * and then will decode the response.
   * It is useful to search for a particular key and display arrays.
   * @nvpstr is NVPString.
   * @nvpArray is Associative Array.
    ----------------------------------------------------------------------------
   */



 function deformatNVP($nvpstr)
 {
  $intial=0;
  $nvpArray = array();

  while(strlen($nvpstr))
  {
   //postion of Key
   $keypos= strpos($nvpstr,'=');
   //position of value
   $valuepos = strpos($nvpstr,'&') ? strpos($nvpstr,'&'): strlen($nvpstr);

   /*getting the Key and Value values and storing in a Associative Array*/
   $keyval=substr($nvpstr,$intial,$keypos);
   $valval=substr($nvpstr,$keypos+1,$valuepos-$keypos-1);
   //decoding the respose
   $nvpArray[urldecode($keyval)] =urldecode( $valval);
   $nvpstr=substr($nvpstr,$valuepos+1,strlen($nvpstr));
      }
  return $nvpArray;
 }
?>

--------------------------------------------------------------------------------------------------------------
create paymment redirect page

<?php
require_once ("paypalplatform.php");

// Request specific required fields
$actionType = "PAY_PRIMARY";
$cancelUrl = 'your cancel url';
$returnUrl = 'your return url';
$currencyCode = "USD";

// A chained payment can be made with 1 primary receiver and between 1 and 5 secondary
// receivers
// TODO - Specify the receiver emails
//        Remove or set to an empty string the array entries for receivers that you
//        do not have
//echo   $this->Salar_Sum_Price ;

$receiverEmailArray = array(
 'primary email id',
  'secondary email-1',
  'secondary email-1'
  );

// TODO - Specify the receiver amounts as the amount of money, for example, '5' or '5.55'
//        Remove or set to an empty string the array entries for receivers that you
//        do not have
$receiverAmountArray = array(
  'primaary amount',
  'sendary amout1',
  'sendary amout2'
  );

// TODO - Set ONLY 1 receiver in the array to 'true' as the primary receiver, and set the
//        other receivers corresponding to those indicated in receiverEmailArray to
//        'false'. Make sure that you do NOT specify more values in this array than
//        in the receiverEmailArray.
$receiverPrimaryArray = array(
  ''
  );

// TODO - Set invoiceId to uniquely identify the transaction associated with each receiver
//        Set the array entries with value for receivers that you have each of the array
//        Values must be unique across all Pay calls made by the caller's API credentials
$receiverInvoiceIdArray = array(
  ''
  );

// Request specific optional fields
//   Provide a value for each field that you want to include in the request;
//   if left as an empty string, the field will not be passed in the request
$senderEmail = ""; // TODO - If you are executing the Pay call against a preapprovalKey,
                   // you should set senderEmail
                   // It is not required if the web approval flow immediately
                   // follows this Pay call
$feesPayer = "";
$ipnNotificationUrl = "";
$memo = ""; // maxlength is 1000 characters
$pin = ""; // TODO - If you are executing the Pay call against an existing preapproval
           // that requires a pin, then you must set this
$preapprovalKey = ""; // TODO - If you are executing the Pay call against an existing
                      // preapproval, set the preapprovalKey here
$reverseAllParallelPaymentsOnError = ""; // TODO - Do not specify for chained payment
$trackingId = generateTrackingID(); // generateTrackingID function is found
                                    // in paypalplatform.php


$resArray = CallPay($actionType, $cancelUrl, $returnUrl, $currencyCode,
      $receiverEmailArray, $receiverAmountArray, $receiverPrimaryArray,
      $receiverInvoiceIdArray, $feesPayer, $ipnNotificationUrl, $memo,
      $pin, $preapprovalKey, $reverseAllParallelPaymentsOnError,
      $senderEmail, $trackingId
);


$ack = strtoupper($resArray["responseEnvelope.ack"]);
if($ack=="SUCCESS")
{
 if ("" == $preapprovalKey)
 {
  // redirect for web approval flow

  $cmd = "cmd=_ap-payment&paykey=" . urldecode($resArray["payKey"]);
  //$cmd = "cmd=_ap-preapproval&preapprovalkey=" . urldecode($resArray["preapprovalKey"]);

  RedirectToPayPal ( $cmd );
 }
 else
 {
  // The Pay API call was made for an existing preapproval agreement, so no approval
  // flow follows.
  // payKey is the key that you can use to identify the result from this Pay call.
  $payKey = urldecode($resArray["payKey"]);
  // paymentExecStatus is the status of the payment
  $paymentExecStatus = urldecode($resArray["paymentExecStatus"]);
  // Note that in order to get the exact status of the transactions resulting from
  // a Pay API call, you should make the PaymentDetails API call for the payKey
 }
}
else
{
 //Display a user-friendly Error on the page using any of the following error information
 //returned by PayPal.
 //TODO - There can be more than 1 error, so check for "error(1).errorId",
 //       then "error(2).errorId", and so on until you find no more errors.
 $ErrorCode = urldecode($resArray["error(0).errorId"]);
 $ErrorMsg = urldecode($resArray["error(0).message"]);
 $ErrorDomain = urldecode($resArray["error(0).domain"]);
 $ErrorSeverity = urldecode($resArray["error(0).severity"]);
 $ErrorCategory = urldecode($resArray["error(0).category"]);

 echo "Pay API call failed. ";
 echo "Detailed Error Message: " . $ErrorMsg;
 echo "Error Code: " . $ErrorCode;
 echo "Error Severity: " . $ErrorSeverity;
 echo "Error Domain: " . $ErrorDomain;
 echo "Error Category: " . $ErrorCategory;
}
?>

5 comments:

  1. very helpful and thanks for the blog!
    I have a question. If we do a delayed chain payment, initially we setup the amount that the secondary and primary receiver would receive. since this is a delayed payment, after some time i need to change the amount that the secondary receiver would receive(depending on his service) before executing the transaction. I tried to do a partial refund, but then i cannot execute it. The scenario is as fallows.

    We are using Adaptive Delayed Chained Payment method to transfer funds from one party to another party with ourselves as an intermediary merchant that takes a percentage. In this scenario we are the primary receiver and there is a secondary receiver as well. In case of a partial refund to the party sending the money (the client) we need to transfer the balance fee less our commission to the secondary receiver.


    It seems that we cannot call the "Execute" function after the partial refund process to complete the transaction flow. i.e. once the the client is partially refunded, we as the intermediary and primary receiver hold the balance funds. The secondary receiver does not get paid since we cannot call the "Execute" function. So the balance fee is stuck at the primary receiver end. So how can we send the balance fee to the secondary receiver in this partial refunding process? Any help would be highly appreciated.

    ReplyDelete
    Replies
    1. Dear Jaliya,
      Thanks for good question you have arise . i thing you do not want to call manually execute function if yes, then i can say the substitute way you can do it.here is the CallRefund() you can use your application whenever your operation is satisfactory.

      $receiverAmountArray = array(
      .04*$backing_amount,
      $backing_amount
      );
      CallRefund( $payKey, $transactionId, $trackingId,$receiverEmailArray, $receiverAmountArray );

      Delete
  2. Nice blog

    how can i get transaction information about payKey and transaction information after redirect page from paypal to my domain

    ReplyDelete