I use Omnipay paypal library. I can make a successful payment but I have problems confirming the payment status. In the response I always get PAYMENTINFO_0_PAYMENTSTATUS => Pending
Here is my purchase code - I get redirected to paypal and it's all good here:
$gateway = Omnipay::create("PayPal_Express");
$gateway->setUsername( $this->USERNAME );
$gateway->setPassword( $this->PASSWORD );
$gateway->setSignature( $this->SIGNATURE );
$gateway->setTestMode(true);
$params = [
'cancelUrl'=>'http://xxxx.com/paypal_tests/cancel',
'returnUrl'=>'http://xxxx.com/paypal_tests/confirm_paypal',
'amount' => '10.00',
'currency' => 'EUR'
];
$response = $gateway->purchase( $params )->send();
$response->redirect();
And returnUrl, where in the response I always get [PAYMENTINFO_0_PAYMENTSTATUS] => Pending:
$gateway = Omnipay::create("PayPal_Express");
$gateway->setUsername( $this->USERNAME );
$gateway->setPassword( $this->PASSWORD );
$gateway->setSignature( $this->SIGNATURE );
$gateway->setTestMode(true);
$response = $gateway->completePurchase( $this->session->PAYPAL )->send();
$data = $response->getData(); // this is the raw response object
echo print_r($data);
Here is full response, as you can see status is "Pending".
Array
(
[TOKEN] => EC-1RA27631NJ550530P
[SUCCESSPAGEREDIRECTREQUESTED] => false
[TIMESTAMP] => 2016-03-07T10:29:43Z
[CORRELATIONID] => 8010f2af74b8
[ACK] => Success
[VERSION] => 119.0
[BUILD] => 18316154
[INSURANCEOPTIONSELECTED] => false
[SHIPPINGOPTIONISDEFAULT] => false
[PAYMENTINFO_0_TRANSACTIONID] => 97R504742X7344311
[PAYMENTINFO_0_TRANSACTIONTYPE] => expresscheckout
[PAYMENTINFO_0_PAYMENTTYPE] => instant
[PAYMENTINFO_0_ORDERTIME] => 2016-03-07T10:29:41Z
[PAYMENTINFO_0_AMT] => 1.44
[PAYMENTINFO_0_TAXAMT] => 0.00
[PAYMENTINFO_0_CURRENCYCODE] => EUR
[PAYMENTINFO_0_PAYMENTSTATUS] => Pending
[PAYMENTINFO_0_PENDINGREASON] => multicurrency
[PAYMENTINFO_0_REASONCODE] => None
[PAYMENTINFO_0_PROTECTIONELIGIBILITY] => Ineligible
[PAYMENTINFO_0_PROTECTIONELIGIBILITYTYPE] => None
[PAYMENTINFO_0_SECUREMERCHANTACCOUNTID] => Z6GHSVEW4KGWG
[PAYMENTINFO_0_ERRORCODE] => 0
[PAYMENTINFO_0_ACK] => Success
)
How to confirm that payment has been processed, confirmed and it is safe to dispatch?
Thanks!
OK, I found the problem, it is here:
[PAYMENTINFO_0_PENDINGREASON] => multicurrency
Basically my customer's test account was in US and seller's test account was charging in EUR, that's why it was pending....
And the answer is here: How do I use omnipay to check if it's a pending payment or not
Related
I am using cakephp2.0 framework. I am doing recurring payment. I am not getting the customer_id and other variables. And I also send the Recurring to Y.
Here is my code:
$paypalParams = array(
'paymentAction' => "Sale",
'amount' => $_POST['amount'],
'currencyCode' => "USD",
'creditCardType' => $_POST['card_type'],
'creditCardNumber' => trim(str_replace(" ","",$_POST['card_number'])),
'expMonth' => $_POST['expiry_month'],
'expYear' => $_POST['expiry_year'],
'cvv' => $_POST['cvv'],
'firstName' => $firstName,
'lastName' => $lastName,
'city' => $city,
'zip' => $zipcode,
'countryCode' => $countryCode,
'recurring' => 'Y',
'billingPeriod' => $session_details['paymentType'],
'billingFrequency' => "1",
'totalBillingCycles' => "0",
);
echo "<pre>"; print_r($paypalParams);
$response = $paypal->paypalCall($paypalParams);
When I call paypalCall function:
public function paypalCall($params){
/*
* Construct the request string that will be sent to PayPal.
* The variable $nvpstr contains all the variables and is a
* name value pair string with & as a delimiter
*/
$recurringStr = (array_key_exists("recurring",$params) && $params['recurring'] == 'Y')?'&RECURRING=Y':'';
$nvpstr = "&TOTALBILLINGCYCLES=".$params['totalBillingCycles']."&BILLINGFREQUENCY=".$params['billingFrequency']."&BILLINGPERIOD=".$params['billingPeriod']."&PAYMENTACTION=".$params['paymentAction']."&AMT=".$params['amount']."&CREDITCARDTYPE=".$params['creditCardType']."&ACCT=".$params['creditCardNumber']."&EXPDATE=".$params['expMonth'].$params['expYear']."&CVV2=".$params['cvv']."&FIRSTNAME=".$params['firstName']."&LASTNAME=".$params['lastName']."&CITY=".$params['city']."&ZIP=".$params['zip']."&COUNTRYCODE=".$params['countryCode']."&CURRENCYCODE=".$params['currencyCode'].$recurringStr;
//echo "<pre>"; print_r($nvpstr); die;
/* Make the API call to PayPal, using API signature.
The API response is stored in an associative array called $resArray */
$resArray = $this->hashCall("DoDirectPayment",$nvpstr);
echo "<pre>"; print_r($resArray); die;
return $resArray;
}
When I print this array($resArray) it gives only these parameters:
enter code here
<pre>Array
(
[TIMESTAMP] => 2016-12-29T09:05:26Z
[CORRELATIONID] => 42743fa743c6
[ACK] => Success
[VERSION] => 65.1
[BUILD] => 24616352
[AMT] => 19.99
[CURRENCYCODE] => USD
[AVSCODE] => X
[CVV2MATCH] => M
[TRANSACTIONID] => 9A3464215B244930U
)
There is no customerid(subscriber_id).
Could anyone help me to see what I am doing wrong?
I am using Laravel with Omnipay for our ecommerce application. We direct the customers to Paypal to make their purchase. We require shipping and billing information prior to placing an order and we would like that information to continue to Paypal to make it easier for them. However, only the first name and last name are crossing over to Paypal correctly. We can also use email with no issues.
public function postPayment() {
//var_dump(Session::get('shipping_info')); die;
$info = Session::get('shipping_info');
$gateway = Omnipay::gateway('paypal');
//sandbox
$gateway->setUsername('xxxx');
$gateway->setPassword('xxxx');
$gateway->setSignature('xxx');
$gateway->setTestMode('true');
//production
// $gateway->setUsername('xxxx');
// $gateway->setPassword('xxxx');
// $gateway->setSignature('xxxx');
$cardInput = array(
'firstName' => $info['first_name_bill'],
'lastName' => $info['last_name_bill'],
'billingAddress1' => $info['street_address_1_bill'],
'billingAddress2' => $info['street_address_2_bill'],
'billingPhone' => $info['phone_bill'],
'billingCity' => $info['city_bill'],
'billingState' => $info['state_bill'],
'billingPostCode' => $info['zip_bill'],
'shippingAddress1' => $info['street_address_1_ship'],
'shippingAddress2' => $info['street_address_2_ship'],
'shippingPhone' => $info['phone_ship'],
'shippingCity' => $info['city_ship'],
'shippingState' => $info['state_ship'],
'shippingPostCode' => $info['zip_ship'],
);
$card = Omnipay::creditCard($cardInput);
// var_dump($card); die;
$response = Omnipay::purchase(
array(
'cancelUrl' => 'http://localhost/public/',
'returnUrl' => 'http://localhost/public/',
'amount' => Input::get('total'),
'currency' => 'USD',
'card' => $card,
'description' => 'Stuff'
)
)->send();
$response->redirect();
}
According to the docs https://github.com/omnipay/omnipay it should work with no issues. dumping the sessions reveals the correct billing and shipping parameters.
It was just needing a cache refresh.
Here is the code I used
$max_amount = 20;
//$max_amount = $this->currency->convert($order_info['total'], $this->config->get('config_currency'), 'USD');
$max_amount = min($max_amount * 1.25, 10000);
$max_amount = $this->currency->format($max_amount, $this->currency->getCode(), '', false);
$max_amount = $max_amount*100;
$data = array(
'METHOD' => 'SetExpressCheckout',
'MAXAMT' => $max_amount,
'AMT' => 1000,
'RETURNURL' => $this->url->link('payment/pp_express/checkoutReturn', '', 'SSL'),
'CANCELURL' => $this->url->link('checkout/checkout', '', 'SSL'),
'REQCONFIRMSHIPPING' => 0,
'NOSHIPPING' => 1,
'LOCALECODE' => 'EN',
'LANDINGPAGE' => 'Login',
'HDRIMG' => $this->model_tool_image->resize($this->config->get('pp_express_logo'), 790, 90),
'HDRBORDERCOLOR' => $this->config->get('pp_express_border_colour'),
'HDRBACKCOLOR' => $this->config->get('pp_express_header_colour'),
'PAYFLOWCOLOR' => $this->config->get('pp_express_page_colour'),
'CHANNELTYPE' => 'Merchant',
'ALLOWNOTE' => $this->config->get('pp_express_allow_note'),
);
$data = array_merge($data, $this->model_payment_pp_express->paymentRequestInfo());
echo '<pre>';
$result = $this->model_payment_pp_express->call($data);
print_r($result);
The result of print_r($result) is
Array
(
[TIMESTAMP] => 2014-05-26T13:48:19Z
[CORRELATIONID] => d5ff8073cbde
[ACK] => Failure
[VERSION] => 65.2
[BUILD] => 11110362
[L_ERRORCODE0] => 10525
[L_SHORTMESSAGE0] => Invalid Data
[L_LONGMESSAGE0] => This transaction cannot be processed. The amount to be charged is zero.
[L_SEVERITYCODE0] => Error
)
Whether I have to round up the values?
You don't have the AMT parameter included in your request. As such, it's getting seen as a zero value which PayPal doesn't accept.
You need to add the AMT parameter and pass the current amount of the order at the time the SEC request is made. Of course, this amount could change between that time and the final DoExpressCheckoutPayment request, but you just need to make sure the final amount is not greater than the MAXAMT you're passing here.
Ok, I've bashed my head against the wall for two hours on making what I assumed was a simple call to PayPal over NVP. I've tried everything, but it keeps telling me that it didn't work out because of an internal error that doesn't tell me what I did wrong.
O' great and wise Internet Jedi's, please guide this wayward Padawan? Thanks in advance :)
(
[TIMESTAMP] => 2013-07-07T09:37:28Z
[CORRELATIONID] => f2e28b7dcf9fb
[ACK] => Failure
[VERSION] => 53.0
[BUILD] => 6680107
[L_ERRORCODE0] => 10001
[L_SHORTMESSAGE0] => Internal Error
[L_LONGMESSAGE0] => Internal Error
[L_SEVERITYCODE0] => Error
[AMT] => 232.15
[CURRENCYCODE] => USD
)
Here are the contents of the NVP call:
METHOD=DoDirectPayment
VERSION=53.0
PWD=1371372778
USER=xxx
SIGNATURE=xxx
PAYMENTACTION=Sale
IPADDRESS=xxx
AMT=232.15
CREDITCARDTYPE=VISA
ACCT=4111111111111111
EXPDATE=072016
FIRSTNAME=Harvey+Brooks
LASTNAME=-
STREET=3443+Padaro+Lane
CITY=Malibu
STATE=CA
COUNTRYCODE=US
CURRENCYCODE=USD
SHIPPINGAMT=0.00
CVV2=123
EMAIL=xxxx
PHONENUM=7022403735
SHIPTONAME=Some Dude
SHIPTOSTREET=90210+S+Bend
SHIPTOSTREET2=STE+120
SHIPTOCITY=Las+Vegas
SHIPTOSTATE=NV
SHIPTOCOUNTRYCODE=US
SHIPTOPHONENUM=xxx
L_NAME0=100+ANOS%C2%AE+
L_NUMBER0=19
L_QTY0=1
L_TAXAMT0=0
L_AMT0=29.69
L_NAME1=Chivas+Regal
L_NUMBER1=69
L_QTY1=2
L_TAXAMT1=0
L_AMT1=51.29
L_NAME2=Wild+Turkey
L_NUMBER2=34
L_QTY2=1
L_TAXAMT2=0
L_AMT2=29.69
L_NAME3=Patr%C3%B3n+Silver+
L_NUMBER3=23
L_QTY3=1
L_TAXAMT3=0
L_AMT3=70.19
ITEMAMT=232.15
TAXAMT=0
VISA
4066901366000455
cvv = 123
exp date = some future date
$version = urlencode('51.0');
Try these setting
$nvpStr ="&PAYMENTACTION=$paymentType&AMT=$amount&CREDITCARDTYPE=$creditCardType&ACCT=$creditCardNumber".
"&EXPDATE=$padDateMonth$expDateYear&CVV2=$cvv2Number&FIRSTNAME=$firstName&LASTNAME=$lastName".
"&STREET=$address1&CITY=$city&STATE=$state&ZIP=$zip&COUNTRYCODE=$country&CURRENCYCODE=$currencyID";
I am testing recurring payments. After doExpressCheckoutPayment action i recieved status Pending in my sandbox paypal account. Why status not completed? How much time need to set status Complete? Or maybe need set some params in sandbox. I am used default settings. Payment review - disabled.
Thanks!)
UPD 1:
Here is my request code:
public function setPayment($plan){
$params = array(
'PAYMENTREQUEST_0_AMT' => '10.00',
'RETURNURL' => $this->base_url.'/paypal/response',
'CANCELURL' => $this->base_url.'/paypal/paypal',
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Authorization',
'PAYMENTREQUEST_0_CURRENCYCODE' => 'GBP',
'PAYMENTREQUEST_0_DESC' => 'Testing PayPal recurring',
'PAYMENTREQUEST_0_NOTIFYURL' => 'http://barton.netai.net/ipn.php',
'L_BILLINGTYPE0' => 'RecurringPayments',
'L_BILLINGAGREEMENTDESCRIPTION0' => 'SamePayments'
);
$this->_paypal->addFields($params);
$response = $this->_paypal->request('SetExpressCheckout');
if (strtoupper($response['ACK'])=='SUCCESS'){
$token=$response['TOKEN'];
header('Location: '.$this->_paypal->getPaypalUrl().'?cmd=_express-checkout&token='.$token);
return true;
} else {
return false;
}
}
public function responseAction(){
if (isset($_GET['token']) && isset($_GET['PayerID'])){
$this->_paypal->addFields(array('TOKEN'=>$_GET['token']));
$response=$this->_paypal->request('GetExpressCheckoutDetails');
if ($response['ACK']=='Success'){
$response=array();
$this->_paypal->addFields(array(
'TOKEN' => $_GET['token'],
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Authorization',
'PAYERID' => $_GET['PayerID'],
'L_BILLINGTYPE0' => 'RecurringPayments',
'L_BILLINGAGREEMENTDESCRIPTION0' => 'SamePayments',
'PAYMENTREQUEST_0_AMT' => '10.00',
'PAYMENTREQUEST_0_CURRENCYCODE' => 'GBP'
));
$response=$this->_paypal->request('DoExpressCheckoutPayment');
show($response); exit;
}
}
}
SetExpressCheckout response:
Array
(
[TOKEN] => EC-01C99915Y11155245
[TIMESTAMP] => 2012-02-24T10:23:32Z
[CORRELATIONID] => 69e91a5abc347
[ACK] => Success
[VERSION] => 84
[BUILD] => 2571254
)
doExpressCheckoutPayment response:
Array
(
[TOKEN] => EC-2FR88291S31672645
[SUCCESSPAGEREDIRECTREQUESTED] => false
[TIMESTAMP] => 2012-02-24T10:26:08Z
[CORRELATIONID] => a95c7a9bb64b3
[ACK] => Success
[VERSION] => 84
[BUILD] => 2571254
[INSURANCEOPTIONSELECTED] => false
[SHIPPINGOPTIONISDEFAULT] => false
[PAYMENTINFO_0_TRANSACTIONID] => 2RN165632T770592L
[PAYMENTINFO_0_TRANSACTIONTYPE] => expresscheckout
[PAYMENTINFO_0_PAYMENTTYPE] => instant
[PAYMENTINFO_0_ORDERTIME] => 2012-02-24T10:26:06Z
[PAYMENTINFO_0_AMT] => 10.00
[PAYMENTINFO_0_TAXAMT] => 0.00
[PAYMENTINFO_0_CURRENCYCODE] => GBP
[PAYMENTINFO_0_PAYMENTSTATUS] => Pending
[PAYMENTINFO_0_PENDINGREASON] => authorization
[PAYMENTINFO_0_REASONCODE] => None
[PAYMENTINFO_0_PROTECTIONELIGIBILITY] => Eligible
[PAYMENTINFO_0_PROTECTIONELIGIBILITYTYPE] => ItemNotReceivedEligible,UnauthorizedPaymentEligible
[PAYMENTINFO_0_SECUREMERCHANTACCOUNTID] => WLC8CZSP2C5L8
[PAYMENTINFO_0_ERRORCODE] => 0
[PAYMENTINFO_0_ACK] => Success
)
In my previous question you advised me to install PAYMENTREQUEST_0_PAYMENTACTION to Sale,
Maybe this help me to decide this problem?
As mentioned in the other question, replace;
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Authorization',
by
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
When you set the PAYMENTREQUEST_0_PAYMENTACTION to 'Authorization' , means that you are asking PayPal to check whether the funds are available, and if they are, to place a hold on them for 72 hours. You have up to 29 days to capture an authorization, and when you do, the funds are on hold for three days only. The first 72 hours of the 29-day period are known as the "honor period", meaning that PayPal guarantees that the funds are available.
The three-day hold occurs in most cases, depending on the
card-issuing bank, or the bank itself in ACH transactions, such as a
debit card. In some cases, the three-day hold is waived, whereas in
other cases there may be a hold on the card for up to 30 days or
until the next billing cycle.
If you decide to capture the funds within the last three days of the
29-day period, those funds are held until the end of the 29th day
instead of the usual three days.
You can capture less than the original authorization amount, the full
amount, or up to 115% of or $75 more than the original authorization,
whichever is less.
And when you set the PAYMENTREQUEST_0_PAYMENTACTION to 'Sale' , the payment is processed without holding the funds. The funds are transferred from the buyer's funding source to your PayPal account balance immediately.
You would use the 'Sale' option for something that is delivered
quickly, such as digital goods or a product that ships as soon as you
receive the order.
The funds are immediately taken from the buyer's funding source and
sent to your PayPal account balance.