Transaction id is invalid 10609 - php

I'm very new to paypal api, I've followed this tutorial and adapted the code to my needs.
I'd like to make a basic Authorization & Capture in 3 steps but I always fail in capturing
Customer land to paypal_pay_redirect.php for login into paypal and make a paymet
The payment is fine and we land to paypal_success.php, here I request the Authorization and keep the TRANSACTIONID for the next step
paypal_capture.php I use the transactionid for capture the payment but I always get "10609: Transaction id is invalid"
here the code, where is the mistake?
thanks
paypal_lib.php
<?php
// code from http://coding.smashingmagazine.com/2011/09/05/getting-started-with-the-paypal-api/
class Paypal {
/**
* Last error message(s)
* #var array
*/
protected $_errors = array();
/**
* API Credentials
* Use the correct credentials for the environment in use (Live / Sandbox)
* #var array
*/
protected $_credentials = array(
'USER' => 'xxxxxxxxxxxxxxxxxxxx',
'PWD' => 'xxxxxxxxxxxxx',
'SIGNATURE' => 'xxxxxxxxxxxxxxxxxxxxxxxxx'
);
/**
* API endpoint
* Live - https://api-3t.paypal.com/nvp
* Sandbox - https://api-3t.sandbox.paypal.com/nvp
* #var string
*/
protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';
/**
* API Version
* #var string
*/
protected $_version = '74.0';
/**
* Make API request
*
* #param string $method string API method to request
* #param array $params Additional request parameters
* #return array / boolean Response array / boolean false on failure
*/
public function request($method,$params = array()) {
$this -> _errors = array();
if( empty($method) ) { //Check if API method is not empty
$this -> _errors = array('API method is missing');
return false;
}
//Our request parameters
$requestParams = array_merge(
array(
'METHOD' => $method,
'VERSION' => $this -> _version
),
$this -> _credentials
);
//Building our NVP string
$request = http_build_query(array_merge($requestParams, $params));
//cURL settings
$curlOptions = array (
CURLOPT_URL => $this -> _endPoint,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $request
);
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
//Sending our request - $response will hold the API response
$response = curl_exec($ch);
//Checking for cURL errors
if (curl_errno($ch)) {
$this -> _errors = curl_error($ch);
curl_close($ch);
return false;
//Handle errors
} else {
curl_close($ch);
$responseArray = array();
parse_str($response,$responseArray); // Break the NVP string to an array
return $responseArray;
}
}
}
?>
paypal_pay_redirect.php
<?php
require("paypal_lib.php");
//Our request parameters
$requestParams = array(
'RETURNURL' => 'https://www.domain.com/paypal_success.php',
'CANCELURL' => 'https://www.domain.com/paypal_fail.php'
);
$orderParams = array(
'PAYMENTREQUEST_0_AMT' => "57.00",
'PAYMENTREQUEST_0_SHIPPINGAMT' => '0',
'PAYMENTREQUEST_0_CURRENCYCODE' => 'EUR',
'PAYMENTREQUEST_0_ITEMAMT' => "57.00"
);
$item = array(
'L_PAYMENTREQUEST_0_NAME0' => 'xxxxxxxxxx',
'L_PAYMENTREQUEST_0_DESC0' => 'xxxxxxxxxx',
'L_PAYMENTREQUEST_0_AMT0' => "57.00",
'L_PAYMENTREQUEST_0_QTY0' => '1'
);
$paypal = new Paypal();
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams + $item);
if(is_array($response) && $response['ACK'] == 'Success') { //Request successful
$token = $response['TOKEN'];
header( 'Location: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . urlencode($token) );
}
?>
paypal_success.php
<?php
require("paypal_lib.php");
if( isset($_GET['token']) && !empty($_GET['token']) ) { // Token parameter exists
// Get checkout details, including buyer information.
// We can save it for future reference or cross-check with the data we have
$paypal = new Paypal();
$checkoutDetails = $paypal -> request('GetExpressCheckoutDetails', array('TOKEN' => $_GET['token']));
// Complete the checkout transaction
$requestParams = array(
'TOKEN' => $_GET['token'],
'PAYMENTACTION' => 'Authorization',
'PAYERID' => $_GET['PayerID'],
'PAYMENTREQUEST_0_AMT' => '57', // Same amount as in the original request
'PAYMENTREQUEST_0_CURRENCYCODE' => 'EUR' // Same currency as the original request
);
$response = $paypal -> request('DoExpressCheckoutPayment',$requestParams);
if( is_array($response) && $response['ACK'] == 'Success') { // Payment successful
// We'll fetch the transaction ID for internal bookkeeping
$transactionId = $response['PAYMENTINFO_0_TRANSACTIONID'];
echo "OK id: ".$transactionId;
var_dump($response);
}
var_dump($checkoutDetails);
}
?>
paypal_capture.php
<?php
require("paypal_lib.php");
$paypal = new Paypal();
// Complete the checkout transaction
$requestParams = array(
'AMT' => '57.00',
'AUTHORIZATIONID' => 'xxxxxxxxxxxxxxxxxxx', //what I get in paypal_success.php
'CURRENCYCODE' => 'EUR',
'COMPLETETYPE' => 'Complete', // Same amount as in the original request
);
$response = $paypal -> request('DoCapture',$requestParams);
var_dump($response);
?>

Two things:
First, in paypal_pay_redirect.php, add PAYMENTREQUEST_0_PAYMENTACTION => 'Authorization' to $orderParams.
Second, in paypal_success.php, change PAYMENTACTION TO PAYMENTREQUEST_0_PAYMENTACTION.
Here's why:
In your SetExpressCheckout call, if you don't set PAYMENTREQUEST_0_PAYMENTACTION, PayPal assumes that it will be Sale. And if this is set to Sale in your SetExpressCheckout call, then PayPal will only allow you to set it to Sale on your DoExpressCheckoutPayment call.
Additionally, in your DoExpressCheckoutPayment call, you're mixing new and old-style variable names. (Some variables, such as PAYMENTACTION, were renamed when PayPal introduced parallel payments for Express Checkout. PAYMENTACTION is the old style; PAYMENTREQUEST_0_PAYMENTACTION is the new style.) When you mix old-style and new-style names like this, PayPal recognizes variables using one style, and ignores the other. In your case, PAYMENTREQUEST_0_AMT and PAYMENTREQUEST_0_CURRENCYCODE are being recognized, but PAYMENTACTION is being ignored.
The combination of these two factors means that your transaction is most likely being run as a Sale transaction, not an Authorization. Since you can't capture against a Sale transaction (since it's technically already captured), PayPal responds by saying that the transaction ID is invalid.

