'payment', 'IDo' => $this->order->id, 'cf' => $this->order->getSecurityCode(), 'step' => $step, 'class' => $this->class, 'paymentId' => $this->paymentId, 'absolute' => true, ]); } private function getPayment($id = null) { if (isset($id)) { $payment = $this->selectSQL('order_payments', ['id' => $id]) ->fetch(); if (!$payment) { $this->step(-3, 'storno'); } $payment['decoded_data'] = json_decode($payment['payment_data']); return $payment; } $kupshopPayment = $this->getPendingPayment(); if (!$kupshopPayment) { $kupshopPayment = $this->initializeSaferpayPayment(); } $this->paymentId = $kupshopPayment['id']; return $kupshopPayment; } /** * @return array $kupshopPayment */ private function initializeSaferpayPayment(): array { $amount = roundPrice($this->order->getRemainingPayment())->asFloat(); $this->createPayment( null, $amount, ['paymentClass' => self::class] ); // ----------------------------- // Step 1: // Initialize the required payment page data // See https://saferpay.github.io/jsonapi/#Payment_v1_PaymentPage_Initialize $requestConfig = new RequestConfig( $this->config['apiKey'], $this->config['apiSecret'], $this->config['customerID'], getVal('test', $this->config, false) ); $containerAmount = new Container\Amount( $amount * 100, // amount in cents $this->order->currency ); $containerPayment = new Container\Payment($containerAmount); $containerPayment ->setOrderId($this->order->order_no) ->setDescription('Order No. '.$this->order->order_no); $returnUrls = new Container\ReturnUrls( $this->getPaymentUrl(2), $this->getPaymentUrl(3), $this->getPaymentUrl(3) ); // ----------------------------- // Step 2: // Create the request with required data $initializeRequest = new InitializeRequest( $requestConfig, $this->config['terminalID'], $containerPayment, $returnUrls ); $containerAddress = (new Container\Address()) ->setFirstName($this->order->invoice_name) ->setLastName($this->order->invoice_surname) ->setStreet($this->order->invoice_street) ->setZip($this->order->invoice_zip) ->setCity($this->order->invoice_city) ->setCountryCode($this->order->invoice_country); $containerPayer = (new Container\Payer()) ->setLanguageCode('de') ->setBillingAddress($containerAddress); $initializeRequest->setPayer($containerPayer); // Note: More data can be provided to InitializeRequest with setters, // for example: $initializeRequest->setPayer() // See Saferpay documentation for available options. // ----------------------------- // Step 3: // Execute and check for successful response try { $response = $initializeRequest->execute(); } catch (SaferpayErrorException $e) { logError(__FILE__, __LINE__, 'Saferpay::initializeSaferpayPayment: ErrorResponse! ErrorName: '.$e->getErrorResponse()->getErrorName().', errorDetail: '.json_encode($e->getErrorResponse()->getErrorDetail())); if (!$this->setStatus(Payment::STATUS_STORNO, $this->paymentId)) { throw new Exception('Saferpay::updatePaymentStatus: setStatus failed!'); } $this->step(-3, 'storno'); } catch (HttpRequestException $e) { $this->deletePayment(); $this->step(-1, 'Server error. Try again please.'); } // Save the response token, you will need it later to verify the payment $token = $response->getToken(); // Redirect to the payment page $redirectURL = $response->getRedirectUrl(); $paymentRow = $this->selectSQL('order_payments', ['id' => $this->paymentId])->fetch(); $json = json_decode($paymentRow['payment_data']); $json->session = $this->paymentId; $json->token = $token; $json->redirectURL = $redirectURL; $paymentRow['payment_data'] = json_encode($json); $logger = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService('logger'); $logger->notice('Saferpay:initializeSaferpayPayment(): '.$paymentRow['id_order'], ['response' => $response, 'paymentRow' => $paymentRow]); $this->updateSQL('order_payments', $paymentRow, ['id' => $this->paymentId]); $paymentRow['decoded_data'] = $json; return $paymentRow; } /* Payment steps */ public function processStep_1() { $amount = roundPrice($this->order->getRemainingPayment())->asFloat(); if ($amount <= (float) 0) { $this->step(-3, 'storno'); } $payment = $this->getPayment(); if (!isset($payment['decoded_data']->redirectURL)) { $this->updateSQL('order_payments', ['status' => Payment::STATUS_STORNO], ['id' => $payment['id']]); $payment = $this->getPayment(); } redirection($payment['decoded_data']->redirectURL); } public function processStep_2() { $payment = $this->getPayment(getVal('paymentId', null, false)); // Return success if payment already finished if ($payment['status'] === strval(Payment::STATUS_FINISHED)) { $this->success(translate('paymentSuccess', 'payment')); } $token = $payment['decoded_data']->token; // ----------------------------- // Step 1: // Prepare the assert request // See http://saferpay.github.io/jsonapi/#Payment_v1_PaymentPage_Assert $requestConfig = new RequestConfig( $this->config['apiKey'], $this->config['apiSecret'], $this->config['customerID'], getVal('test', $this->config, false) ); // ----------------------------- // Step 2: // Create the request with required data $assertRequest = new AssertRequest( $requestConfig, $token, ); // ----------------------------- // Step 3: // Execute and check for successful response try { $response = $assertRequest->execute(); } catch (SaferpayErrorException $e) { $logger = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService('logger'); $logger->notice('Saferpay:processStep_2() ErrorResponse: '.$payment['id_order'], ['response' => $e->getErrorResponse(), 'payment' => $payment]); if (!$this->setStatus(Payment::STATUS_STORNO, $payment['id'])) { throw new Exception('Saferpay::updatePaymentStatus: setStatus failed! (ErrorResponse: '.$e->getErrorResponse()->getErrorMessage().')'); } $this->step(-3, 'storno'); } // A transaction id you received with a successful assert request (see ../PaymentPage/example-assert.php) $transactionId = $response->getTransaction()->getId(); // ----------------------------- // Step 1: // Prepare the capture request // https://saferpay.github.io/jsonapi/#Payment_v1_Transaction_Capture $transactionReference = (new Container\TransactionReference()) ->setTransactionId($transactionId); // ----------------------------- // Step 2: // Create the request with required data $captureRequest = new CaptureRequest( $requestConfig, $transactionReference ); // ----------------------------- // Step 3: // Execute and check for successful response try { $captureResponse = $captureRequest->execute(); } catch (SaferpayErrorException $e) { /** @var $sentryLogger \KupShop\KupShopBundle\Util\Logging\SentryLogger */ $sentryLogger = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\KupShopBundle\Util\Logging\SentryLogger::class); $sentryLogger->captureMessage( $e->getErrorResponse()->getErrorMessage(), [], ['transaction_id' => $transactionId], true ); } // save transactionID $paymentRow = $this->selectSQL('order_payments', ['id' => $payment['id']])->fetch(); $json = json_decode($paymentRow['payment_data']); $json->transactionID = $transactionId; $paymentRow['payment_data'] = json_encode($json); $this->updateSQL('order_payments', $paymentRow, ['id' => $payment['id']]); $logger = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService('logger'); $logger->notice('Saferpay:processStep_2() finished: '.$paymentRow['id_order'], ['response' => $response, 'captureResponse' => $captureResponse, 'paymentRow' => $paymentRow]); // change payment status to finished if (!$this->setStatus(Payment::STATUS_FINISHED, $payment['id'])) { throw new Exception('Saferpay::updatePaymentStatus: setStatus failed!'); } $this->success(translate('paymentSuccess', 'payment')); } public function processStep_3() { $payment = $this->getPayment(getVal('paymentId', null, false)); if (!$this->setStatus(Payment::STATUS_STORNO, $payment['id'])) { throw new Exception('Saferpay::updatePaymentStatus: setStatus failed!'); } $this->step(-3, 'storno'); } public function hasOnlinePayment() { return true; } public static function isEnabled($className) { $cfg = Config::get(); if (empty($cfg['Modules']['payments'][$className])) { return false; } return true; } }