293 lines
11 KiB
PHP
293 lines
11 KiB
PHP
<?php
|
|
|
|
use KupShop\KupShopBundle\Config;
|
|
use Ticketpark\SaferpayJson\Request\Container;
|
|
use Ticketpark\SaferpayJson\Request\Exception\HttpRequestException;
|
|
use Ticketpark\SaferpayJson\Request\Exception\SaferpayErrorException;
|
|
use Ticketpark\SaferpayJson\Request\PaymentPage\AssertRequest;
|
|
use Ticketpark\SaferpayJson\Request\PaymentPage\InitializeRequest;
|
|
use Ticketpark\SaferpayJson\Request\RequestConfig;
|
|
use Ticketpark\SaferpayJson\Request\Transaction\CaptureRequest;
|
|
|
|
/**
|
|
* Requires composer package "ticketpark/saferpay-json-api: ~4.4".
|
|
*/
|
|
class Saferpay extends Payment
|
|
{
|
|
public static $name = 'Saferpay platební brána';
|
|
|
|
public $template = 'payment.Saferpay.tpl';
|
|
|
|
public $class = 'Saferpay';
|
|
|
|
protected $pay_method = Payment::METHOD_ONLINE;
|
|
|
|
public function getPaymentUrl($step = 1)
|
|
{
|
|
return createScriptURL([
|
|
's' => '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;
|
|
}
|
|
}
|