Related

Symfony Paypal "Cannot use object of type RedirectResponse as array"

I have set up a simple express checkout Paypal, everything work just fine in Dev Mode but i have an error in production mode.
Cannot use object of type Symfony\Component\HttpFoundation\RedirectResponse as array
$responseArray = $this->requestPaypal('SetExpressCheckout', array(
'RETURNURL' => 'http://returnUrl.fr/member/payment/confirm/validate/membership/'.$ref,
'CANCELURL' => 'http://cancelUrl.fr/member/payment/cancel',
'PAYMENTREQUEST_0_AMT' => $info['price'], # amount of transaction \
'PAYMENTREQUEST_0_CURRENCYCODE' => 'EUR', # currency of transaction \
'PAYMENTREQUEST_0_DESC0' => $info['description'],
'PAYMENTREQUEST_0_CUSTOM' => $info['time'],
));
$token = $responseArray['TOKEN']; // Error line
$payPalUrl = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token='.$token.'';
return $this->redirect($payPalUrl);
METHOD RequestPaypal :
public function requestPaypal($method, $params)
{
$params = array_merge($params, array(
'METHOD' => $method,
'VERSION' => $this->getParameter('version'),
'USER' => $this->getParameter('username'),
'SIGNATURE' => $this->getParameter('signature'),
'PWD' => $this->getParameter('password'),
));
$params = http_build_query($params);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $this->getParameter('endpoint'),
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $params,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_VERBOSE => 1
));
$response = curl_exec($curl);
$responseArray = array();
parse_str($response, $responseArray);
if(curl_errno($curl))
{
$errors = curl_error($curl);
$this->addFlash('danger', $errors);
curl_close($curl);
return $this->redirectToRoute('payment');
}
if($responseArray['ACK'] == 'Success')
{
curl_close($curl);
}
return $responseArray;
}
I think the code doesn't not work in prod because of paypal/sandbox.
Help Please
Nic
As I can see, you face with CURL error and your code executes this block of code: if(curl_errno($curl)) { ... }. I assume that method $this->redirectToRoute returns RedirectResponse object. After that, you trying to get "TOKEN" element on RedirectResponse object, which causes the error. To fix this issue, please add condition to check if method requestPaypal returns RedirectResponse object and return RedirectResponse from your controller to "payment" route with flash message, containing CURL error messages.
This code should handle this situation:
$responseArray = $this->requestPaypal('SetExpressCheckout', array(
'RETURNURL' => 'http://returnUrl.fr/member/payment/confirm/validate/membership/'.$ref,
'CANCELURL' => 'http://cancelUrl.fr/member/payment/cancel',
'PAYMENTREQUEST_0_AMT' => $info['price'], # amount of transaction \
'PAYMENTREQUEST_0_CURRENCYCODE' => 'EUR', # currency of transaction \
'PAYMENTREQUEST_0_DESC0' => $info['description'],
'PAYMENTREQUEST_0_CUSTOM' => $info['time'],
));
if ($responseArray instanceof RedirectResponse) {
return $responseArray;
}
$token = $responseArray['TOKEN'];
$payPalUrl = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token='.$token.'';
return $this->redirect($payPalUrl);

