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).
Related
I'm working with srmk/paypal package 1.0.
Been working with this awesome package for some months in sandbox mode, yet I've been struggling to work with live mode.
I've been all over the issues others had and elsewhere and haven't been able to find a solution for this.
If I remove sandbox credentials I get an infinite loop right after dd($response) from $response = $provider->setExpressCheckout($checkoutData);
I'm using 1.0 so ExpressCheckout should not be the problem
I've tested on live server with same results.
My config
return [
'mode' => 'live', // Can only be 'sandbox' Or 'live'. If empty or invalid, 'live' will be used.
'sandbox' => [
'username' => env('PAYPAL_SANDBOX_API_USERNAME', ''),
'password' => env('PAYPAL_SANDBOX_API_PASSWORD', ''),
'secret' => env('PAYPAL_SANDBOX_API_SECRET', ''),
'certificate' => env('PAYPAL_SANDBOX_API_CERTIFICATE', ''),
'app_id' => 'APP-80W284485P519543T', // Used for testing Adaptive Payments API in sandbox mode
],
'live' => [
'username' => env('PAYPAL_LIVE_API_USERNAME', ''),
'password' => env('PAYPAL_LIVE_API_PASSWORD', ''),
'secret' => env('PAYPAL_LIVE_API_SECRET', ''),
'certificate' => env('PAYPAL_LIVE_API_CERTIFICATE', ''),
'app_id' => '', // Used for Adaptive Payments API
],
'payment_action' => 'Sale', // Can only be 'Sale', 'Authorization' or 'Order'
'currency' => env('PAYPAL_CURRENCY', 'MXN'),
'billing_type' => 'MerchantInitiatedBilling',
'notify_url' => '', // Change this accordingly for your application.
'locale' => env('PAYPAL_LOCALE', 'es_ES'), // force gateway language i.e. it_IT, es_ES, en_US ... (for express checkout only)
'validate_ssl' => false, // Validate SSL when creating api client.
];
env and env.example
#PayPal Setting & API Credentials - sandbox
PAYPAL_SANDBOX_API_USERNAME=sb-tr4z02598960_api1.business.example.com
PAYPAL_SANDBOX_API_PASSWORD=VSYUE32AU7MT7VY4
PAYPAL_SANDBOX_API_SECRET=ACdNh.ieqXXfGzIFBkj6F-fUdA49AIBmvpyOyz5MhLCsLyQVdcB74zVJ
PAYPAL_SANDBOX_API_CERTIFICATE=
#PayPal Setting & API Credentials - live
PAYPAL_LIVE_API_USERNAME=********************api1.gmail.com
PAYPAL_LIVE_API_PASSWORD=**********************K9W
PAYPAL_LIVE_API_SECRET=******************************FCBABE
PAYPAL_LIVE_API_CERTIFICATE= storage_path('cert_key_pem.txt'); // also tested empty
I use the new API credentials provided by PayPal
public function getExpressCheckout ($orderId) {
$checkoutData = $this->checkoutData($orderId);
$provider = new ExpressCheckout();
$response = $provider->setExpressCheckout($checkoutData);
dd($response);
return redirect($response['paypal_link']);
}
private function checkoutData($orderId)
{
$cart = \Cart::getContent();
$cart2 = \Cart::getTotal();
$cartItems = array_map( function($item){
return [
'name' => $item['name'],
'price' => $item['price'],
'qty' => $item['quantity']
];
}, $cart->toarray());
$checkoutData = [
'items' => $cartItems,
'return_url' => route('paypal.success', $orderId),
'cancel_url' => route('paypal.cancel'),
'invoice_id' => uniqid(),
'invoice_description' => 'order description',
'total' => $cart2
];
return $checkoutData;
}
public function getExpressCheckoutSuccess(Request $request, $orderId)
{
$token = $request->get('token');
$payerId = $request->get('PayerID');
$provider = new ExpressCheckout();
$checkoutData = $this->checkoutData($orderId);
$response = $provider->getExpressCheckoutDetails($token);
if (in_array(strtoupper($response['ACK']),['SUCCESS','SUCCESSWITHWARNING'])) {
$payment_status = $provider->doExpressCheckoutPayment($checkoutData,$token,$payerId);
$status = $payment_status['PAYMENTINFO_0_PAYMENTSTATUS'];
if (in_array($status, ['Completed','Processed'])) {
$order = Order::find($orderId);
$order->is_paid = 1;
$order->save();
Mail::to($order->buyer_email)->send(new OrderMail($order));
\Cart::clear();
return view ('newOrder.success', compact('order'));
}
The infinite loop pops when calling this function from the package
private function doPayPalRequest($method)
{
// Setup PayPal API Request Payload
$this->createRequestPayload($method);
try {
// Perform PayPal HTTP API request.
$response = $this->makeHttpRequest();
// dd($response); // I'm stuck here
return $this->retrieveData($method, $response);
} catch (Throwable $t) {
$message = collect($t->getTrace())->implode('\n');
}
return [
'type' => 'error',
'message' => $message,
];
}
Thanks all,
I am working from a php form to send data to a CRM to collect data and put it in the correct spot on the CRM to notify the correct division in the company. Someone else wrote the API to collect the information and they supplied me with the SOAP URL. They supplied me with sample XML that has been shown to work in SOAPUI to give the correct GUID response back.
I have coded the PHP to collect the data from the form, put it in the same xml code that was used to test the API in SOAP API. I am having a hard time getting the proper submit code. My issue is similar to the page here: How do I send XML data to an API via SOAP in PHP?. However using the $client->Submit gives me an error saying this is not a function.
So I went back to the SOAP 1.2 specs and have tried __soapCall(function(array)).
I get nothing back in response. I have tried a couple of other things but this seems like it should work.
Example of xml to send:
<soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:header>
<soapenv:body>
<tem:addnewlead>
<!--Optional-->
<tem:firstname>test</tem:firstname>
<!--Optional-->
<tem:lastname>test2</tem:lastname>
<!--Optional-->
<tem:emailaddress>test#test.com</tem:emailaddress>
<!--Optional-->
<tem:mainphone>555-555-5555</tem:mainphone>
<!--Optional-->
<tem:companyname>testtest</tem:companyname>
<!--Optional-->
<tem:interest>testtesttest</tem:interest>
<!--Optional-->
<tem:requesttype>test</tem:requesttype>
<!--Optional-->
<tem:requestdetails>testtesttest</tem:requestdetails>
</tem:addnewlead>
</soapenv:body>
</soapenv:header>
</soapenv:envelope>
This is the php with the code to form the xml removed for brevity as I know this works, using the xml above to send which matches the previous coder's testing in SOAPUI:
<?php
$URL = 'http://zzzzzzzz.com/APIService.svc';
$send = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>
<soapenv:Header/>
<soapenv:Body>
<tem:ADDNEWLEAD>
<!--Optional-->
<tem:FirstName>test</tem:FirstName>
<!--Optional-->
<tem:LastName>test2</tem:LastName>
<!--Optional-->
<tem:emailAddress>test#test.com</tem:emailAddress>
<!--Optional-->
<tem:MainPhone>555-555-5555</tem:MainPhone>
<!--Optional-->
<tem:CompanyName>testtest</tem:CompanyName>
<!--Optional-->
<tem:Interest>testtesttest</tem:Interest>
<!--Optional-->
<tem:RequestType>test</tem:RequestType>
<!--Optional-->
<tem:RequestDetails>testtesttest</tem:RequestDetails>
</tem:ADDNEWLEAD>
</soapenv:Body>
</soapenv:Envelope>";
print_r($send);
try {
$client = new SoapClient("http://zzzzzzzz.com/APIService.svc?WSDL",array(
'location' => $URL,
'uri' => "http://zzzzzzz.com/",
'trace' => 1,
'exceptions' => true
));
$return = $client->__soapCall(array('ADDNEWLEAD' => $send));
$functions = $client->__getFunctions();
// Some other code that I thought I would try as I am not the best SOAP API writer as you can tell by now.
// $return = $client->__soapCall(array(DoWork $xml, ADDNEWLEAD $send));
// $return = $client->DoWork(ADDNEWLEAD($send));
// $return = $client->__soapCall('DoWork',array('DoWork' => null,'ADDNEWLEAD' => $send));
echo '<pre>'; //show response on screen
echo '<br>-';
print_r($functions);
echo '<br>+';
print_r($return);
echo '</pre>';
} catch(SoapFault $e) {
echo '<h3>Exception</h3>';
echo '<pre>';
print_r($e);
echo '</pre>';
}
die(); ?>
I get:
Array
(
[0] => DoWorkResponse DoWork(DoWork $parameters)
[1] => ADDNEWLEADResponse ADDNEWLEAD(ADDNEWLEAD $parameters)
)
stdClass Object (
[ADDNEWLEADResult] => )
Where it is black, I should be getting a confirmation code from the API.
Any help appreciated.
Thank you.
I have also received this xml response as well when the submission did not work:
/**
* Class GF_Services_API
*
* Accesses the API for Service Request data
*
* #since 1.0.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
ini_set('default_socket_timeout', 120);
class GF_Services_API {
/**
* #var GF_Services_API $endpoint The Endpoint that we ping for data
* #since 1.0.0
*/
private $endpoint = 'http://xxxxxxxxxxxxxxxx/Alpha.svc?wsdl';
/**
* GF_Services_API constructor.
*
* #since 1.0.0
*/
function __construct() {
}
/**
* I guess this is marginally easier than using Capture Groups in Regex...?
* Maybe it is more efficient, don't feel like running a benchmark. This is how it was to begin with.
*
* #param string $haystack Input to Search
* #param string $start Opening Tag
* #param string $end Closing Tag
*
* #access private
* #since 1.0.0
* #return string String between the opening and closing Tag
*/
private function substring_between( $haystack, $start, $end ) {
if ( strpos( $haystack, $start ) === false ||
strpos( $haystack, $end ) === false) {
return false;
}
else {
$start_position = strpos( $haystack, $start ) + strlen( $start );
$end_position = strpos( $haystack, $end );
return substr( $haystack, $start_position, $end_position - $start_position );
}
}
/**
* Grab Information from the API using a Ticket Number
*
* #param string $ticket_number Ticket Number
*
* #access public
* #since 1.0.0
* #return array API Data for the Ticket Number
*/
public function get_information_by_ticket_number( $ticket_number = '' ) {
$return_array = array();
if ( $ticket_number != '' ) {
try {
$wsdl = $this->endpoint;
// options for OpenSSL in php 5.6.5
$opts = array(
'ssl' => array(
'ciphers' => 'RC4-SHA',
'verify_peer' => false,
'verify_peer_name' => false
)
);
// SOAP 1.2 client
$params = array(
'encoding' => 'UTF-8',
'verifypeer' => false,
'verifyhost' => false,
//'soap_version' => SOAP_1_2, SOAP v1.2 doesn't support text/html which we need
'trace' => 1,
'exceptions' => 1,
'connection_timeout' => 180,
'stream_context' => stream_context_create( $opts )
);
$cliente = new SoapClient( $wsdl, $params );
$data = array(
"TicketNo" => $ticket_number,
"Key1" => '76xxxxxxxxxxxxxx94',
"Key2" => '6x-xxxxxxxxxxxxxxx4xxxxxxxxxxxxx16'
);
$result = $cliente->__call( 'CheckServiceTicket', array( $data ) );
$result_data = $result->CheckServiceTicketResult->any;
$return_array['serial_number'] = $this->substring_between( $result_data, '<serial_no>', '</serial_no>' );
$return_array['descr'] = $this->substring_between( $result_data, '<descr>', '</descr>' );
$return_array['contract_id'] = $this->substring_between( $result_data, '<Contract_ID>', '</Contract_ID>' );
$return_array['contract_status'] = $this->substring_between( $result_data, '<Contract_Status>', '</Contract_Status>' );
$return_array['contract_expiry_date'] = $this->substring_between( $result_data, '<Contract_Expiry_date>', '</Contract_Expiry_date>' );
$return_array['address_1'] = $this->substring_between( $result_data, '<address_1>','</address_1>');
$return_array['address_2'] = $this->substring_between( $result_data, '<address_2>', '</address_2>' );
$return_array['address_3'] = $this->substring_between( $result_data, '<address_3>', '</address_3>' );
$return_array['city'] = $this->substring_between( $result_data, '<city>', '</city>' );
$return_array['state'] = $this->substring_between( $result_data, '<state>', '</state>' );
$return_array['zip'] = $this->substring_between( $result_data, '<zip>', '</zip>' );
$return_array['country'] = $this->substring_between( $result_data, '<country>', '</country>' );
$return_array['company_name'] = $this->substring_between( $result_data, '<Company_Name>', '</Company_Name>' );
$return_array['device_type'] = $this->substring_between( $result_data, '<Device_Type>', '</Device_Type>' );
$return_array['state'] = $this->get_us_state_name( $return_array['state'] );
$return_array['contract_expiry_date'] = date( "F d, Y", strtotime( $return_array['contract_expiry_date'] ) );
}
catch ( Exception $e ) {
echo "Error: " . $e->getMessage();
}
}
return $return_array;
}
/**
* Gets an Array of Service Requests Information (Including Status) via an Email Address
*
* #param string $email Email Address
*
* #access public
* #since 1.0.0
* #return array Array of Service Request Info
*/
public function get_information_by_email_address( $email = '' ) {
$return_array = array();
if ( $email != '' ) {
try {
$wsdl = $this->endpoint;
// options for OpenSSL in php 5.6.5
$opts = array(
'ssl' => array(
'ciphers' => 'RC4-SHA',
'verify_peer' => false,
'verify_peer_name' => false
)
);
// SOAP 1.2 client
$params = array(
'encoding' => 'UTF-8',
'verifypeer' => false,
'verifyhost' => false,
//'soap_version' => SOAP_1_2, SOAP v1.2 doesn't support text/html which we need
'trace' => 1,
'exceptions' => 1,
'connection_timeout' => 180,
'stream_context' => stream_context_create( $opts )
);
$client = new SoapClient( $wsdl, $params );
$data = array(
"Email" => $email,
"Key1" => '7x',
xxxxxxxxxxxxxxxxxxxxxxxxxxx
"Key2" => '6xxxxxxxxxxxxxxxxxxxxxx'
);
$result = $client->__call( 'QueryTicketInfo', array( $data ) );
$xml = $result->QueryTicketInfoResult->any;
// Remove namespaces
$xml = str_replace( array( "diffgr:", "msdata:" ), '', $xml );
$xml = "<package>" . $xml . "</package>";
$data = simplexml_load_string( $xml );
$tickets = $data->diffgram->DocumentElement->WS0002;
foreach ( $tickets as $ticket ) {
$_result = array();
$_result['Opened'] = (string) $ticket->Opened;
$_result['LastAction'] = (string) $ticket->LastAction;
$_result['Enteredby'] = (string) $ticket->Enteredby;
$_result['TicketNumber'] = (string) $ticket->TicketNumber;
$_result['ProblemDescription'] = (string) $ticket->ProblemDescription;
$_result['CurrentStatus'] = (string) $ticket->CurrentStatus;
$_result['CustomerName'] = (string) $ticket->CustomerName;
$_result['CalledInBy'] = (string) $ticket->CalledInBy;
$_result['Email'] = (string) $ticket->Email;
$_result['ServiceAgent'] = (string) $ticket->ServiceAgent;
$_result['PartNumber'] = (string) $ticket->PartNumber;
$_result['PartDescription'] = (string) $ticket->PartDescription;
$_result['SerialNumber'] = (string) $ticket->SerialNumber;
$_result['City'] = (string) $ticket->City;
$_result['State'] = (string) $ticket->State;
$_result['LastActivity'] = (string) $ticket->LastActivity;
$_result['DO'] = (string) $ticket->DO;
$return_array[] = $_result;
}
}
catch ( Exception $e ) {
echo "Error: " . $e->getMessage();
}
}
return $return_array;
}
}
You shouldn't need to work with XML directly when using the PHP SoapClient. Build a PHP request object:
$addNewLeadRequest = new \stdClass();
$addNewLeadRequest->FirstName = 'test';
$addNewLeadRequest->LastName = 'test2';
$addNewLeadRequest->emailAddress = 'test#test.com';
$addNewLeadRequest->MainPhone = '555-555-5555';
$addNewLeadRequest->CompanyName = 'testtest';
$addNewLeadRequest->Interest = 'testtesttest';
$addNewLeadRequest->RequestType = 'test';
$addNewLeadRequest->RequestDetails = 'testtesttest';
Then just pass it to the method on the client:
$addNewLeadResponse = $client->ADDNEWLEAD($addNewLeadRequest);
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);
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".
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.