/** * Contact the PayPal servers in order to verify the payment * @param jmsPaymentMethodData $data */ private function verifyApproval(jmsPaymentMethodData $data) { $expressCheckoutDetailsRequest = PayPal::getType('GetExpressCheckoutDetailsRequestType'); $expressCheckoutDetailsRequest->setToken($data->getValue('express_token')); $response = $this->getCallerServices()->GetExpressCheckoutDetails($expressCheckoutDetailsRequest); if (Pear::isError($response)) { throw new jmsPaymentCommunicationException('Error while fetching express checkout details: ' . $response->getMessage()); } if ($response->Ack !== 'Success') { throw new jmsPaymentCommunicationException('Express checkout details could not be retrieved: ' . $response->Ack); } $details = $response->getGetExpressCheckoutDetailsResponseDetails(); $buyerInfo = $details->getPayerInfo(); if ($this->verifiedAccountRequired() && $buyerInfo->PayerStatus !== 'verified') { throw new jmsPaymentUnverifiedBuyerException('This PayPal account is not verified.'); } $data->setValue('payer_id', $buyerInfo->PayerID); $basicAmount = PayPal::getType('BasicAmountType'); $basicAmount->setattr('currencyID', $data->getCurrency()); $basicAmount->setval(number_format($data->getAmount(), 2)); $paymentDetails = PayPal::getType('PaymentDetailsType'); $paymentDetails->setOrderTotal($basicAmount); $paymentDetails->setOrderDescription($data->subject); $request = PayPal::getType('DoExpressCheckoutPaymentRequestDetailsType'); $request->setToken($data->getValue('express_token')); $request->setPayerID($buyerInfo->PayerID); $request->setPaymentAction('Order'); $request->setPaymentDetails($paymentDetails); $doExpressCheckoutPaymentRequest = PayPal::getType('DoExpressCheckoutPaymentRequestType'); $doExpressCheckoutPaymentRequest->setVersion(self::API_VERSION); $doExpressCheckoutPaymentRequest->setDoExpressCheckoutPaymentRequestDetails($request); $response = $this->getCallerServices()->DoExpressCheckoutPayment($doExpressCheckoutPaymentRequest); if (Pear::isError($response)) { $reasonCode = $response->getMessage(); $data->setReasonCode($reasonCode); $e = new jmsPaymentCommunicationException('Error while authorizing express checkout payment: ' . $reasonCode); $e->setPaymentMethodData($data); throw $e; } if ($response->Ack !== 'Success') { $reasonCode = $this->extractErrors($response->Errors); $data->setReasonCode($reasonCode); $data->setResponseCode($response->Ack); $e = new jmsPaymentException('Payment could not be authorized: ' . $reasonCode); $e->setPaymentMethodData($data); throw $e; } $details = $response->getDoExpressCheckoutPaymentResponseDetails(); $paymentInfo = $details->getPaymentInfo(); $data->setValue('external_reference_number', $paymentInfo->TransactionID); $data->setProcessedAmount($data->getAmount()); }
/** * Deposits a transaction. This method is not intended to call any * api belonging to 4b system as this api does not exist. The first * action for depositing has to be a POST submission to an URL outside * of the online shop pages where the purchaser has to fill payment info. * When this is done 4b server calls in return online shop url. * You have to connect that url with this method. * You can inform 4b about the url that leads to this method in the * field labeled: "URL que graba el resultado en la BD del comercio" * https://tpv.4b.es/config * * @see plugins/jmsPaymentPlugin/lib/method/jmsPaymentMethod#deposit($data, $retry) */ public function deposit(jmsPaymentMethodData $data, $retry = false) { //If this is not called from 4b systems we want to launch a user interaction exception //Check call originated from 4b simulation or production servers. $caller_address = sfContext::getInstance()->getRequest()->getRemoteAddress(); //This call is far from the paymentDemo sfAction //to not taint the 'general' logic implemented there. $production_ip = $this->getProductionIp(); $simulation_ip = $this->getSimulationIp(); //This block is going to be executed when call is from 'shop' pages and //4b pages to be filled by the user are going to be shown as result. if ($caller_address != $production_ip && $caller_address != $simulation_ip) { //call to deposit not from 4b servers $production_url = $this->getProductionUrl(); $simulation_url = $this->getSimulationUrl(); $_4b_conection_url = !$this->isDebug() ? $production_url : $simulation_url; // throw $exception = new jmsPaymentUserActionRequiredException(new jmsPaymentUserActionVisitURL($_4b_conection_url)); $data->setValue('transaction_from_ip', $caller_address); $exception->setPaymentMethodData($data); throw $exception; } //This block is going to be executed when call is from 4b server $amount_value = $data->getAmount(); if ($data->getValue('transaction_result') == 1) { //Success $data->setResponseCode($data->getValue('transaction_id')); $data->setReasonCode('Approval with 4b approval code: ' . $data->getValue('transaction_approval_code')); $data->setProcessedAmount($amount_value); //Processed amount equals requested. } else { //Failed $data->setResponseCode($data->getValue('transaction_error_code')); $data->setReasonCode($data->getValue('transaction_error_description')); $e = new jmsPaymentException('Payment could not be completed. Reason: ' . $data->getReasonCode()); $e->setPaymentMethodData($data); throw $e; } }