paypal mass payment api use in php

I'm trying to use Paypal Mass Payment API with this code, but I got this error.
I saved this code to a file 'MassPay.php' and uploaded it to my localhost. I'm trying to test the code and if I can make it work I'll use it inside core php, to monthly mass pay teachers.
Array
(
[TIMESTAMP] => 2015-07-03T06:55:19Z
[CORRELATIONID] => 437cfd2eedc02
[ACK] => Failure
[VERSION] => 74.0
[BUILD] => 17235934
[L_ERRORCODE0] => 10004
[L_SHORTMESSAGE0] => Transaction refused because of an invalid argument. See additional error messages for details.
[L_LONGMESSAGE0] => The number of input records is less than or equal to zero
[L_SEVERITYCODE0] => Error
[ERRORS] => Array
(
[0] => Array
(
[L_ERRORCODE] => 10004
[L_SHORTMESSAGE] => Transaction refused because of an invalid argument. See additional error messages for details.
[L_LONGMESSAGE] => The number of input records is less than or equal to zero
[L_SEVERITYCODE] => Error
)
)
[REQUESTDATA] => Array
(
[USER] => dudhat-facilitator_api1.artoongames.com
[PWD] => AXAT8HSZRR4XANFZ
[VERSION] => 74.0
[BUTTONSOURCE] => AngellEYE_PHPClass
[SIGNATURE] => AFcWxV21C7fd0v3bYYYRCpSSRl31Ab1QV5bWA6uEZ.6emUAkZaZEhjiA
[METHOD] => MassPay
[EMAILSUBJECT] => dudhat#artoongames.com
[CURRENCYCODE] => USD
[RECEIVERTYPE] => EmailAddress
)
[RAWREQUEST] => USER=dudhat-facilitator_api1.artoongames.com&PWD=AXAT8HSZRR4XANFZ&VERSION=74.0&BUTTONSOURCE=AngellEYE_PHPClass&SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31Ab1QV5bWA6uEZ.6emUAkZaZEhjiA&METHOD=MassPay&EMAILSUBJECT=dudhat%40artoongames.com&CURRENCYCODE=USD&RECEIVERTYPE=EmailAddress
[RAWRESPONSE] => TIMESTAMP=2015%2d07%2d03T06%3a55%3a19Z&CORRELATIONID=437cfd2eedc02&ACK=Failure&VERSION=74%2e0&BUILD=17235934&L_ERRORCODE0=10004&L_SHORTMESSAGE0=Transaction%20refused%20because%20of%20an%20invalid%20argument%2e%20See%20additional%20error%20messages%20for%20details%2e&L_LONGMESSAGE0=The%20number%20of%20input%20records%20is%20less%20than%20or%20equal%20to%20zero&L_SEVERITYCODE0=Error
)
Use this code "MassPay.php"
<?php
// Include required library files.
require_once('includes/config.php');
require_once('includes/paypal.class.php');
// Create PayPal object.
$PayPalConfig = array('Sandbox' => $sandbox, 'APIUsername' => $api_username, 'APIPassword' => $api_password, 'APISignature' => $api_signature);
$PayPal = new PayPal($PayPalConfig);
// Prepare request arrays
$MPFields = array(
'emailsubject' => 'dudhat#artoongames.com', // The subject line of the email that PayPal sends when the transaction is completed. Same for all recipients. 255 char max.
'currencycode' => 'USD', // Three-letter currency code.
'receivertype' => 'EmailAddress' // Indicates how you identify the recipients of payments in this call to MassPay. Must be EmailAddress or UserID
);
// Typically, you'll loop through some sort of records to build your MPItems array.
// Here I simply include 3 items individually.
$Item1 = array(
'l_email' => 'dudhat#gmail.com', // Required. Email address of recipient. You must specify either L_EMAIL or L_RECEIVERID but you must not mix the two.
'l_receiverid' => 'dudhat#gmail.com', // Required. ReceiverID of recipient. Must specify this or email address, but not both.
'l_amt' => '10.00', // Required. Payment amount.
'l_uniqueid' => '522', // Transaction-specific ID number for tracking in an accounting system.
'l_note' => 'test payment' // Custom note for each recipient.
);
$Item2 = array(
'l_email' => 'dilip#gmail.com', // Required. Email address of recipient. You must specify either L_EMAIL or L_RECEIVERID but you must not mix the two.
'l_receiverid' => 'dilip#gmail.com', // Required. ReceiverID of recipient. Must specify this or email address, but not both.
'l_amt' => '1.00', // Required. Payment amount.
'l_uniqueid' => '523', // Transaction-specific ID number for tracking in an accounting system.
'l_note' => 'test payment' // Custom note for each recipient.
);
$MPItems = array($Item1,$Item2); // etc
$PayPalRequestData = array('MPFields' => $MPFields, 'MPItems' => $MPFields);
// Pass data into class for processing with PayPal and load the response array into $PayPalResult
$PayPalResult = $PayPal->MassPay($PayPalRequestData);
// Write the contents of the response array to the screen for demo purposes.
echo '<pre />';
print_r($PayPalResult);
?>
You assembled some payment items in $MPItems, but did not add $MPItems into the PayPal request data. So PayPal rejected the mass payment as containing no payment items.
You can use below class for to make transaction of mass pay
define your constants with actual your credentials of paypal with mode(live/sandbox).
class PaypalnvpComponent {
private static $API_Username = PAYPAL_API_USERNAME;
private static $API_Password = PAYPAL_API_PASSWORD;
private static $API_Signature = PAYPAL_API_SIGNATURE;
private static $API_Environment = PAYPAL_API_MODE;
private static $API_Version = '116.0';
public static function Call($methodName,$params){
if(self::$API_Environment == 'LIVE'){
$API_Endpoint = "https://api-3t.paypal.com/nvp";
}else{
$API_Endpoint = "https://api-3t.sandbox.paypal.com/nvp";
}
$nvpstr = "";
foreach($params as $k=>$v){
$nvpstr .="&".$k."=".urlencode($v);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
//Turn of server and pakagemanager
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,API signature in requrest
$nvpreq ="";
$nvpreq .= "METHOD=".urlencode($methodName);
$nvpreq .= "&VERSION=".urlencode(self::$API_Version);
$nvpreq .= "&PWD=".urlencode(self::$API_Password);
$nvpreq .= "&USER=".urlencode(self::$API_Username);
$nvpreq .= "&SIGNATURE=".urlencode(self::$API_Signature);
$nvpreq .= $nvpstr;
//set the request as POST field for curl
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
//get the response from server
$httpResponse = curl_exec($ch);
if(!$httpResponse){
return "$methodName failed:".curl_error($ch).'('.curl_errno($ch).')';
}
//Extract the response details
$httpResponseArray = explode('&', $httpResponse);
$httpParsedResponseArray = array();
foreach ($httpResponseArray as $i=>$value){
$tmpArray = explode('=', $value);
if(sizeof($tmpArray) > 1){
$httpParsedResponseArray[$tmpArray[0]] = urldecode($tmpArray[1]);
}
}
if((0 == sizeof($httpParsedResponseArray)) || !array_key_exists('ACK',$httpParsedResponseArray)){
return "Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.";
}
return $httpParsedResponseArray;
}
#----------------------------
# #$hok
# mass payment with multiple users in one go
# paypal transaction status will be : Completed, Failed, Returned, Reversed, Unclaimed, Pending, Blocked
#----------------------------
public static function MassPay($params){
$methodName = "MassPay";
return self::Call($methodName, $params);
}
public static function GetTransactionDetail($params){
$methodName = "GetTransactionDetails";
return self::Call($methodName, $params);
}
public static function TransactionSearch($params){
$methodName = "TransactionSearch";
return self::Call($methodName, $params);
}
}
# below is the example how to use above class
$params = array();
$params["RECEIVERTYPE"] = "EmailAddress";
$params["EMAILSUBJECT"] = "Your withdraw request was processed";
$params["L_AMT0"] = 1;
$params["L_EMAIL0"] = "xyz#xyz.abc";
$params["L_UNIQUEID0"] = rand(11111,9999999);
$params["L_AMT1"] = 2;
$params["L_EMAIL1"] = "hamed-buyer#lifeofu.com";
$params["L_UNIQUEID1"] = rand(11111,9999999);
$params["L_AMT2"] = 3;
$params["L_EMAIL2"] = "testuser1#test1.com";
$params["L_UNIQUEID2"] = rand(11111,9999999);
$params["CURRENCYCODE"] = "USD";
$result = PaypalnvpComponent::MassPay($params);
//transaction detial
$params = array();
$params["TRANSACTIONID"] = TRANSACTIONID_HERE;
$result = PaypalnvpComponent::GetTransactionDetail($params);

no response from paypal api dodirectpayment nvp php

I am attempting to set up a paypal api using the dodirectpayment NVP which I have assembled some code from online resource but when I submit it I get no response whatsoever, just a white screen. I noticed my code doesn't have any echo in it, but I am not sure how to echo whatever response paypal sends. any assistance would be great. All the customer info and credentials are all from the sandbox. Thanks!
enter code here <?php
class Paypal {
/**
* Last error message(s)
* #var array
*/
protected $_errors = array();
/**
* API Credentials
* Use the correct credentials for the environment in use (Live / Sandbox)
* #var array
*/
protected $_credentials = array(
'USER' => 'centerfusiondesign-test_api1.gmail.com',
'PWD' => 'JBTYXGQHZY37RXGH',
'SIGNATURE' => 'ANRk81o3BhdjleyZOhWslseXywLQAfcftsn6e71ykaqxRzNASgC3NYUn',
);
/**
* API endpoint
* Live - https://api-3t.paypal.com/nvp
* Sandbox - https://api-3t.sandbox.paypal.com/nvp
* #var string
*/
protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';
/**
* API Version
* #var string
*/
protected $_version = ' 95.0';
/**
* Make API request
*
* #param string $method string API method to request
* #param array $params Additional request parameters
* #return array / boolean Response array / boolean false on failure
*/
public function request($method,$params = array()) {
$this -> _errors = array();
if( empty($method) ) { //Check if API method is not empty
$this -> _errors = array('API method is missing');
return false;
}
//Our request parameters
$requestParams = array(
'METHOD' => $method,
'VERSION' => $this -> _version
) + $this -> _credentials;
//Building our NVP string
$request = http_build_query($requestParams + $params);
//cURL settings
$curlOptions = array (
CURLOPT_URL => $this -> _endPoint,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', //CA cert file
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $request
);
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
//Sending our request - $response will hold the API response
$response = curl_exec($ch);
//Checking for cURL errors
if (curl_errno($ch)) {
$this -> _errors = curl_error($ch);
curl_close($ch);
return false;
//Handle errors
} else {
curl_close($ch);
$responseArray = array();
parse_str($response,$responseArray); // Break the NVP string to an array
return $responseArray;
}
}
}
$requestParams = array(
'IPADDRESS' => $_SERVER['REMOTE_ADDR'],
'PAYMENTACTION' => 'Sale'
);
$creditCardDetails = array(
'CREDITCARDTYPE' => 'Visa',
'ACCT' => '4032032109229382',
'EXPDATE' => '012020',
);
$payerDetails = array(
'FIRSTNAME' => 'John',
'LASTNAME' => 'Doe',
'COUNTRYCODE' => 'US',
'STATE' => 'NY',
'CITY' => 'New York',
'STREET' => '14 Argyle Rd.',
'ZIP' => '10010'
);
$orderParams = array(
'AMT' => '500',
'ITEMAMT' => '496',
'SHIPPINGAMT' => '4',
'CURRENCYCODE' => 'GBP'
);
$item = array(
'L_NAME0' => 'iPhone',
'L_DESC0' => 'White iPhone, 16GB',
'L_AMT0' => '496',
'L_QTY0' => '1'
);
$paypal = new Paypal();
$response = $paypal -> request('DoDirectPayment',
$requestParams + $creditCardDetails + $payerDetails + $orderParams + $item
);
if( is_array($response) && $response['ACK'] == 'Failure') { // Payment successful
// We'll fetch the transaction ID for internal bookkeeping
$transactionId = $response['TRANSACTIONID'];
}
?>
I am a little new to PHP so hopefully my error want be too stupid, Thanks!
You seemed to have CURL peer certificate verification enabled, which you might want to disable for testing purpose until you have it setup on server.
Replace:
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', //CA cert file
with:
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => FALSE,
Also, to check the response, just add
print_r($response);
below:
$response = $paypal -> request('DoDirectPayment',
$requestParams + $creditCardDetails + $payerDetails + $orderParams + $item
);
Let me help you have the complete code below:
<?php
class Paypal {
/**
* Last error message(s)
* #var array
*/
protected $_errors = array();
/**
* API Credentials
* Use the correct credentials for the environment in use (Live / Sandbox)
* #var array
*/
protected $_credentials = array(
'USER' => 'centerfusiondesign-test_api1.gmail.com',
'PWD' => 'JBTYXGQHZY37RXGH',
'SIGNATURE' => 'ANRk81o3BhdjleyZOhWslseXywLQAfcftsn6e71ykaqxRzNASgC3NYUn',
);
/**
* API endpoint
* Live - https://api-3t.paypal.com/nvp
* Sandbox - https://api-3t.sandbox.paypal.com/nvp
* #var string
*/
protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';
/**
* API Version
* #var string
*/
protected $_version = ' 95.0';
/**
* Make API request
*
* #param string $method string API method to request
* #param array $params Additional request parameters
* #return array / boolean Response array / boolean false on failure
*/
public function request($method,$params = array()) {
$this -> _errors = array();
if( empty($method) ) { //Check if API method is not empty
$this -> _errors = array('API method is missing');
return false;
}
//Our request parameters
$requestParams = array(
'METHOD' => $method,
'VERSION' => $this -> _version
) + $this -> _credentials;
//Building our NVP string
$request = http_build_query($requestParams + $params);
//cURL settings
$curlOptions = array (
CURLOPT_URL => $this -> _endPoint,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => FALSE,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $request
);
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
//Sending our request - $response will hold the API response
$response = curl_exec($ch);
//Checking for cURL errors
if (curl_errno($ch)) {
$this -> _errors = curl_error($ch);
curl_close($ch);
return false;
//Handle errors
} else {
curl_close($ch);
$responseArray = array();
parse_str($response,$responseArray); // Break the NVP string to an array
return $responseArray;
}
}
}
$requestParams = array(
'IPADDRESS' => $_SERVER['REMOTE_ADDR'],
'PAYMENTACTION' => 'Sale'
);
$creditCardDetails = array(
'CREDITCARDTYPE' => 'Visa',
'ACCT' => '4032032109229382',
'EXPDATE' => '012020',
);
$payerDetails = array(
'FIRSTNAME' => 'John',
'LASTNAME' => 'Doe',
'COUNTRYCODE' => 'US',
'STATE' => 'NY',
'CITY' => 'New York',
'STREET' => '14 Argyle Rd.',
'ZIP' => '10010'
);
$orderParams = array(
'AMT' => '500',
'ITEMAMT' => '496',
'SHIPPINGAMT' => '4',
'CURRENCYCODE' => 'GBP'
);
$item = array(
'L_NAME0' => 'iPhone',
'L_DESC0' => 'White iPhone, 16GB',
'L_AMT0' => '496',
'L_QTY0' => '1'
);
$paypal = new Paypal();
$response = $paypal -> request('DoDirectPayment',
$requestParams + $creditCardDetails + $payerDetails + $orderParams + $item
);
print_r($response);
if( is_array($response) && $response['ACK'] == 'Failure') { // Payment successful
// We'll fetch the transaction ID for internal bookkeeping
$transactionId = $response['TRANSACTIONID'];
}
?>
Also, you might want to upgrade your sandbox business account to Pro, as refered to this link:
https://stackoverflow.com/a/21926016/4410290
hope this helps.. :)
If you're getting a blank white screen that means there's a PHP error happening but you don't have error reporting enabled.
Add this to the very top of your script.
error_reporting(E_ALL);
ini_set('display_errors', '1');
Then run the script again and you should see the error(s).

