src/Controller/PaymentController.php line 363

  1. <?php
  2. /*
  3. * The Payment controller contains methods for the following payment gateways:
  4. * BarclaysSmart Pay - http://www.barclaycard.com/smartpay/documentation/pdf/SmartPay_HPP_IntegrationGuide.pdf
  5. * Authorize.net - https://developer.authorize.net/guides/DPM/wwhelp/wwhimpl/js/html/wwhelp.htm
  6. */
  7. namespace App\Controller;
  8. use Doctrine\Persistence\ManagerRegistry;
  9. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  10. use Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail;
  11. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\Mailer\Mailer;
  16. use Symfony\Component\Mailer\MailerInterface;
  17. use Symfony\Component\Mailer\Transport;
  18. use Symfony\Component\Mime\Email;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  21. use Symfony\Contracts\Translation\TranslatorInterface;
  22. use Psr\Log\LoggerInterface;
  23. use Twig\Environment;
  24. use App\Entity\Booking as Booking;
  25. class PaymentController extends AbstractController
  26. {
  27. private $loggedUser;
  28. public function __construct(private ManagerRegistry $doctrine, private LoggerInterface $logger, private TranslatorInterface $trans, private MailerInterface $mailer, private Environment $twig)
  29. {
  30. }
  31. #[\Symfony\Component\Routing\Attribute\Route('/customer/booking-confirmation/{ref}', name: 'bookingLink')]
  32. public function confirmAction($ref)
  33. {
  34. $em = $this->doctrine->getManager();
  35. $booking = $this->decodeRef(urldecode($ref));
  36. $this->loggedUser = $this->getUser();
  37. $this->logger->info('confirmAction: Confirm booking for ref '.$ref);
  38. if ($booking)
  39. {
  40. $this->logger->info('confirmAction: Found booking Id: '.$booking->getBookingid());
  41. $paid = false;
  42. $payment = $this->getPayment($em, $booking, $paid);
  43. $this->logger->info("confirmAction: paid: ".$paid);
  44. if (!$payment)
  45. {
  46. $payment = new Payment();
  47. $payment->setPaymentgateway($booking->getBookingoffice()->getPaymentgateway());
  48. $payment->setBooking($booking);
  49. $payment->setUpdated( new \DateTime() );
  50. $em->persist($payment);
  51. $em->flush();
  52. $paymentArray = $em->getRepository('App\Entity\Payment')->findByBooking($booking->getBookingid());
  53. $payment = array_pop($paymentArray);
  54. }
  55. else if ($paid)
  56. {
  57. $redirect = $this->generateUrl('successPayment', array('payment' => $this->createPaymentRef($payment)), UrlGeneratorInterface::ABSOLUTE_URL);
  58. return new RedirectResponse($redirect);
  59. }
  60. $paymentTemplate = $booking->getBookingoffice()->getPaymentgateway()->getTemplate();
  61. $this->logger->info('confirmAction: paymentTemplate: '.$paymentTemplate);
  62. $func = 'appendData_'.$paymentTemplate;
  63. $this->logger->info("confirmAction: Looking for appendData func: ".$func);
  64. if (method_exists($this, $func))
  65. $data = $this->$func($booking, $payment);
  66. else
  67. $data = array();
  68. $this->logger->info('confirmAction: Got payment Id: '.$payment->getPaymentid());
  69. $data['bookingRef'] = $ref;
  70. $data['booking'] = $booking;
  71. $data['payment'] = $payment;
  72. $data['user'] = $this->loggedUser;
  73. $data['resURL'] = $this->generateURL('processBooking', array('gateway' => $payment->getPaymentgateway()->getPaymentgatewayid()), UrlGeneratorInterface::ABSOLUTE_URL);
  74. $data['paid'] = $paid;
  75. $data['footer'] = 'booking.confirmation.footer.'.$paymentTemplate;
  76. $data['template'] = $paymentTemplate;
  77. $response = $this->render('booking/confirm.html.twig', $data);
  78. $date = new \DateTime(); // Set expire date to +2 seconds to prevent caching
  79. $date->modify('+2 seconds');
  80. $response->setExpires($date);
  81. return $response;
  82. }
  83. else
  84. return $this->render('booking/notfound.html.twig', array("user" => $this->loggedUser));
  85. }
  86. #[\Symfony\Component\Routing\Attribute\Route('/customer/payment-failure/{payment}', name: 'failurePayment')]
  87. public function failureAction($payment, Request $request)
  88. {
  89. $payment = $this->decodePaymentRef($payment);
  90. if ($payment)
  91. {
  92. $notificationData = explode('\n', $payment->getNotification());
  93. $this->logger->info('$notificationData: '.end($notificationData));
  94. $notificationData = json_decode(end($notificationData));
  95. return $this->render('payment/failure.html.twig', array('payment' => $payment, 'failureReason' => $notificationData->code.': '.$notificationData->status));
  96. }
  97. else
  98. return $this->render('booking/notfound.html.twig', array("user"=>$this->loggedUser ));
  99. }
  100. #[\Symfony\Component\Routing\Attribute\Route('/customer/worldpay/getRedirectUrl/{ref}', name: 'getWorldpayRedirectUrl')]
  101. public function getWorldpayRedirectUrlAction($ref)
  102. {
  103. //BE 190702: this is for Worldpay XML payments only
  104. $em = $this->doctrine->getManager();
  105. $booking = $this->decodeRef(urldecode($ref));
  106. $this->loggedUser = $this->getUser();
  107. $this->logger->info("getWorldpayRedirectUrlAction: getRedirectUrlAction for ref ".$ref);
  108. if ($booking)
  109. {
  110. $this->logger->info("getWorldpayRedirectUrlAction: Found booking Id: ".$booking->getBookingid());
  111. $paid = false;
  112. $payment = $this->getPayment($em, $booking, $paid);
  113. $this->logger->info("getWorldpayRedirectUrlAction: Found payment Id: ".$payment->getPaymentid());
  114. $office = $booking->getBookingoffice();
  115. //$data = $this->appendData_worldpay($booking, $payment);
  116. $cost = number_format($booking->getTotalprice(), 2, '', '');
  117. $currency = $booking->getBookingcurrency()->getCode();
  118. $officeSalt = $office->getMerchantsalt();
  119. $merchantCode = $this->decrypt($office->getMerchantcode(), $officeSalt).$currency;
  120. //$merchantCode = $office->getMerchantcode().$currency;
  121. $xml = '<?xml version="1.0" encoding="UTF-8"?>
  122. <!DOCTYPE paymentService PUBLIC "-//Worldpay//DTD Worldpay PaymentService v1//EN" "http://dtd.worldpay.com/paymentService_v1.dtd">
  123. <paymentService version="1.4" merchantCode="'.$merchantCode.'">
  124. <submit>
  125. <order orderCode="'.$payment->getPaymentid().'" installationId="1356990">
  126. <description>'.$booking->__toString().'</description>
  127. <amount currencyCode="'.$currency.'" exponent="2" value="'.$cost.'" />
  128. <orderContent><![CDATA[]]></orderContent>
  129. <paymentMethodMask>
  130. <include code="ALL" />
  131. </paymentMethodMask>
  132. <shopper>
  133. <shopperEmailAddress>'.$booking->getCustomer()->getEmail().'</shopperEmailAddress>
  134. </shopper>
  135. <billingAddress>
  136. <address>
  137. <address1>'.$booking->getCustomer()->getAddress().'</address1>
  138. <address2></address2>
  139. <address3></address3>
  140. <postalCode>'.$booking->getCustomer()->getPostcode().'</postalCode>
  141. <city>'.$booking->getCustomer()->getCity().'</city>
  142. <state>'.$booking->getCustomer()->getState().'</state>
  143. <countryCode>'.$booking->getCustomer()->getCustomercountry()->getCountry2Code().'</countryCode>
  144. </address>
  145. </billingAddress>
  146. </order>
  147. </submit>
  148. </paymentService>';
  149. $this->logger->info("getWorldpayRedirectUrlAction: Xml: ".$xml);
  150. $username = $merchantCode;//$this->decrypt($office->getMerchantusername(), $officeSalt);
  151. $pwd = $this->decrypt($office->getMerchantpassword(), $officeSalt);
  152. $test_mode = $this->getParameter('app.worldpayxml_test_mode') == 'TRUE';
  153. $basicAuth = $username . ':' . $pwd;
  154. //$this->logger->info("Using Auth: ".$basicAuth);
  155. $basicAuthBase64 = base64_encode($basicAuth);
  156. $basicAuthUrlEncoded = urlencode($username) . ":" . urlencode($pwd);
  157. if ($test_mode)
  158. $url = "https://secure-test.worldpay.com/jsp/merchant/xml/paymentService.jsp";
  159. else
  160. $url = "https://secure.worldpay.com/jsp/merchant/xml/paymentService.jsp";
  161. $this->logger->info("Using Url: ".$url);
  162. //$this->logger->info("Using Url: ".str_replace($basicAuth, "user:pwd", $url));
  163. $ch = curl_init();
  164. curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  165. curl_setopt($ch, CURLOPT_USERPWD, $basicAuth);
  166. //curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml', 'Authorization: ' . $basicAuthBase64));
  167. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
  168. curl_setopt($ch, CURLOPT_URL, $url);
  169. curl_setopt($ch, CURLOPT_POST, true);
  170. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  171. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  172. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
  173. $response = curl_exec($ch);
  174. if ($response == false)
  175. {
  176. $this->logger->error('Error code: '.curl_error($ch));
  177. $url = $this->generateUrl('failurePayment', array('payment'=>$this->createPaymentRef($payment)), UrlGeneratorInterface::ABSOLUTE_URL);
  178. $err = array('date' => date('Y-m-d H:i:s'),'code' => 999, 'status' => 'XML Response empty - contact Support');
  179. $payment->setNotification($payment->getNotification().'\n'.json_encode($err));
  180. $em->persist($payment);
  181. $em->flush();
  182. $this->mailSalesFailure($payment);
  183. //$this->logger->info("failurePayment: ".$serializedData);
  184. return new RedirectResponse($url);
  185. }
  186. else
  187. {
  188. $this->logger->info("getWorldpayRedirectUrlAction: response: ".$response);
  189. $responseXml = simplexml_load_string($response);
  190. //$this->logger->info("responseXml: ".print_r($responseXml, true));
  191. if (property_exists($responseXml->reply, 'error') || strpos($response, '<html') !== false)
  192. {
  193. $url = $this->generateUrl('failurePayment', array('payment'=>$this->createPaymentRef($payment)), UrlGeneratorInterface::ABSOLUTE_URL);
  194. if (property_exists($responseXml->reply, 'error'))
  195. {
  196. $code = (int)$responseXml->reply->error['code'];
  197. $error = (string)$responseXml->reply->error;
  198. if ($error == 'Order has already been paid')
  199. $status = $error;
  200. else
  201. $status = 'There was an unknown problem with the gateway - Contact Support, and give them this info: '.(string)$responseXml->reply->error;
  202. }
  203. else if (strpos($response, '<html') !== false && strpos($response, 'Status: 401') !== false)
  204. {
  205. $code = '401';
  206. $status = 'There was an authentication problem with the gateway - contact Support, and give them this info: Status 401: Authentication Problem';
  207. }
  208. else
  209. {
  210. $code = '?';
  211. $status = 'There was an unknown problem with the gateway - Contact Support, and give them this info: '.htmlentities($response);
  212. }
  213. $err = array('date' => date('Y-m-d H:i:s'), 'code' => $code, 'status' => $status);
  214. $payment->setNotification($payment->getNotification().'\n'.json_encode($err));
  215. $em->persist($payment);
  216. $em->flush();
  217. $this->mailSalesFailure($payment);
  218. //$this->logger->info("failurePayment: ".$serializedData);
  219. return new RedirectResponse($url);
  220. }
  221. else if (property_exists($responseXml->reply, 'orderStatus') && property_exists($responseXml->reply->orderStatus, 'reference'))
  222. {
  223. $refUrl = (string)$responseXml->reply->orderStatus->reference[0];
  224. $this->logger->info("getWorldpayRedirectUrlAction: reference: ".$refUrl);
  225. //$this->logger->info("reference: ".print_r($refUrl, true));
  226. //$this->logger->info("reference type: ".gettype($refUrl));
  227. //return $this->redirect($refUrl);
  228. $successURL = urlencode($this->generateURL("processWorldpay", array("pid" => $payment->getPaymentID() ), UrlGeneratorInterface::ABSOLUTE_URL));
  229. $refUrl .= '&successURL='.$successURL.'&failureURL='.$successURL.'&cancelURL='.$successURL.'&errorURL='.$successURL;
  230. $this->logger->info("getWorldpayRedirectUrlAction: reference: ".$refUrl);
  231. return new RedirectResponse($refUrl);
  232. }
  233. }
  234. curl_close($ch);
  235. }
  236. else
  237. $this->logger->info("getWorldpayRedirectUrlAction: No booking found!");
  238. }
  239. public function paymentNotificationAction($template, Request $request)
  240. {
  241. $this->logger->info("PaymentController.paymentNotificationAction started template:$template");
  242. if ($template == "barclays")
  243. {
  244. $dataChk=array();
  245. $dataChk['live'] = $request->get("live"); // live or test
  246. $dataChk["eventCode"] = $request->get("eventCode"); // event code - will be AUTHORISATION
  247. $dataChk["pspReference"] = $request->get("pspReference"); // Barclay ref code
  248. $dataChk["originalReference"] = $request->get("originalReference"); // blank
  249. $dataChk["merchantReference"] = $request->get("merchantReference"); // Our ref code
  250. $dataChk["merchantAccountCode"] = $request->get("merchantAccountCode"); // Merchant account code
  251. $dataChk["success"] = $request->get("success");
  252. $dataChk["paymentMethod"] = $request->get("paymentMethod");
  253. $dataChk["operations"] = $request->get("operations");
  254. $dataChk["reason"] = $request->get("reason");
  255. $dataChk["amount"] = $request->get("amount");
  256. $this->logger->info("PaymentController.paymentNotificationAction Request Data: ".print_r($dataChk,true));
  257. $em = $this->doctrine->getManager();
  258. $payment = false;
  259. if ($dataChk["merchantReference"] > 0)
  260. {
  261. $this->logger->info("PaymentController.paymentNotificationAction Retrieving Payment: ".$dataChk['merchantReference']);
  262. $payment = $em->getRepository('App\Entity\Payment')->find($dataChk["merchantReference"]);
  263. } else {
  264. $this->logger->info("PaymentController.paymentNotificationAction No Asscociated Payment");
  265. }
  266. if ($payment)
  267. {
  268. $this->logger->info("PaymentController.paymentNotificationAction Payment Successfully Retreived: ".$dataChk['merchantReference']);
  269. $payment->setNotification(serialize($dataChk));
  270. $em->persist($payment);
  271. $em->flush();
  272. if ($dataChk["success"]=='false')
  273. {
  274. $this->logger->info("PaymentController.paymentNotificationAction Payment Unsuccessful, Mailing Sales Rep: ".$dataChk['merchantReference']);
  275. $this->mailSalesFailure($payment);
  276. } else
  277. {
  278. $this->logger->info("PaymentController.paymentNotificationAction Payment Successful: ".$dataChk['merchantReference']);
  279. }
  280. }
  281. $this->logger->info("PaymentController.paymentNotificationAction Returning 200 Response");
  282. return new Response('[accepted]',200,array('content-type' => 'text/html'));
  283. }
  284. }
  285. #[\Symfony\Component\Routing\Attribute\Route('/customer/worldpay/redirect/{pid}', name: 'processWorldpay')]
  286. public function processWorldpayAction($pid, MailerInterface $mailer, Request $request)
  287. {
  288. $em = $this->doctrine->getManager();
  289. $payment = $this->saveReturnData_worldpay($pid, $request);
  290. $msg = 'NONE';
  291. if ($payment)
  292. {
  293. $paymentRef = $this->createPaymentRef($payment);
  294. $booking = $payment->getBooking();
  295. if ($payment->getSuccessful() == 1)
  296. {
  297. $redirect = $this->generateUrl('successPayment', array("payment"=>$paymentRef), UrlGeneratorInterface::ABSOLUTE_URL);
  298. $this->mailCustomerConfirmation($booking, $payment);
  299. $this->mailSalesConfirmation($booking, $payment, $request);
  300. $booking->setPaid(1);
  301. $em->persist($booking);
  302. $em->flush();
  303. } else {
  304. $redirect = $this->generateUrl('failurePayment', array("payment"=>$paymentRef), UrlGeneratorInterface::ABSOLUTE_URL);
  305. $this->mailSalesFailure($payment);
  306. }
  307. } else
  308. $redirect = $this->generateUrl('failurePayment', array("payment"=>$paymentRef), UrlGeneratorInterface::ABSOLUTE_URL);
  309. //$redirect = $redirect===false ? $request->get("MC_failure") : $redirect;
  310. //$params = $request->query->all();
  311. //return $this->render("ACSBundle:Payment:process_worldpay.html.twig", array("redirect"=>$redirect, "payment"=>$payment, 'params'=>$params, 'msg'=>$msg) );
  312. //return new Response("done");
  313. return new RedirectResponse($redirect);
  314. }
  315. #[\Symfony\Component\Routing\Attribute\Route('/customer/payment-success/{payment}', name: 'successPayment')]
  316. public function successAction($payment)
  317. {
  318. $payment = $this->decodePaymentRef($payment);
  319. if ($payment)
  320. return $this->render("payment/success.html.twig", array('payment' => $payment));
  321. else
  322. return $this->render("booking/notfound.html.twig", array("user"=>$this->loggedUser ));
  323. }
  324. public function testAction()
  325. {
  326. $test = 'MYADMINCODE^MYMERCHANT^T0211010:1400:GBP:AUTHORISED';
  327. $result = hash_hmac('sha256', $test, '@p-p1epie');
  328. return new Response($result);
  329. /*$em = $this->getDoctrine()->getManager();
  330. $payment = $em->getRepository('App\Entity\Payment')->find(57);
  331. $booking = $payment->getBooking();
  332. $this->mailCustomerConfirmation($booking, $payment);
  333. $customer = $booking->getCustomer();
  334. $user = $booking->getCreatedby();
  335. $recipient = trim($customer->getFirstname()." ".$customer->getSurname());
  336. $sender = trim($user->getFirstname()." ".$user->getSurname());
  337. return $this->render("emails/CustomerConfirmation.html.twig",
  338. array(
  339. 'recipient' => $recipient,
  340. 'sender'=> $sender,
  341. 'booking'=>$booking,
  342. 'payment'=>$payment,
  343. ));*/
  344. }
  345. /*** PRIVATE HELPER METHODS ***/
  346. private function appendData_worldpay($booking, $payment)
  347. {
  348. // See docs for implementation : https://beta.developer.worldpay.com/docs/wpg/hostedintegration/quickstart
  349. $test_mode = $this->getParameter('app.worldpayxml_test_mode') == 'TRUE';
  350. // MD5 hash params may be chosen from the merchant interface. Currently set to
  351. // md5_secret:instId:currency:amount:paymentid
  352. $cost = number_format($booking->getTotalprice(), 2, '.', '');
  353. $currency = $booking->getBookingcurrency()->getCode();
  354. $sig_params = array();
  355. $sig_params[] = null; //$md5_secret;
  356. $sig_params[] = null; //$instId;
  357. $sig_params[] = $currency;
  358. $sig_params[] = $cost;
  359. $sig_params[] = $payment->getPaymentid();
  360. $bookingOffice = $booking->getBookingoffice();
  361. $bookingAgentEmail = $booking->getCreatedby()->getEmail();
  362. $bookingAgentName = trim($booking->getCreatedby()->getFirstname()." ".$booking->getCreatedby()->getSurname());
  363. $contactDetails = $bookingOffice->getAddress()."<br />".$bookingOffice->getCity()."<br />".$bookingOffice->getZipcode()."<br />".$bookingOffice->getOfficecountry()->getName()."<br />Reg. No.: ".$bookingOffice->getRegnumber()."<br />Phone: ".$bookingOffice->getPhone()."<br />Booking agent: ".$bookingAgentName." - <a href='mailto:".$bookingAgentEmail."'>".$bookingAgentEmail."</a>";
  364. $data = array(
  365. "orderId" => $payment->getPaymentid(),
  366. "testMode" => $test_mode,
  367. "orderCurrency" => $currency,
  368. "orderAmount" => $cost,
  369. "description" => $booking->__toString(),
  370. "shopperEmail" => $booking->getCustomer()->getEmail(),
  371. "name" => $booking->getCustomer()->getFirstname()." ".$booking->getCustomer()->getSurname(),
  372. "address" => $booking->getCustomer()->getAddress(),
  373. "city" => $booking->getCustomer()->getCity(),
  374. "zip" => $booking->getCustomer()->getPostcode(),
  375. "state" => $booking->getCustomer()->getState(),
  376. "country" => $booking->getCustomer()->getCustomercountry()->getCountry2Code(),
  377. "phone" => preg_replace("/^![0-9]$/","",$booking->getCustomer()->getPhone()),
  378. "successURL" => $this->generateURL("successPayment", array( "payment"=>$payment->getPaymentID() ), UrlGeneratorInterface::ABSOLUTE_URL),
  379. "failureURL" => $this->generateURL("failurePayment", array( "payment"=>$payment->getPaymentID() ), UrlGeneratorInterface::ABSOLUTE_URL),
  380. // Following fields required by VISA for payments in GBP
  381. "shopperAdditionalAccountNumber" => "",
  382. "shopperAdditionalLastName" => "",
  383. "shopperAdditionalBirthDate" => "",
  384. "shopperAdditionalPostalCode" => "",
  385. "contactDetails" => $contactDetails
  386. );
  387. $data['MD5sig'] = md5(implode(":", $sig_params));
  388. return $data;
  389. }
  390. private function createPaymentRef($payment)
  391. {
  392. $booking = $payment->getBooking();
  393. $ref=array();
  394. $ref[]=$payment->getPaymentid();
  395. $ref[]=$booking->getBookingid();
  396. $ref[]=$booking->getCustomer()->getCustomerid();
  397. $ref[]=$booking->getBookingoffice()->getOfficeid();
  398. /*$finalRef = $ref[0].$ref[1].$ref[2].$ref[3];
  399. $next = $this->getEverySecondDigit($finalRef);
  400. $finalRef = $finalRef / $next;
  401. $next = $this->getEverySecondDigit($finalRef);
  402. $finalRef = $finalRef / $next;
  403. $next = $this->getEverySecondDigit($finalRef);
  404. $finalRef = $finalRef * $next;
  405. $decimalPos = strrpos($finalRef, '.');
  406. $finalRef = str_replace('.', '', $finalRef);
  407. $finalRef .= $decimalPos;
  408. $this->logger->info('$finalRef: '.$finalRef);
  409. return urlencode($finalRef);*/
  410. return urlencode(bin2hex(implode(Booking::URL_SECRET, $ref)));
  411. }
  412. private function decodePaymentRef($ref)
  413. {
  414. $this->logger->info('decodePaymentRef: '.$ref);
  415. //$decimalPos = (string)$ref[strlen((string)$ref) - 1];
  416. //$this->logger->info('decimalPos: '.$decimalPos);
  417. $data = explode(Booking::URL_SECRET, pack("H*", $ref));
  418. $this->logger->info('Data: '.print_r($data, true));
  419. $id = array_shift($data);
  420. $em = $this->doctrine->getManager();
  421. $payment = $em->getRepository('App\Entity\Payment')->find($id);
  422. if ($payment)
  423. {
  424. $this->logger->info('Got payment: '.$payment->getPaymentid());
  425. $booking = $payment->getBooking();
  426. if ($booking->getBookingid() == $data[0] && $booking->getCustomer()->getCustomerid() == $data[1] && $booking->getBookingoffice()->getOfficeid() == $data[2])
  427. return $payment;
  428. else {
  429. $this->logger->info('Did not match criteria: bid: '.$booking->getBookingid().' $data[0]: '.$data[0].', cid: '.$booking->getCustomer()->getCustomerid().' $data[1]: '.$data[1].', oid: '.$booking->getBookingoffice()->getOfficeid().' $data[2]: '.$data[2]);
  430. return false;
  431. }
  432. } else {
  433. $this->logger->info('Could not find payment from id: '.$id);
  434. return false;
  435. }
  436. }
  437. private function decodeRef($ref)
  438. {
  439. $data = explode(Booking::URL_SECRET, pack("H*", $ref));
  440. //$decimalPos = (string)$ref[(strlen($ref) - 1];
  441. $id = array_shift($data);
  442. $em = $this->doctrine->getManager();
  443. $booking = $em->getRepository('App\Entity\Booking')->find($id);
  444. if ($booking)
  445. {
  446. if ($booking->getCustomer()->getCustomerid() == $data[0] && $booking->getBookingoffice()->getOfficeid()==$data[1])
  447. return $booking;
  448. else
  449. return false;
  450. } else
  451. return false;
  452. }
  453. private function decrypt($encrypted, $salt) {
  454. //https://www.the-art-of-web.com/php/two-way-encryption/
  455. $encKey = $this->getParameter('app.worldpayxml_enckey').$salt;
  456. $method = 'AES-256-CTR';
  457. list($encrypted, $encIV) = explode("::", $encrypted);
  458. $decrypted = openssl_decrypt($encrypted, $method, $encKey, 0, hex2bin($encIV));
  459. return $decrypted;
  460. }
  461. private function encrypt($token, $salt) {
  462. //https://www.the-art-of-web.com/php/two-way-encryption/
  463. $encKey = $this->getParameter('app.worldpayxml_enckey').$salt;
  464. $method = 'AES-256-CTR';
  465. $encIV = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method));
  466. $encrypted = openssl_encrypt($token, $method, $encKey, 0, $encIV) . "::" . bin2hex($encIV);
  467. return $encrypted;
  468. }
  469. public static function getEverySecondDigit($input) {
  470. //$this->logger = Logger::getLogger(__CLASS__);
  471. $input = (string)$input;
  472. $len = strlen($input);
  473. //$this->logger->info('Length of '.$input.' is '.$len);
  474. $final = '';
  475. for ($x = 0; $x < $len; $x++) {
  476. if ($input[$x] != '.') {
  477. if (($x + 1) % 2 === 0) {
  478. $final .= $input[$x];
  479. }
  480. } else {
  481. $final .= '.';
  482. }
  483. }
  484. //$this->logger->info('From $input: '.$input.', calculated: '.$final);
  485. return $final;
  486. }
  487. private function getPayment($em, $booking, &$paid)
  488. {
  489. $this->logger->info('getPayment for booking: '.$booking->getBookingid());
  490. $paymentArray = $em->getRepository('App\Entity\Payment')->findByBooking($booking->getBookingid());
  491. $payment = false;
  492. foreach ($paymentArray as $p)
  493. {
  494. $this->logger->info('Found payment: '.$p->getPaymentid().', is successful: '.($p->getSuccessful() == 1));
  495. $payment = $p;
  496. if ($p->getSuccessful() == 1)
  497. {
  498. $paid = true;
  499. break;
  500. }
  501. //else if ($p->getResulttoken() == null && $p->getAuthcode() == null && $p->getSuccessful() == null) {
  502. // $payment = $p;
  503. // break;
  504. //}
  505. }
  506. return $payment;
  507. }
  508. private function mailCustomerConfirmation($booking, $payment)
  509. {
  510. $customer = $booking->getCustomer();
  511. $user = $booking->getCreatedby();
  512. $office = $booking->getBookingoffice();
  513. $recipient = trim($customer->getFirstname().' '.$customer->getSurname());
  514. $sender = trim($user->getFirstname().' '.$user->getSurname());
  515. $from = $office->getEmailaddress();
  516. $message = (new TemplatedEmail())
  517. ->subject('Booking Payment Received')
  518. ->from($from)
  519. ->to($customer->getEmail());
  520. //https://github.com/symfony/symfony/issues/42407#issuecomment-1006995400
  521. $html = $this->render('emails/CustomerConfirmation.html.twig',
  522. [
  523. 'recipient' => $recipient,
  524. 'sender' => $sender,
  525. 'booking' => $booking,
  526. 'payment' => $payment,
  527. 'email' => new WrappedTemplatedEmail($this->twig, $message),
  528. ])
  529. ->getContent();
  530. $message->html($html);
  531. $this->mailer = new Mailer(Transport::fromDsn('sendmail://default'));
  532. $sent = $this->mailer->send($message);
  533. //https://stackoverflow.com/q/71496164/206852
  534. // if ($sent !== null)
  535. // dd($sent->getDebug());
  536. }
  537. private function mailSalesConfirmation($booking, $payment, $request) {
  538. $customer = $booking->getCustomer();
  539. $user = $booking->getCreatedby();
  540. $office = $booking->getBookingoffice();
  541. $recipient = trim($user->getFirstname().' '.$user->getSurname());
  542. $sender = 'System';
  543. $from = $office->getEmailaddress();
  544. $message = (new TemplatedEmail())
  545. ->subject('Booking Payment Received')
  546. ->from($from)
  547. ->to($user->getEmail())
  548. ->cc($this->getParameter('app.accountsemail'));
  549. //https://github.com/symfony/symfony/issues/42407#issuecomment-1006995400
  550. $html = $this->render('emails/SalesConfirmation.txt.twig',
  551. [
  552. 'recipient' => $recipient,
  553. 'sender' => $sender,
  554. 'booking' => $booking,
  555. 'payment' => $payment,
  556. 'cardUsed' => $request->get('cardType'),
  557. 'email' => new WrappedTemplatedEmail($this->twig, $message),
  558. ])
  559. ->getContent();
  560. $message->html($html);
  561. $this->mailer = new Mailer(Transport::fromDsn('sendmail://default'));
  562. $sent = $this->mailer->send($message);
  563. //https://stackoverflow.com/q/71496164/206852
  564. // if ($sent !== null)
  565. // dd($sent->getDebug());
  566. }
  567. private function mailSalesFailure($payment)
  568. {
  569. $this->logger->info('mailSalesFailure');
  570. if ($payment)
  571. {
  572. $booking = $payment->getBooking();
  573. $customer = $booking->getCustomer();
  574. $user = $booking->getCreatedby();
  575. $office = $booking->getBookingoffice();
  576. $recipient = trim($user->getFirstname().' '.$user->getSurname());
  577. $sender = 'System';
  578. $name = trim($customer->getFirstname().' '.$customer->getSurname());
  579. $from = $office->getEmailaddress();
  580. $template = $booking->getBookingoffice()->getPaymentgateway()->getTemplate();
  581. $notificationData = explode('\n', $payment->getNotification());
  582. $notificationData = json_decode(end($notificationData));
  583. //$this->logger->info('$payment->getNotification(): '.$payment->getNotification());
  584. $this->logger->info('$notificationData: '.print_r($notificationData, true));
  585. $this->logger->info('json_last_error: '.json_last_error());
  586. switch ($template)
  587. {
  588. case 'authorize':
  589. $reason = $notificationData->response_reason_text;
  590. break;
  591. case 'barclays':
  592. $reason = $notificationData['reason'];
  593. break;
  594. case 'worldpay':
  595. $reason = 'Error code: '.$notificationData->code.', Error message: '.$notificationData->status;
  596. break;
  597. }
  598. $message = (new TemplatedEmail())
  599. ->subject('Booking Payment Failed')
  600. ->from($from)
  601. ->to($user->getEmail());
  602. //https://github.com/symfony/symfony/issues/42407#issuecomment-1006995400
  603. $html = $this->render('emails/Failure.txt.twig',
  604. [
  605. 'recipient' => $recipient,
  606. 'sender' => $sender,
  607. 'booking' => $booking,
  608. 'payment' => $payment,
  609. 'name' => $name,
  610. 'reason' => $reason,
  611. 'email' => new WrappedTemplatedEmail($this->twig, $message),
  612. ])
  613. ->getContent();
  614. $message->html($html);
  615. $this->mailer = new Mailer(Transport::fromDsn('sendmail://default'));
  616. $sent = $this->mailer->send($message);
  617. //https://stackoverflow.com/q/71496164/206852
  618. // if ($sent !== null)
  619. // dd($sen
  620. }
  621. }
  622. private function saveReturnData_worldpay($pid, Request $request)
  623. {
  624. $this->logger->info('saveReturnData_worldpay');
  625. $em = $this->doctrine->getManager();
  626. $payment = $em->getRepository('App\Entity\Payment')->find($pid);
  627. if ($payment)
  628. {
  629. $this->logger->info("Found payment with id ".$pid);
  630. if ($request->query->has('errorRefNumber') && $request->query->has('errors'))
  631. {
  632. $err = array('date' => date('Y-m-d H:i:s'), 'code' => $request->get('errorRefNumber'), 'status' => 'Worldpay error: '.$request->get('errors'));
  633. $payment->setNotification($payment->getNotification().'\n'.json_encode($err));
  634. $payment->setSuccessful(0);
  635. $em->persist($payment);
  636. $em->flush();
  637. return $payment;
  638. }
  639. //AUTHORISED EXAMPLE
  640. //https://dev.onlinepayments.aircharterservice.com/customer/worldpay/redirect/296?orderKey=AIRCHARTERSERVICES%5EAIRCHARTERUKECOMGBP%5E296&paymentStatus=AUTHORISED&paymentAmount=1234565&paymentCurrency=GBP&mac2=c975417ba3d7b63a29c1457802379b4f6b799a67750d9aab590dd277622ff92e
  641. //CANCELLED EXAMPLE
  642. //https://dev.onlinepayments.aircharterservice.com/customer/worldpay/redirect/309?orderKey=AIRCHARTERSERVICES%5EAIRCHARTERUKECOMGBP%5E309&orderAmount=65421&orderCurrency=GBP&mac2=5e3ee235214f9906c3869bb916f49477f126d076cb11c6497472f07b2528fdbf
  643. //REFUSED EXAMPLE
  644. //https://dev.onlinepayments.aircharterservice.com/customer/worldpay/redirect/309?orderKey=AIRCHARTERSERVICES%5EAIRCHARTERUKECOMGBP%5E309&paymentStatus=REFUSED&paymentAmount=65421&paymentCurrency=GBP&mac2=8911c0e65ad5d7bbd219db86581c84fe63a532a34023b2ac670e44f0d6e6c677
  645. //ERROR EXAMPLE
  646. //https://dev.onlinepayments.aircharterservice.com/customer/worldpay/redirect/309?orderKey=AIRCHARTERSERVICES%5EAIRCHARTERUKECOMGBP%5E309&errorRefNumber=D190710-T154806-M001-43&errors=Gateway+error
  647. //BE 190708: documentation at https://beta.developer.worldpay.com/docs/wpg/hostedintegration/securingpayments
  648. $booking = $payment->getBooking();
  649. $office = $booking->getBookingoffice();
  650. $officeSalt = $office->getMerchantsalt();
  651. $macSecret = $this->decrypt($office->getMerchantmacsecret(), $officeSalt);
  652. $test_mode = $this->getParameter('app.worldpayxml_test_mode') == 'TRUE';
  653. $currency = $booking->getBookingcurrency()->getCode();
  654. $merchantCode = $this->decrypt($office->getMerchantcode(), $officeSalt).$currency;
  655. // status can be "AUTHORISED" or "REFUSED"
  656. $status = $request->get('paymentStatus');
  657. $sig_params = array();
  658. $sig_params[] = $request->get('orderKey');
  659. $sig_params[] = $request->get('paymentAmount');
  660. $sig_params[] = $request->get('paymentCurrency');
  661. if ($status)
  662. $sig_params[] = $status;
  663. $sig_check = array();
  664. $sig_check[] = 'AIRCHARTERSERVICES^'.$merchantCode.'^'.$payment->getPaymentId();
  665. $sig_check[] = ltrim((string)number_format($booking->getTotalprice(), 2, '', ''), '0');
  666. $sig_check[] = $currency;
  667. if ($status)
  668. $sig_check[] = $status;
  669. $sigSent = implode(":", $sig_params);
  670. $sigCalculated = implode(":", $sig_check);
  671. $calculated_hash = hash_hmac('sha256', $sigCalculated, $macSecret);
  672. //$this->logger->info('Using secret: '.$macSecret);
  673. $hash_check = $calculated_hash == $request->get('mac2');
  674. $retVal = false;
  675. if ($hash_check)
  676. {
  677. $statusCode = 1;
  678. if (!$status || $status == 'CANCELLED')
  679. $statusCode = 3;
  680. else if ($status == 'AUTHORISED')
  681. $statusCode = 1;
  682. else if ($status == 'REFUSED')
  683. $statusCode = 2;
  684. else
  685. $statusCode = 99;
  686. $this->logger->info('Hash check succeeded!');
  687. $payment->setResulttoken($request->get('mac2'));
  688. $payment->setAuthcode($request->get('mac2'));
  689. $payment->setSuccessful($statusCode == 1);
  690. $payment->setNotification($payment->getNotification().'\n'.json_encode(array('date' => date('Y-m-d H:i:s'), 'code' => $statusCode, 'status' => $status, 'params' => $request->query->all())));
  691. $retVal = $payment;
  692. }
  693. else
  694. {
  695. $this->logger->info('Sig params sent: '.$sigSent.', Sig params calculated: '.$sigCalculated.', are equal = '.($sigSent == $sigCalculated));
  696. $this->logger->info('Failed Hash Check: Calculated Value: '.$calculated_hash.', Sent Value (mac): '.$request->get('mac').', Sent Value (mac2): '.$request->get('mac2'));
  697. $payment->setNotification($payment->getNotification().'\n'.json_encode(array('date' => date('Y-m-d H:i:s'), 'code' => 4, 'status' => 'Failed Auth Hash Check - contact Support', 'params' => $request->query->all())));
  698. $retVal = $payment;
  699. }
  700. $em->persist($payment);
  701. $em->flush();
  702. return $retVal;
  703. } else {
  704. $this->logger->info("Payment with id ".$pid." was NOT found.");
  705. return false;
  706. }
  707. }
  708. /*** OLD CODE - KEPT FOR REFERENCE IF REQUIRED IN THE FUTURE ***/
  709. private function appendData_barclays($booking, $payment) {
  710. $hmac_key = $this->getParameter('barclays_hmac_key');
  711. $skin_code = $this->getParameter('barclays_skin_code');
  712. $merchant_acc = $this->getParameter('barclays_merchant_acc');
  713. $time = $payment->getUpdated()->format("U") + 60*60*24*30;
  714. $paymentexpires = gmdate("Y-m-d", $time) . 'T' . gmdate("H:i:s", $time) ."Z";
  715. //$paymentexpires=gmdate(DATE_ISO8601,$expTimestamp);
  716. $data = array(
  717. 'paymentAmount' => $booking->getTotalprice()*100,
  718. 'currencyCode' => $booking->getBookingcurrency()->getCode(),
  719. 'shipBeforeDate' => $payment->getUpdated()->format('Y-m-d'),
  720. 'merchantReference' => $payment->getPaymentid(),
  721. 'skinCode' => $skin_code,
  722. 'merchantAccount' => $merchant_acc,
  723. 'sessionValidity' => $paymentexpires,
  724. 'shopperEmail' => $booking->getCustomer()->getEmail(),
  725. 'shopperReference' => $booking->getCustomer()->getCustomerid(),
  726. 'allowedMethods' => '',
  727. 'blockedMethods' => '',
  728. 'shopperStatement' => '',
  729. 'billingAddressType'=> '',
  730. );
  731. $summary = implode("",$data);
  732. $merchantSig = base64_encode(hash_hmac('sha1',$summary,$hmac_key,true));
  733. $data['orderData'] = base64_encode($booking->__toString());
  734. $data['merchantSig'] = $merchantSig;
  735. return $data;
  736. }
  737. private function appendData_authorize($booking,$payment) {
  738. $hmac_key = $this->getParameter('authorize_hmac_key');
  739. $api_login = $this->getParameter('authorize_api_login');
  740. /*added by vazquel on 2014-02-19*/
  741. $md5_hash = $this->getParameter('authorize_md5_hash');
  742. $gateway = new \Authorizenet_Authorizenet($api_login, $md5_hash);
  743. $response = $gateway->AuthorizeSIM;
  744. $fp_timestamp = gmdate("U");
  745. $fingerprint = \AuthorizeNetSIM_Form::getFingerprint($api_login, $hmac_key, $booking->getTotalprice(), $payment->getPaymentid(), $fp_timestamp, $booking->getBookingcurrency()->getCode());
  746. $data['x_login'] = $api_login;
  747. $data['x_test_request'] = $this->getParameter('authorize_test_mode');
  748. $data['x_fp_sequence'] = $payment->getPaymentid();
  749. $data['x_fp_timestamp'] = $fp_timestamp;
  750. $data['x_amount'] = $booking->getTotalprice();
  751. $data['x_currency_code']= $booking->getBookingcurrency()->getCode();
  752. $data['x_fp_hash'] = $fingerprint;
  753. $data['x_description'] = $booking->__toString();
  754. $data['x_first_name'] = $booking->getCustomer()->getFirstname();
  755. $data['x_last_name'] = $booking->getCustomer()->getSurname();
  756. $data['x_address'] = $booking->getCustomer()->getAddress();
  757. $data['x_city'] = $booking->getCustomer()->getCity();
  758. $data['x_zip'] = $booking->getCustomer()->getPostcode();
  759. $data['x_state'] = $booking->getCustomer()->getState();
  760. $data['x_country'] = $booking->getCustomer()->getCustomercountry()->getName();
  761. $data['x_phone'] = preg_replace("/^![0-9]$/","",$booking->getCustomer()->getPhone());
  762. $data['x_email'] = $booking->getCustomer()->getEmail();
  763. $data['booking'] = $booking;
  764. $data['payment'] = $payment;
  765. return $data;
  766. }
  767. private function appendData_moneyswap($booking, $payment) {
  768. $moneyswap_aid = $this->getParameter('moneyswap_aid');
  769. $moneyswap_md5_signature = $this->getParameter('moneyswap_md5_signature');
  770. $data = array(
  771. "acqID" => $moneyswap_aid,
  772. //"acqID" => "04020826",
  773. "backURL" => $this->generateURL("processBooking", array( "gateway"=>$payment->getPaymentgateway()->getPaymentgatewayid() ), UrlGeneratorInterface::ABSOLUTE_URL),
  774. "charSet" => "UTF-8",
  775. "frontURL" => $this->generateURL("processBooking", array( "gateway"=>$payment->getPaymentgateway()->getPaymentgatewayid() ), UrlGeneratorInterface::ABSOLUTE_URL),
  776. "merID" => "846084045110001",
  777. "merReserve" => $booking->__toString(),
  778. "orderAmount" => number_format($booking->getTotalprice(), 2, '.', ''),
  779. "orderCurrency" => $booking->getBookingcurrency()->getCode(),
  780. "orderNum" => $payment->getPaymentid(),
  781. "paymentSchema" => "UP",
  782. "transTime" => date("YmdHis"),
  783. "transType" => "PURC",
  784. "signType" => "MD5",
  785. "version" => "VER000000002",
  786. );
  787. $signature = MoneySwapHelper::createSignature($moneyswap_md5_signature, $data);
  788. $data['signature'] = $signature;
  789. return $data;
  790. }
  791. private function getRelayResponseSnippet($redirect_url) {
  792. return "<html><head><script language=\"javascript\">
  793. <!--
  794. window.location1=\"{$redirect_url}\";
  795. //-->
  796. </script>
  797. </head><body><noscript><meta http-equiv=\"refresh\" content=\"1;url={$redirect_url}\"></noscript>Test</body></html>";
  798. }
  799. #[\Symfony\Component\Routing\Attribute\Route('/customer/process/{gateway}', name: 'processBooking')]
  800. public function processAction($gateway, MailerInterface $mailer, Request $request)
  801. {
  802. $em = $this->getDoctrine()->getManager();
  803. $paymentGateway = $em->getRepository('App\Entity\Paymentgateway')->find($gateway);
  804. $func = "saveReturnData_".$paymentGateway->getTemplate();
  805. $api_login = $this->getParameter('authorize_api_login');
  806. $md5_hash = $this->getParameter('authorize_md5_hash');
  807. $fullDomain = ($request->server->get("https") ? "https://" : "http://") . $request->getHost();
  808. if (method_exists($this, $func))
  809. $payment = $this->$func($request);
  810. if ($payment)
  811. {
  812. $booking=$payment->getBooking();
  813. if ($payment->getSuccessful()==1)
  814. {
  815. if ($gateway == 3) {
  816. if (!$booking->getPaid()) {
  817. $this->mailCustomerConfirmation($booking,$payment);
  818. $this->mailSalesConfirmation($booking,$payment,$request);
  819. }
  820. } else {
  821. $this->mailCustomerConfirmation($booking,$payment);
  822. $this->mailSalesConfirmation($booking,$payment,$request);
  823. }
  824. $booking->setPaid(1);
  825. $em->persist($booking);
  826. $em->flush();
  827. //$this->mailCustomerConfirmation($booking,$payment);
  828. //$this->mailSalesConfirmation($booking,$payment);
  829. $fail = 0;
  830. $url = $this->generateUrl('successPayment', array("payment"=>$payment->getPaymentid()), UrlGeneratorInterface::ABSOLUTE_URL);
  831. if ($gateway == 2)
  832. {
  833. //added by vazquel on 2014-02-19
  834. $auth_controller = new \Authorizenet_Authorizenet($api_login, $md5_hash);
  835. $response = $auth_controller->AuthorizeSIM;
  836. //added by vazquel on 2014-02-19 (Redirect to the payment success page)
  837. if ($response->isAuthorizeNet())
  838. return new Response($this->getRelayResponseSnippet($fullDomain.$url));
  839. else
  840. return $this->redirect($url);
  841. }
  842. else
  843. return $this->redirect($url);
  844. } else
  845. $fail=1;
  846. } else
  847. $fail=2;
  848. if ($fail == 1)
  849. {
  850. $url = $this->generateUrl('failurePayment', array("payment"=>$payment->getPaymentid()), UrlGeneratorInterface::ABSOLUTE_URL);
  851. if ($gateway == 2)
  852. {
  853. $this->mailSalesFailure($payment);
  854. $auth_controller = new \Authorizenet_Authorizenet($api_login, $md5_hash);
  855. $response = $auth_controller->AuthorizeSIM;
  856. if ($response->isAuthorizeNet())
  857. return new Response($this->getRelayResponseSnippet($fullDomain.$url));
  858. else
  859. return $this->redirect($url);
  860. }
  861. else
  862. return $this->redirect($url);
  863. }
  864. }
  865. private function saveReturnData_barclays(Request $request) {
  866. $hmac_key = $this->getParameter('barclays_hmac_key');
  867. $em = $this->getDoctrine()->getManager();
  868. $payment = $em->getRepository('App\Entity\Payment')->find($request->get("merchantReference"));
  869. if ($payment)
  870. {
  871. $booking = $payment->getBooking();
  872. $data = $this->appendData_barclays($booking, $payment);
  873. $dataChk = array();
  874. $dataChk[] = $request->get("authResult");
  875. $dataChk[] = $request->get("pspReference");
  876. $dataChk[] = $request->get("merchantReference");
  877. $dataChk[] = $request->get("skinCode");
  878. $dataChk[] = $request->get("merchantReturnData");
  879. $sig = base64_encode(hash_hmac('sha1',implode("", $dataChk),$hmac_key,true));
  880. if ($sig==$request->get("merchantSig"))
  881. {
  882. $payment->setResulttoken($request->get("pspReference"));
  883. $payment->setAuthcode($request->get("authResult"));
  884. $payment->setSuccessful("AUTHORISED"==$request->get("authResult"));
  885. $em->persist($payment);
  886. $em->flush();
  887. return $payment;
  888. }
  889. else
  890. return false;
  891. }
  892. else
  893. return false;
  894. }
  895. private function saveReturnData_authorize(Request $request) {
  896. $hmac_key = $this->getParameter('authorize_hmac_key');
  897. $api_login = $this->getParameter('authorize_api_login');
  898. $md5_hash = $this->getParameter('authorize_md5_hash');
  899. $em = $this->doctrine->getManager();
  900. $payment = $em->getRepository('App\Entity\Payment')->find($request->get("x_invoice_num"));
  901. $gateway = new \Authorizenet_Authorizenet($api_login, $md5_hash);
  902. $response = $gateway->AuthorizeSIM;
  903. if ($response->isAuthorizeNet() && $payment instanceof Payment)
  904. {
  905. $payment->setResulttoken($response->authorization_code);
  906. $payment->setAuthcode($response->response_reason_code);
  907. $payment->setSuccessful($response->approved*1);
  908. $payment->setNotification(serialize($response));
  909. $em->persist($payment);
  910. $em->flush();
  911. return $payment;
  912. }
  913. else
  914. die( "Error. Check your MD5 Setting.<br>Received: $response->md5_hash<br>Calculated: ".$response->generateHash());
  915. }
  916. private function saveReturnData_moneyswap(Request $request) {
  917. $moneyswap_aid = $this->getParameter('moneyswap_aid');
  918. $moneyswap_md5_signature = $this->getParameter('moneyswap_md5_signature');
  919. $em = $this->getDoctrine()->getManager();
  920. $payment = $em->getRepository('App\Entity\Payment')->find($request->get("orderNum"));
  921. if ($payment)
  922. {
  923. $booking = $payment->getBooking();
  924. $query = "version=".$request->get("version");
  925. $query .= "&charSet=".$request->get("charSet");
  926. $query .= "&transType=".$request->get("transType");
  927. $query .= "&orderNum=".$request->get("orderNum");
  928. $query .= "&orderAmount=".$request->get("orderAmount");
  929. $query .= "&orderCurrency=".$request->get("orderCurrency");
  930. $query .= "&settAmount=".$request->get("settAmount");
  931. $query .= "&settCurrency=".$request->get("settCurrency");
  932. $query .= "&rate=".$request->get("rate");
  933. $query .= "&merReserve=".$request->get("merReserve");
  934. $query .= "&transID=".$request->get("transID");
  935. $query .= "&merID=".$request->get("merID");
  936. $query .= "&acqID=".$request->get("acqID");
  937. $query .= "&paymentSchema=".$request->get("paymentSchema");
  938. $query .= "&RespCode=".$request->get("RespCode");
  939. $query .= "&RespMsg=".$request->get("RespMsg");
  940. $query .= "&transTime=".$request->get("transTime");
  941. $query .= "&GWTime=".$request->get("GWTime");
  942. $query .= "&signType=".$request->get("signType");
  943. $query .= "&signature=".$request->get("signature");
  944. $isValid = MoneySwapHelper::verifySignature($moneyswap_md5_signature, $query);
  945. if ($isValid)
  946. {
  947. $payment->setResulttoken($request->get("RespMsg"));
  948. $payment->setAuthcode($request->get("RespCode"));
  949. $payment->setSuccessful("00"==$request->get("RespCode"));
  950. $payment->setNotification(serialize($query));
  951. $em->persist($payment);
  952. $em->flush();
  953. return $payment;
  954. }
  955. else
  956. return false;
  957. }
  958. else
  959. return false;
  960. }
  961. }