Skip to content
Code-Schnipsel Gruppen Projekte
Commit e80bca6e erstellt von Patrick Müller's avatar Patrick Müller
Dateien durchsuchen

refactor: SCA compatibility (temp commit) #19

Übergeordneter 22c3d5c5
No related branches found
No related tags found
Keine zugehörigen Merge Requests gefunden
......@@ -4,7 +4,6 @@ use QUI\ERP\Order\Handler;
use QUI\ERP\Payments\Amazon\Payment;
use QUI\ERP\Payments\Amazon\AmazonPayException;
use QUI\Utils\Security\Orthos;
use QUI\ERP\Payments\Amazon\Provider;
/**
* Authorize Amazon Pay payment for an Order
......@@ -33,5 +32,5 @@ QUI::$Ajax->registerFunction(
return true;
},
array('orderReferenceId', 'orderHash')
['orderReferenceId', 'orderHash']
);
<?php
use QUI\ERP\Order\Handler;
use QUI\ERP\Payments\Amazon\Payment;
use QUI\ERP\Payments\Amazon\AmazonPayException;
use QUI\Utils\Security\Orthos;
/**
* Confirm an order with Amazon Pay
*
* @param string $orderReferenceId - Amazon OrderReferenceId; if false try to retrieve from Order
* @param string $orderHash - Unique order hash to identify Order
* @return bool - success
* @throws AmazonPayException
*/
QUI::$Ajax->registerFunction(
'package_quiqqer_payment-amazon_ajax_confirmOrder',
function ($orderReferenceId, $orderHash) {
$orderHash = Orthos::clear($orderHash);
try {
$Order = Handler::getInstance()->getOrderByHash($orderHash);
$Payment = new Payment();
$Payment->confirmOrder($orderReferenceId, $Order);
} catch (AmazonPayException $Exception) {
QUI\System\Log::writeDebugException($Exception);
throw $Exception;
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
return false;
}
return true;
},
['orderReferenceId', 'orderHash']
);
<?php
define('QUIQQER_SYSTEM', true);
require_once dirname(dirname(dirname(dirname(__FILE__)))).'/header.php';
use QUI\ERP\Order\Handler;
use QUI\ERP\Payments\Amazon\AmazonPayException;
use QUI\ERP\Payments\Amazon\Payment;
use Symfony\Component\HttpFoundation\RedirectResponse;
use \Symfony\Component\HttpFoundation\Response;
use QUI\Utils\Security\Orthos;
use QUI\ERP\Accounting\Payments\Order\Payment as OrderProcessStepPayments;
use QUI\ERP\Order\Controls\OrderProcess\Finish as OrderProcessStepFinish;
function badRequest()
{
$Response = QUI::getGlobalResponse();
$Response->setStatusCode(Response::HTTP_BAD_REQUEST);
$Response->send();
exit;
}
if (empty($_REQUEST['hash'])) {
badRequest();
}
$orderHash = Orthos::clear($_REQUEST['hash']);
try {
$Order = Handler::getInstance()->getOrderByHash($orderHash);
$OrderProcess = new QUI\ERP\Order\OrderProcess([
'orderHash' => $orderHash
]);
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
badRequest();
}
if (!empty($_REQUEST['ErrorCode'])) {
$OrderProcess->addStepMessage(
Payment::MESSAGE_ID_ERROR_SCA_FAILURE,
Payment::class,
OrderProcessStepPayments::class
);
} elseif (empty($_REQUEST['AuthenticationStatus'])) {
badRequest();
}
// Default step = payment select
$GoToStep = new OrderProcessStepPayments([
'Order' => $Order
]);
if ($_REQUEST['AuthenticationStatus'] === 'Success') {
// If the SCA was successful -> Authorize the Order
try {
/** @var Payment $AmazonPayment */
$AmazonPayment = $Order->getPayment()->getPaymentType();
$AmazonPayment->authorizePayment($Order);
// Go to finish step if authorization was successful
$GoToStep = new OrderProcessStepFinish([
'Order' => $Order
]);
$OrderProcess->clearStepMessages();
} catch (AmazonPayException $Exception) {
$amazonErrorCode = $Exception->getAttribute('amazonErrorCode');
if (!empty($amazonErrorCode)) {
$OrderProcess->addStepMessage(
$amazonErrorCode,
Payment::class,
OrderProcessStepPayments::class
);
} else {
$OrderProcess->addStepMessage(
Payment::MESSAGE_ID_ERROR_INTERNAL,
Payment::class,
OrderProcessStepPayments::class
);
}
} catch (\Exception $Exception) {
$OrderProcess->addStepMessage(
Payment::MESSAGE_ID_ERROR_INTERNAL,
Payment::class,
OrderProcessStepPayments::class
);
}
} else {
$OrderProcess->addStepMessage(
Payment::MESSAGE_ID_ERROR_INTERNAL,
Payment::class,
OrderProcessStepPayments::class
);
}
$processingUrl = $OrderProcess->getStepUrl($GoToStep->getName());
// Redirect to OrderProcess
$Redirect = new RedirectResponse($processingUrl);
$Redirect->setStatusCode(Response::HTTP_SEE_OTHER);
echo $Redirect->getContent();
$Redirect->send();
exit;
......@@ -50,6 +50,7 @@ define('package/quiqqer/payment-amazon/bin/controls/PaymentDisplay', [
this.$PayBtn = null;
this.$MsgElm = null;
this.$OrderProcess = null;
this.$confirmationFlow = null; // Reference to Amazon Pay Confirmation Flow
this.addEvents({
onImport: this.$onImport
......@@ -337,9 +338,12 @@ define('package/quiqqer/payment-amazon/bin/controls/PaymentDisplay', [
QUILocale.get(pkg, 'controls.PaymentDisplay.authorize_payment')
);
self.$authorizePayment().then(function (success) {
self.$initConfirmationFlow().then(function () {
return self.$confirmOrder();
}).then(function (success) {
if (success) {
self.$OrderProcess.next();
self.$confirmationFlow.success();
//self.$OrderProcess.next();
return;
}
......@@ -353,6 +357,65 @@ define('package/quiqqer/payment-amazon/bin/controls/PaymentDisplay', [
Btn.enable();
Btn.setAttribute('textimage', 'fa fa-amazon');
//self.$authorizePayment().then(function (success) {
// if (success) {
// self.$confirmationFlow.success();
// //self.$OrderProcess.next();
// return;
// }
//
// self.$OrderProcess.Loader.hide();
//
// self.$showErrorMsg(
// QUILocale.get(pkg, 'controls.PaymentDisplay.processing_error')
// );
//
// self.$showAmazonWallet(false);
//
// Btn.enable();
// Btn.setAttribute('textimage', 'fa fa-amazon');
//}, function (error) {
// self.$OrderProcess.Loader.hide();
// self.$showErrorMsg(error.getMessage());
//
// if (error.getAttribute('orderCancelled')) {
// self.$orderReferenceId = false;
// }
//
// // abort Amazon Pay initConfirmationFlow
// self.$confirmationFlow.error();
//
// if (error.getAttribute('reRenderWallet')) {
// self.$WalletElm.removeClass('quiqqer-payment-amazon__hidden');
// self.$showAmazonWallet(false);
//
// Btn.enable();
// Btn.setAttribute('textimage', 'fa fa-amazon');
//
// self.fireEvent('processingError', [self]);
// return;
// }
//
// // sign out
// amazon.Login.logout();
// Btn.destroy();
//
// self.$showErrorMsg(
// QUILocale.get(pkg, 'controls.PaymentDisplay.fatal_error')
// );
//
// new QUIButton({
// text : QUILocale.get(pkg, 'controls.PaymentDisplay.btn_reselect_payment.text'),
// texticon: 'fa fa-credit-card',
// events : {
// onClick: function () {
// window.location.reload();
// }
// }
// }).inject(self.getElm().getElement('#quiqqer-payment-amazon-btn-pay'))
//});
}, function (error) {
self.$OrderProcess.Loader.hide();
self.$showErrorMsg(error.getMessage());
......@@ -361,6 +424,9 @@ define('package/quiqqer/payment-amazon/bin/controls/PaymentDisplay', [
self.$orderReferenceId = false;
}
// abort Amazon Pay initConfirmationFlow
self.$confirmationFlow.error();
if (error.getAttribute('reRenderWallet')) {
self.$WalletElm.removeClass('quiqqer-payment-amazon__hidden');
self.$showAmazonWallet(false);
......@@ -388,7 +454,46 @@ define('package/quiqqer/payment-amazon/bin/controls/PaymentDisplay', [
window.location.reload();
}
}
}).inject(self.getElm().getElement('#quiqqer-payment-amazon-btn-pay'))
}).inject(self.getElm().getElement('#quiqqer-payment-amazon-btn-pay'));
});
},
/**
* Init SCA-compatible confirmation flow
*
* @return {Promise}
*/
$initConfirmationFlow: function () {
var self = this;
return new Promise(function (resolve, reject) {
OffAmazonPayments.initConfirmationFlow(
self.getAttribute('sellerid'),
self.$orderReferenceId,
function (confirmationFlow) {
self.$confirmationFlow = confirmationFlow;
resolve();
},
reject
);
});
},
/**
* Confirm order with Amazon Pay
*
* @return {Promise}
*/
$confirmOrder: function () {
var self = this;
return new Promise(function (resolve, reject) {
QUIAjax.post('package_quiqqer_payment-amazon_ajax_confirmOrder', resolve, {
'package' : pkg,
orderHash : self.getAttribute('orderhash'),
orderReferenceId: self.$orderReferenceId,
onError : reject
})
});
},
......
......@@ -249,6 +249,14 @@
<de><![CDATA[Der Rückzahlungs-Vorgang bei Amazon konnte nicht durchgeführt werden, da die Bestellung auf Seite von Amazon noch nicht vollständig bezahlt wurde.]]></de>
<en><![CDATA[The refund process with Amazon could not be completed because the order has not yet been fully paid/captured on the Amazon side.]]></en>
</locale>
<locale name="Payment.message.error.sca_failure">
<de><![CDATA[Mit dieser Zahlungsart ist ein Problem aufgetreten. Um Ihre Bestellung abzuschließen, wählen Sie bitte eine andere aus.]]></de>
<en><![CDATA[Something's wrong with your payment method. To place your order, try another.]]></en>
</locale>
<locale name="Payment.message.error.internal">
<de><![CDATA[Der Zahlungsvorgang mit Amazon war nicht erfolgreich. Ihr gewähltes Zahlungsmittel wurde nicht belastet. Bitte versuchen Sie es erneut oder wählen Sie eine andere Zahlungsmethode.]]></de>
<en><![CDATA[The payment process with Amazon was not successful. Your chosen payment method was not debited. Please try again or choose another payment method.]]></en>
</locale>
</groups>
......
......@@ -12,11 +12,14 @@ use QUI\ERP\Order\Handler as OrderHandler;
use QUI\ERP\Accounting\Payments\Gateway\Gateway;
use QUI\ERP\Accounting\Payments\Transactions\Factory as TransactionFactory;
use QUI\ERP\Accounting\Payments\Transactions\Handler as TransactionHandler;
use QUI\ERP\Order\OrderProcess\OrderProcessMessage;
/**
* Class Payment
*/
class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
class Payment
extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
implements QUI\ERP\Order\OrderProcess\OrderProcessMessageHandlerInterface
{
/**
* Amazon API Order attributes
......@@ -28,6 +31,7 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
const ATTR_AMAZON_REFUND_ID = 'amazon-RefundId';
const ATTR_CAPTURE_REFERENCE_IDS = 'amazon-CaptureReferenceIds';
const ATTR_ORDER_REFUND_DETAILS = 'amazon-RefundDetails';
const ATTR_ORDER_CONFIRMED = 'amazon-OrderConfirmed';
const ATTR_ORDER_AUTHORIZED = 'amazon-OrderAuthorized';
const ATTR_ORDER_CAPTURED = 'amazon-OrderCaptures';
const ATTR_ORDER_REFERENCE_SET = 'amazon-OrderReferenceSet';
......@@ -40,6 +44,12 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
const SETTING_ARTICLE_TYPE_PHYSICAL = 'physical';
const SETTING_ARTICLE_TYPE_DIGITAL = 'digital';
/**
* Messages
*/
const MESSAGE_ID_ERROR_SCA_FAILURE = 1;
const MESSAGE_ID_ERROR_INTERNAL = 2;
/**
* Error codes
*/
......@@ -297,21 +307,21 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
* @throws QUI\ERP\Exception
* @throws QUI\Exception
*/
public function authorizePayment($orderReferenceId, AbstractOrder $Order)
public function confirmOrder($orderReferenceId, AbstractOrder $Order)
{
$Order->addHistory('Amazon Pay :: Authorize payment');
$Order->addHistory('Amazon Pay :: Confirm order');
if ($Order->getPaymentDataEntry(self::ATTR_ORDER_AUTHORIZED)) {
$Order->addHistory('Amazon Pay :: Authorization already exist');
$reConfirm = $Order->getPaymentDataEntry(self::ATTR_RECONFIRM_ORDER);
if ($Order->getPaymentDataEntry(self::ATTR_ORDER_CONFIRMED) && !$reConfirm) {
$Order->addHistory('Amazon Pay :: Order already confirmed');
return;
}
$AmazonPay = $this->getAmazonPayClient();
$PriceCalculation = $Order->getPriceCalculation();
$reconfirmOrder = $Order->getPaymentDataEntry(self::ATTR_RECONFIRM_ORDER);
$AmazonPay = $this->getAmazonPayClient();
// Re-confirm Order after previously declined Authorization because of "InvalidPaymentMethod"
if ($reconfirmOrder) {
if ($reConfirm) {
$Order->addHistory(
'Amazon Pay :: Re-confirm Order after declined Authorization because of "InvalidPaymentMethod"'
);
......@@ -325,6 +335,7 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
$this->getResponseData($Response); // check response data
$Order->setPaymentData(self::ATTR_RECONFIRM_ORDER, false);
$Order->setPaymentData(self::ATTR_ORDER_CONFIRMED, true);
$Order->addHistory('Amazon Pay :: OrderReference re-confirmed');
} elseif (!$Order->getPaymentDataEntry(self::ATTR_ORDER_REFERENCE_SET)) {
......@@ -332,6 +343,8 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
'Amazon Pay :: Setting details of the Order to Amazon Pay API'
);
$PriceCalculation = $Order->getPriceCalculation();
$Response = $AmazonPay->setOrderReferenceDetails([
'amazon_order_reference_id' => $orderReferenceId,
'amount' => $PriceCalculation->getSum()->precision(2)->get(),
......@@ -350,7 +363,7 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
$response = $this->getResponseData($Response);
$orderReferenceDetails = $response['SetOrderReferenceDetailsResult']['OrderReferenceDetails'];
if (isset($orderReferenceDetails['Constraints']['Constraint']['ConstraintID'])) {
if (!empty($orderReferenceDetails['Constraints']['Constraint']['ConstraintID'])) {
$Order->addHistory(
'Amazon Pay :: An error occurred while setting the details of the Order: "'
.$orderReferenceDetails['Constraints']['Constraint']['ConstraintID'].'""'
......@@ -365,12 +378,40 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
}
$AmazonPay->confirmOrderReference([
'amazon_order_reference_id' => $orderReferenceId
'amazon_order_reference_id' => $orderReferenceId,
'success_url' => $this->getSuccessUrl($Order),
'failure_url' => $this->getFailureUrl($Order)
]);
$Order->setPaymentData(self::ATTR_ORDER_REFERENCE_SET, true);
$Order->setPaymentData(self::ATTR_ORDER_CONFIRMED, true);
$Order->setPaymentData(self::ATTR_AMAZON_ORDER_REFERENCE_ID, $orderReferenceId);
$Order->update(QUI::getUsers()->getSystemUser());
}
}
/**
* Authorize the payment for an Order with Amazon
*
* @param AbstractOrder $Order
*
* @throws AmazonPayException
* @throws QUI\ERP\Exception
* @throws QUI\Exception
*/
public function authorizePayment(AbstractOrder $Order)
{
$Order->addHistory('Amazon Pay :: Authorize payment');
if ($Order->getPaymentDataEntry(self::ATTR_ORDER_AUTHORIZED)) {
$Order->addHistory('Amazon Pay :: Authorization already exist');
return;
}
$AmazonPay = $this->getAmazonPayClient();
$PriceCalculation = $Order->getPriceCalculation();
$orderReferenceId = $Order->getPaymentDataEntry(self::ATTR_AMAZON_ORDER_REFERENCE_ID);
$Order->addHistory('Amazon Pay :: Requesting new Authorization');
......@@ -392,7 +433,7 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
$this->addAuthorizationReferenceIdToOrder($authorizationReferenceId, $Order);
$Order->setPaymentData(self::ATTR_AMAZON_AUTHORIZATION_ID, $amazonAuthorizationId);
$Order->setPaymentData(self::ATTR_AMAZON_ORDER_REFERENCE_ID, $orderReferenceId);
$Order->addHistory(
QUI::getLocale()->get(
'quiqqer/payment-amazon',
......@@ -846,7 +887,8 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
case 'AmazonRejected':
case 'ProcessingFailure':
case 'MaxCapturesProcessed':
$msg = $L->get($lg, 'payment.error_msg.'.$errorCode);
$msg = $L->get($lg, 'payment.error_msg.'.$errorCode);
$exceptionAttributes['amazonErrorCode'] = $errorCode;
break;
}
......@@ -1058,4 +1100,59 @@ class Payment extends QUI\ERP\Accounting\Payments\Api\AbstractPayment
{
$Process->addHistory('Amazon Pay :: '.$message);
}
/**
* Get confirmation flow success url
*
* @param AbstractOrder $Order
* @return string
*/
protected function getSuccessUrl(AbstractOrder $Order)
{
return Payments::getInstance()->getHost().
URL_OPT_DIR.
'quiqqer/payment-amazon/bin/confirmation.php?hash='.$Order->getHash();
}
/**
* Get confirmation flow error url
*
* @param AbstractOrder $Order
* @return string
*/
protected function getFailureUrl(AbstractOrder $Order)
{
return Payments::getInstance()->getHost().
URL_OPT_DIR.
'quiqqer/payment-amazon/bin/confirmation.php?hash='.$Order->getHash().'&error=1';
}
/**
* @param int $id
* @return OrderProcessMessage
*/
public static function getMessage(int $id)
{
$L = QUI::getLocale();
$lg = 'quiqqer/payment-amazon';
switch ($id) {
case self::MESSAGE_ID_ERROR_SCA_FAILURE:
$msg = $L->get($lg, 'Payment.message.error.sca_failure');
$type = OrderProcessMessage::MESSAGE_TYPE_ERROR;
break;
case self::MESSAGE_ID_ERROR_INTERNAL:
$msg = $L->get($lg, 'Payment.message.error.internal');
$type = OrderProcessMessage::MESSAGE_TYPE_ERROR;
break;
default:
$msg = $L->get($lg, 'payment.error_msg.'.$id);
$type = OrderProcessMessage::MESSAGE_TYPE_ERROR;
}
return new OrderProcessMessage($msg, $type);
}
}
0% oder .
You are about to add 0 people to the discussion. Proceed with caution.
Bearbeitung dieser Nachricht zuerst beenden!
Bitte registrieren oder zum Kommentieren