How to use a variable as the amount for recurring payments (Paypal API)

I'm using the Paypal API to create a subscription system where there are two types of subscriptions
Monthly subscription (5dlls)
Annual subscription (50dlls)
I currently have the following code:
For setting the checkout:
public function do_purchase($type){
$this->load->library('paypal');
$requestParams = array(
'RETURNURL' => site_url('restaurant/get_purchase_details'),
'CANCELURL' => site_url('restaurant/afiliaturestaurante')
);
$orderParams = array(
'L_BILLINGTYPE0' => 'RecurringPayments',
'L_BILLINGAGREEMENTDESCRIPTION0' => 'Monthly',
'AMT' => 0
);
$paypal = new Paypal();
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams);
if(is_array($response) && $response['ACK'] == 'Success') { //Request successful
$token = $response['TOKEN'];
header( 'Location: https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=' . urlencode($token) );
}
}
For creating the recurring Paypal profile:
public function get_purchase_details(){
if( isset($_GET['token']) && !empty($_GET['token']) ) { // Token parameter exists
// Get checkout details, including buyer information.
// We can save it for future reference or cross-check with the data we have
$this->load->library('paypal');
$paypal = new Paypal();
$checkoutDetails = $paypal -> request('GetExpressCheckoutDetails', array('TOKEN' => $_GET['token']));
// Complete the checkout transaction
$requestParams = array(
'TOKEN' => $_GET['token'],
'PAYERID' => $checkoutDetails['PAYERID'],
'PROFILESTARTDATE' => '2014-03-7T05:38:48Z',
'DESC' => 'Monthly',
'BILLINGPERIOD' => 'Month',
'BILLINGFREQUENCY' => '1',
'AMT' => '5',
'CURRENCYCODE' => 'USD',
'COUNTRYCODE' => 'US',
'MAXFAILEDPAYMENTS' => '3',
);
$response = $paypal -> request('CreateRecurringPaymentsProfile',$requestParams);
if( is_array($response) && $response['ACK'] == 'Success') { // Payment successful
// We'll fetch the transaction ID for internal bookkeeping
$profileID = $response['PROFILEID'];
}
}
}
I need to use $type variable on get_purchase_details for setting the amount of the profile, how can I pass the variable through Paypal so I can user on the other function? I'm using a Paypal library for creating the cURL requests.
Thanks in advance
You could just set the value of $type in a session variable, and that would be available upon return from PayPal.
Alternatively, you could pass your $type value in the CUSTOM parameter of SetExpressCheckout and that way it'll be returned in the GetExpressCheckoutDetails response.

