3namespace Sale\Handlers\PaySystem;
5use Bitrix\Main\Request;
6use Bitrix\Main\Type\DateTime;
7use Bitrix\Main\Type\Date;
8use Bitrix\Sale\Payment;
9use Bitrix\Sale\PaySystem;
10use Bitrix\Main\Application;
11use Bitrix\Main\Localization\Loc;
12use Bitrix\Main\Web\HttpClient;
13use Bitrix\Sale\PriceMaths;
14use Bitrix\Sale\Registry;
16Loc::loadMessages(__FILE__);
26 const DELIMITER_PAYMENT_ID =
':';
28 private $prePaymentSetting =
array();
35 return array(
'mc_gross',
'mc_currency');
43 protected static function isMyResponseExtended(Request
$request, $paySystemId)
45 $data = PaySystem\Manager::getById($paySystemId);
48 return self::getRegistryType(
$request) ===
$data[
'ENTITY_REGISTRY_TYPE'];
58 private static function getRegistryType(Request
$request)
61 if (
$request->get(
'custom') !==
null)
63 $paymentId =
$request->get(
'custom');
66 if ($paymentId ===
null)
71 $pos = mb_strpos($paymentId, static::DELIMITER_PAYMENT_ID);
74 return mb_substr($paymentId, 0, $pos);
77 return Registry::REGISTRY_TYPE_ORDER;
88 $serviceResult =
new PaySystem\ServiceResult();
99 elseif (
$request->get(
'txn_id') && $server->getRequestMethod() ==
"POST")
101 $req = $this->getIpnRequest(
$request);
109 $domain =
"sandbox.";
111 $host =
"www.".$domain.
"paypal.com";
113 $header =
"POST /cgi-bin/webscr HTTP/1.1\r\n";
114 $header .=
"Host: ".$host.
"\r\n";
115 $header .=
"Content-Type: application/x-www-form-urlencoded\r\n";
116 $header .=
"Content-Length: ".mb_strlen($req).
"\r\n";
117 $header .=
"User-Agent: 1C-Bitrix\r\n";
118 $header .=
"Connection: Close\r\n\r\n";
122 $fp = fsockopen(
"ssl://".
$host, 443, $errNo, $errStr, 30);
126 $fp = fsockopen(
$host, 80, $errNo, $errStr, 30);
131 PaySystem\Logger::addDebugInfo(
'PayPal: request: '.$header.$req);
133 fputs ($fp, $header.$req);
138 $line = fgets ($fp, 1024);
139 if (strcmp($line,
"\r\n") == 0)
149 PaySystem\Logger::addDebugInfo(
'PayPal: response: '.
$response);
154 if (strcmp($lines[1],
"SUCCESS") == 0)
164 $serviceResult->setData(
array(
'MESSAGE' => Loc::getMessage(
"SALE_HPS_PAYPAL_I1")));
169 $serviceResult->setData(
170 array(
'MESSAGE' => Loc::getMessage(
"SALE_HPS_PAYPAL_I3").
'<br /><br />'.Loc::getMessage(
"SALE_HPS_PAYPAL_I4"))
175 return $serviceResult;
184 protected function processSuccessAction(Payment
$payment, Request
$request, $lines)
186 $serviceResult =
new PaySystem\ServiceResult();
193 $keys[urldecode(
$key)] = urldecode(
$val);
196 $psStatusMessage =
'Name: '.$keys[
'first_name'].
' '.$keys[
'last_name'].
'; ';
197 $psStatusMessage .=
'Email: '.$keys[
'payer_email'].
'; ';
198 $psStatusMessage .=
'Item: '.$keys[
'item_name'].
'; ';
199 $psStatusMessage .=
'Amount: '.$keys[
'mc_gross'].
'; ';
201 $psStatusDescription =
'Payment status - '.$keys[
'payment_status'].
'; ';
202 $psStatusDescription .=
'Payment sate - '.$keys[
'payment_date'].
'; ';
206 "PS_STATUS_CODE" =>
"-",
207 "PS_STATUS_DESCRIPTION" => $psStatusDescription,
208 "PS_STATUS_MESSAGE" => $psStatusMessage,
209 "PS_SUM" => $keys[
"mc_gross"],
210 "PS_CURRENCY" => $keys[
"mc_currency"],
211 "PS_RESPONSE_DATE" =>
new DateTime(),
212 "PAY_VOUCHER_NUM" =>
$request->get(
'tx'),
213 "PAY_VOUCHER_DATE" =>
new Date()
216 $serviceResult->setPsData(
$fields);
220 $payPalSum = (float)$keys[
"mc_gross"];
223 $payPalSum -= (float)$keys[
"tax"];
225 $payPalSum = PriceMaths::roundPrecision($payPalSum);
227 PaySystem\Logger::addDebugInfo(
'PayPal: payPalSum='.$payPalSum.
"; paymentSum=".$paymentSum);
229 if ($paymentSum == $payPalSum
231 && $keys[
"payment_status"] ==
"Completed"
234 $serviceResult->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
237 $response =
'<p><h3>'.Loc::getMessage(
'SALE_HPS_PAYPAL_T1').
'</h3></p>';
238 $response .=
'<b>'.Loc::getMessage(
'SALE_HPS_PAYPAL_T2').
'</b><br>';
239 $response .=
'<li>'.Loc::getMessage(
'SALE_HPS_PAYPAL_T3').
': '.$keys[
'first_name'].
' '.$keys[
'last_name'].
'</li>';
240 $response .=
'<li>'.Loc::getMessage(
'SALE_HPS_PAYPAL_T4').
': '.$keys[
'item_name'].
'</li>';
241 $response .=
'<li>'.Loc::getMessage(
'SALE_HPS_PAYPAL_T5').
': '.$keys[
'mc_gross'].
'</li>';
245 return $serviceResult;
253 protected function processVerifiedAction(Payment
$payment, Request
$request)
255 $serviceResult =
new PaySystem\ServiceResult();
257 $psStatusMessage = Loc::getMessage(
"SALE_HPS_PAYPAL_T3").
": ".
$request->get(
"first_name").
" ".
$request->get(
"last_name").
"; ";
258 $psStatusMessage .=
"Email: ".$request->get(
"payer_email").
"; ";
259 $psStatusMessage .= Loc::getMessage(
"SALE_HPS_PAYPAL_T4").
": ".$_POST[
"item_name"].
"; ";
260 $psStatusMessage .= Loc::getMessage(
"SALE_HPS_PAYPAL_T5").
": ".$_POST[
"mc_gross"].
"; ";
262 $psStatusDescription =
"Payment status - ".$request->get(
"payment_status").
"; ";
263 $psStatusDescription .=
"Payment sate - ".$request->get(
"payment_date").
"; ";
267 "PS_STATUS_CODE" =>
"-",
268 "PS_STATUS_DESCRIPTION" => $psStatusDescription,
269 "PS_STATUS_MESSAGE" => $psStatusMessage,
270 "PS_SUM" =>
$request->get(
"mc_gross"),
271 "PS_CURRENCY" =>
$request->get(
"mc_currency"),
272 "PS_RESPONSE_DATE" =>
new DateTime(),
273 "PAY_VOUCHER_NUM" =>
$request->get(
'txn_id'),
274 "PAY_VOUCHER_DATE" =>
new Date()
277 $serviceResult->setPsData(
$fields);
281 $payPalSum = (float)
$request->get(
"mc_gross");
284 $payPalSum -= (float)
$request->get(
'tax');
286 $payPalSum = PriceMaths::roundPrecision($payPalSum);
288 PaySystem\Logger::addDebugInfo(
'PayPal: payPalSum='.$payPalSum.
"; paymentSum=".$paymentSum);
290 if ($paymentSum == $payPalSum
292 &&
$request->get(
"payment_status") ==
"Completed"
296 $serviceResult->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
299 return $serviceResult;
312 $req =
'cmd=_notify-synch';
323 protected function getIpnRequest(Request
$request)
325 $req =
'cmd=_notify-validate';
327 foreach ($_POST as
$key => $value)
329 $req .=
'&'.$key.
'='.urlencode(stripslashes($value));
342 self::TEST_URL =>
'https://www.sandbox.paypal.com/cgi-bin/webscr',
343 self::ACTIVE_URL =>
'https://www.paypal.com/cgi-bin/webscr'
357 'PAYPAL_RETURN' => $this->getReturnUrl(
$payment),
358 'PAYED' =>
$payment->isPaid() ?
'Y' :
'N',
368 public function getParamsBusValue(Payment
$payment =
null)
374 $registryType = $payment::getRegistryType();
375 $params[
'PAYMENT_ID'] = $registryType.static::DELIMITER_PAYMENT_ID.$params[
'PAYMENT_ID'];
387 return array(
'RUB',
'EUR',
'USD');
394 public function getPaymentIdFromRequest(Request
$request)
397 if (
$request->get(
'custom') !==
null)
399 $paymentId =
$request->get(
'custom');
402 if ($paymentId ===
null)
407 $pos = mb_strpos($paymentId, static::DELIMITER_PAYMENT_ID);
410 return mb_substr($paymentId, $pos + 1);
420 protected function isTestMode(Payment
$payment =
null)
430 public function sendResponse(PaySystem\ServiceResult
$result, Request
$request)
434 if (isset(
$data[
'MESSAGE']))
436 echo
$data[
'MESSAGE'];
449 $this->prePaymentSetting =
array(
454 'TEST' => $this->isTestMode(
$payment),
456 'ENCODING' => $this->service->getField(
'ENCODING')
459 if (!$this->prePaymentSetting[
'CURRENCY'])
461 $this->prePaymentSetting[
'CURRENCY'] = \CSaleLang::GetLangCurrency(
SITE_ID);
464 if ($this->prePaymentSetting[
'TEST'])
466 $this->prePaymentSetting[
'DOMAIN'] =
"sandbox.";
471 $this->prePaymentSetting[
'TOKEN'] =
$request->get(
"token");
476 $this->prePaymentSetting[
'PayerID'] =
$request->get(
"PayerID");
479 $this->prePaymentSetting[
'VERSION'] =
"98.0";
481 $dbSite = \CSite::GetByID(
SITE_ID);
482 $arSite = $dbSite->Fetch();
484 $this->prePaymentSetting[
'SERVER_NAME'] = $arSite[
"SERVER_NAME"];
485 if ($this->prePaymentSetting[
'SERVER_NAME'])
487 if (defined(
"SITE_SERVER_NAME") && SITE_SERVER_NAME <>
'')
489 $this->prePaymentSetting[
'SERVER_NAME'] = SITE_SERVER_NAME;
493 $this->prePaymentSetting[
'SERVER_NAME'] = \COption::GetOptionString(
"main",
"server_name");
497 $this->prePaymentSetting[
'SERVER_NAME'] = (\CMain::IsHTTPS() ?
"https" :
"http").
"://".$this->prePaymentSetting[
'SERVER_NAME'];
499 if(!$this->prePaymentSetting[
'USER'])
501 $GLOBALS[
"APPLICATION"]->ThrowException(
"CSalePaySystempaypal: init error",
"CSalePaySystempaypal_init_error");
512 protected function parsePrePaymentResult(
$data)
517 $res1 = explode(
"&",
$data);
518 foreach ($res1 as $res2)
520 list(
$key,
$val) = explode(
"=", $res2);
521 $keyArray[urldecode(
$key)] = urldecode(
$val);
522 if ($this->prePaymentSetting[
'ENCODING'])
524 $keyArray[urldecode(
$key)] = \Bitrix\Main\Text\Encoding::convertEncoding($keyArray[urldecode(
$key)], $this->prePaymentSetting[
'ENCODING'],
SITE_CHARSET);
538 if ($this->prePaymentSetting[
'TOKEN'])
540 $url =
"https://api-3t.".$this->prePaymentSetting[
'DOMAIN'].
"paypal.com/nvp";
542 "METHOD" =>
"GetExpressCheckoutDetails",
543 "VERSION" => $this->prePaymentSetting[
'VERSION'],
544 "USER" => $this->prePaymentSetting[
'USER'],
545 "PWD" => $this->prePaymentSetting[
'PWD'],
546 "SIGNATURE" => $this->prePaymentSetting[
'SIGNATURE'],
547 "TOKEN" => $this->prePaymentSetting[
'TOKEN'],
548 "buttonsource" =>
"Bitrix_Cart"
551 $ht =
new HttpClient(
array(
"version" =>
"1.1"));
555 if (
$result[
"ACK"] ==
"Success")
561 "ADDRESS" =>
$result[
"SHIPTOSTREET"].
" ".
$result[
"SHIPTOSTREET2"],
562 "COUNTRY" =>
$result[
"SHIPTOCOUNTRYNAME"],
563 "STATE" =>
$result[
"SHIPTOSTATE"],
564 "CITY" =>
$result[
"SHIPTOCITY"],
565 "LOCATION" =>
$result[
"SHIPTOCITY"],
580 public function payOrder($orderData =
array())
582 $serviceResult =
new PaySystem\ServiceResult();
584 if($this->prePaymentSetting[
'TOKEN'])
586 $url =
"https://api-3t.".$this->prePaymentSetting[
'DOMAIN'].
"paypal.com/nvp";
588 "METHOD" =>
"GetExpressCheckoutDetails",
589 "VERSION" => $this->prePaymentSetting[
'VERSION'],
590 "USER" => $this->prePaymentSetting[
'USER'],
591 "PWD" => $this->prePaymentSetting[
'PWD'],
592 "SIGNATURE" => $this->prePaymentSetting[
'SIGNATURE'],
593 "TOKEN" => $this->prePaymentSetting[
'TOKEN'],
594 "buttonsource" =>
"Bitrix_Cart",
597 $ht = new \Bitrix\Main\Web\HttpClient(
array(
"version" =>
"1.1"));
601 if(
$result[
"ACK"] ==
"Success" && in_array(
$result[
"CHECKOUTSTATUS"],
array(
"PaymentActionNotInitiated")))
603 $arFields[
"METHOD"] =
"DoExpressCheckoutPayment";
604 $arFields[
"PAYERID"] = $this->prePaymentSetting[
'payerId'];
606 $arFields[
"PAYMENTREQUEST_0_AMT"] = number_format($this->prePaymentSetting[
'ORDER_PRICE'], 2,
".",
"");
607 $arFields[
"PAYMENTREQUEST_0_CURRENCYCODE"] = $this->prePaymentSetting[
'CURRENCY'];
608 $arFields[
"PAYMENTREQUEST_0_DESC"] =
"Order #".$this->prePaymentSetting[
'ORDER_ID'];
609 $arFields[
"PAYMENTREQUEST_0_NOTETEX"] =
"Order #".$this->prePaymentSetting[
'ORDER_ID'];
610 $arFields[
"PAYMENTREQUEST_0_INVNUM"] = $this->prePaymentSetting[
'ORDER_ID'];
612 if(DoubleVal($this->prePaymentSetting[
'DELIVERY_PRICE']) > 0)
614 $arFields[
"PAYMENTREQUEST_0_SHIPPINGAMT"] = number_format($this->prePaymentSetting[
'DELIVERY_PRICE'], 2,
".",
"");
618 if(!empty($orderProps))
620 $arFields[
"PAYMENTREQUEST_0_SHIPTONAME"] = $orderProps[
"PP_SOURCE"][
"PAYMENTREQUEST_0_SHIPTONAME"];
621 $arFields[
"PAYMENTREQUEST_0_SHIPTOSTREET"] = $orderProps[
"PP_SOURCE"][
"PAYMENTREQUEST_0_SHIPTOSTREET"];
622 $arFields[
"PAYMENTREQUEST_0_SHIPTOSTREET2"] = $orderProps[
"PP_SOURCE"][
"PAYMENTREQUEST_0_SHIPTOSTREET2"];
623 $arFields[
"PAYMENTREQUEST_0_SHIPTOCITY"] = $orderProps[
"PP_SOURCE"][
"PAYMENTREQUEST_0_SHIPTOCITY"];
624 $arFields[
"PAYMENTREQUEST_0_SHIPTOSTATE"] = $orderProps[
"PP_SOURCE"][
"PAYMENTREQUEST_0_SHIPTOSTATE"];
625 $arFields[
"PAYMENTREQUEST_0_SHIPTOZIP"] = $orderProps[
"PP_SOURCE"][
"PAYMENTREQUEST_0_SHIPTOZIP"];
626 $arFields[
"PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE"] = $orderProps[
"PP_SOURCE"][
"PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE"];
629 if(!empty($orderData[
"BASKET_ITEMS"]))
631 $arFields[
"PAYMENTREQUEST_0_ITEMAMT"] = number_format($this->prePaymentSetting[
'ORDER_PRICE']-$this->prePaymentSetting[
'DELIVERY_PRICE'], 2,
".",
"");
632 foreach($orderData[
"BASKET_ITEMS"] as
$i =>
$val)
635 $arFields[
"L_PAYMENTREQUEST_0_AMT".$i] = number_format(
$val[
"PRICE"], 2,
".",
"");
637 $arFields[
"L_PAYMENTREQUEST_0_NUMBER".$i] =
$val[
"PRODUCT_ID"];
641 if($this->prePaymentSetting[
'DELIVERY_PRICE'] <>
'')
643 $arFields[
"PAYMENTREQUEST_0_NOTIFYURL"] = $this->prePaymentSetting[
'NOTIFY_URL'];
648 $parseResult = $this->parsePrePaymentResult($postResult);
650 if($parseResult[
"ACK"] ==
"Success" && in_array($parseResult[
"PAYMENTINFO_0_PAYMENTSTATUS"],
array(
"Completed")))
652 $psStatusMessage =
"Name: ".$result[
"FIRSTNAME"].
" ".
$result[
"LASTNAME"].
"; ";
653 $psStatusMessage .=
"Email: ".$result[
"EMAIL"].
"; ";
655 $psStatusDescription =
"Payment status: ".$parseResult[
"PAYMENTINFO_0_PAYMENTSTATUS"].
"; ";
656 $psStatusDescription .=
"Payment sate: ".$parseResult[
"PAYMENTINFO_0_ORDERTIME"].
"; ";
660 "PS_STATUS_CODE" =>
"-",
661 "PS_STATUS_DESCRIPTION" => $psStatusDescription,
662 "PS_STATUS_MESSAGE" => $psStatusMessage,
663 "PS_SUM" => $parseResult[
"PAYMENTINFO_0_AMT"],
664 "PS_CURRENCY" => $parseResult[
"PAYMENTINFO_0_CURRENCYCODE"],
666 "PAY_VOUCHER_NUM" => $parseResult[
"PAYMENTINFO_0_TRANSACTIONID"],
672 $psStatusMessage =
"Name: ".$result[
"FIRSTNAME"].
" ".
$result[
"LASTNAME"].
"; ";
673 $psStatusMessage .=
"Email: ".$result[
"EMAIL"].
"; ";
675 $psStatusDescription =
"Payment status: ".$parseResult[
"PAYMENTINFO_0_PAYMENTSTATUS"].
"; ";
676 $psStatusDescription .=
"Pending reason: ".$parseResult[
"PAYMENTINFO_0_PENDINGREASON"].
"; ";
677 $psStatusDescription .=
"Payment sate: ".$parseResult[
"PAYMENTINFO_0_ORDERTIME"].
"; ";
681 "PS_STATUS_CODE" => $parseResult[
"PAYMENTINFO_0_PAYMENTSTATUS"],
682 "PS_STATUS_DESCRIPTION" => $psStatusDescription,
683 "PS_STATUS_MESSAGE" => $psStatusMessage,
684 "PS_SUM" => $parseResult[
"PAYMENTINFO_0_AMT"],
685 "PS_CURRENCY" => $parseResult[
"PAYMENTINFO_0_CURRENCYCODE"],
687 "PAY_VOUCHER_NUM" => $parseResult[
"PAYMENTINFO_0_TRANSACTIONID"],
692 $serviceResult->setPsData(
$fields);
703 public function BasketButtonAction($orderData =
array())
706 if (array_key_exists(
'paypalbutton_x', $_POST) && array_key_exists(
'paypalbutton_y', $_POST))
708 $url =
"https://api-3t.".$this->prePaymentSetting[
'DOMAIN'].
"paypal.com/nvp";
711 "METHOD" =>
"SetExpressCheckout",
713 "USER" => $this->prePaymentSetting[
'USER'],
714 "PWD" => $this->prePaymentSetting[
'PWD'],
715 "SIGNATURE" => $this->prePaymentSetting[
'SIGNATURE'],
716 "PAYMENTREQUEST_0_AMT" => number_format($orderData[
"AMOUNT"], 2,
".",
""),
717 "PAYMENTREQUEST_0_CURRENCYCODE" => $this->prePaymentSetting[
'CURRENCY'],
718 "RETURNURL" => $this->prePaymentSetting[
'SERVER_NAME'].$orderData[
"PATH_TO_ORDER"],
719 "CANCELURL" => $this->prePaymentSetting[
'SERVER_NAME'].
$APPLICATION->GetCurPageParam(
"paypal=Y&paypal_error=Y",
array(
"paypal",
"paypal_error")),
720 "PAYMENTREQUEST_0_PAYMENTACTION" =>
"Authorization",
721 "PAYMENTREQUEST_0_DESC" =>
"Order payment for ".$this->prePaymentSetting[
'SERVER_NAME'],
722 "LOCALECODE" => mb_strtoupper(LANGUAGE_ID),
723 "buttonsource" =>
"Bitrix_Cart",
726 if(!empty($orderData[
"BASKET_ITEMS"]))
728 $arFields[
"PAYMENTREQUEST_0_ITEMAMT"] = number_format($orderData[
"AMOUNT"], 2,
".",
"");
729 foreach($orderData[
"BASKET_ITEMS"] as
$k =>
$val)
732 $arFields[
"L_PAYMENTREQUEST_0_AMT".$k] = number_format(
$val[
"PRICE"], 2,
".",
"");
737 $arFields[
"RETURNURL"] .= ((mb_strpos(
$arFields[
"RETURNURL"],
"?") ===
false) ?
"?" :
"&").
"paypal=Y";
739 $ht = new \Bitrix\Main\Web\HttpClient(
array(
"version" =>
"1.1"));
746 $url =
"https://www.".$this->prePaymentSetting[
'DOMAIN'].
"paypal.com/webscr?cmd=_express-checkout&token=".
$result[
"TOKEN"];
747 if($orderData[
"ORDER_REQUEST"] ==
"Y")
755 $GLOBALS[
"APPLICATION"]->ThrowException(
$result[
'L_SHORTMESSAGE0'].
' : '.
$result[
'L_LONGMESSAGE0'],
"CSalePaySystemPrePayment_action_error");
761 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"SALE_HPS_PAYPAL_ERROR"),
"CSalePaySystemPrePayment_action_error");
772 public function setOrderConfig($orderData =
array())
776 $this->prePaymentSetting = array_merge($this->prePaymentSetting, $orderData);
784 private function getReturnUrl(Payment
$payment)
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
getUrl(Payment $payment=null, $action)
showTemplate(Payment $payment=null, $template='')
setExtraParams(array $values)
getBusinessValue(Payment $payment=null, $code)
static getIndicativeFields()
processRequest(Payment $payment, Request $request)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
ConvertTimeStamp($timestamp=false, $type="SHORT", $site=false, $bSearchInSitesOnly=false)
GetMessage($name, $aReplace=null)
LocalRedirect($url, $skip_security_check=false, $status="302 Found")
$GLOBALS['____1690880296']
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']