how to setup recurring payments in paypal

I'm trying to setup recurring payments in paypal with PHP. But the problem that I'm having is that I don't know if I'm doing the right thing. I have this class which makes the request to the Paypal API:
<?php
class Paypal {
protected $_errors = array();
protected $_credentials = array(
'USER' => 'my-user-id',
'PWD' => 'my-pass',
'SIGNATURE' => 'my-signature',
);
protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';
protected $_version = '74.0';
public function request($method,$params = array()) {
$this -> _errors = array();
if( empty($method) ) {
$this -> _errors = array('API method is missing');
return false;
}
$requestParams = array(
'METHOD' => $method,
'VERSION' => $this -> _version
) + $this -> _credentials;
$request = http_build_query($requestParams + $params);
$http_header = array(
'X-PAYPAL-SECURITY-USERID' => 'my-user-id',
'X-PAYPAL-SECURITY-PASSWORD' => 'my-pass',
'X-PAYPAL-SECURITY-SIGNATURE' => 'my-signature',
'X-PAYPAL-REQUEST-DATA-FORMAT' => 'JSON',
'X-PAYPAL-RESPONSE-DATA-FORMAT' => 'JSON'
);
$curlOptions = array (
CURLOPT_HTTPHEADER => $http_header,
CURLOPT_URL => $this -> _endPoint,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $request
);
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
$response = curl_exec($ch);
if (curl_errno($ch)) {
$this -> _errors = curl_error($ch);
curl_close($ch);
return false;
} else {
curl_close($ch);
$responseArray = array();
parse_str($response,$responseArray);
return $responseArray;
}
}
}
?>
Then I'm making the initial request like this:
session_start();
require_once('Paypal.php');
$paypal = new Paypal();
$amount = 1;
$requestParams = array(
'RETURNURL' => 'http://localhost/tester/paypal/new_test/test_done.php',
'CANCELURL' => 'http://localhost/tester/paypal/new_test/test_cancel.php',
'NOSHIPPING' => '1',
'ALLOWNOTE' => '1',
'L_BILLINGTYPE0' => 'RecurringPayments',
'L_BILLINGAGREEMENTDESCRIPTION0' => 'site donation'
);
$orderParams = array(
'PAYMENTREQUEST_0_AMT' => '1',
'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
'PAYMENTREQUEST_0_ITEMAMT' => $amount
);
$item = array(
'L_PAYMENTREQUEST_0_NAME0' => 'site donation',
'L_PAYMENTREQUEST_0_DESC0' => 'site donation',
'L_PAYMENTREQUEST_0_AMT0' => $amount,
'L_PAYMENTREQUEST_0_QTY0' => '1'
);
$response = $paypal->request('SetExpressCheckout', $requestParams + $orderParams + $item);
$sandbox_location = 'https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=';
if(is_array($response) && $response['ACK'] == 'Success'){
$token = $response['TOKEN'];
$_SESSION['token'] = $token;
header('Location: ' . $sandbox_location . urlencode($token));
}
?>
As you can see I'm using the SetExpressCheckout API method to get the token that I need and store it in a session so that I can use it later with the request for CreateRecurringPaymentsProfile.
I'm currently redirected to a page similar to this:
Once the user is done logging in with paypal and confirming the amount it redirects to the success page that I've specified which contains this code:
session_start();
require_once('Paypal.php');
$amount = 1;
$paypal = new Paypal();
$token_param = array('TOKEN' => $_SESSION['token']);
$current_date = date('Y-m-d');
$recurring_payment_params = array(
'PROFILESTARTDATE' => gmdate('Y-m-d H:i:s', strtotime($current_date . ' + 1 months')),
'DESC' => 'site donation',
'BILLINGPERIOD' => 'Month',
'BILLINGFREQUENCY' => '1',
'TOTALBILLINGCYCLES' => '0',
'AMT' => $amount
);
$recurringpayment_response = $paypal->request('CreateRecurringPaymentsProfile', $recurring_payment_params + $token_param);
This works, I've verified in the sandbox account that the recurring payment profile was created and that the next billing due is next month. But the problem is that its not really visible in the paypal interface (the screenshot earlier) that they're paying for a subscription. Perhaps I'm getting the redirect url wrong? (https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=) or do I have to add additional arguments to the SetExpressCheckout method? Please help.
You're only showing the login screen. After you login you'll see information about the subscription and the button will see "Agree and Pay" or "Agree and Continue" (depending on your useraction value in the return URL) instead of just "Pay" or "Continue".

Categories