Skip to content

Commit

Permalink
Merge pull request #35 from PrestaShop/feature/add_webhook_states
Browse files Browse the repository at this point in the history
Feature/add webhook states
  • Loading branch information
apacios authored Jul 3, 2019
2 parents 897fa96 + 62d787c commit 42203b8
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 136 deletions.
2 changes: 2 additions & 0 deletions classes/OrderState.php → classes/OrderStates.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class OrderStates
{
const MODULE_NAME = 'ps_checkout';
const ORDER_STATE_TEMPLATE = 'payment';
const ORDER_TABLE = 'orders';
const ORDER_HISTORY_TABLE = 'order_history';
const ORDER_STATE_TABLE = 'order_state';
const ORDER_STATE_LANG_TABLE = 'order_state_lang';
const BLUE_HEXA_COLOR = '#4169E1';
Expand Down
59 changes: 48 additions & 11 deletions classes/WebHookOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

class WebHookOrder
{
const REFUND_STATE = 'PS_CHECKOUT_STATE_PARTIAL_REFUND';
/**
* Tell if refund is initiate by Paypal or Merchant
*
Expand Down Expand Up @@ -61,15 +62,23 @@ class WebHookOrder
*
* @param string $initiateBy
* @param array $resource
* @param int $orderId
*/
public function __construct($initiateBy, $resource)
public function __construct($initiateBy, $resource, $orderId)
{
$paypalOrderRepository = new PaypalOrderRepository();

$this->initiateBy = (string) $initiateBy;
$this->orderId = (int) $paypalOrderRepository->getPsOrderIdByPaypalOrderId($resource['orderId']);
$this->amount = (float) $resource['amount']['value'];
$this->currencyId = (string) \Currency::getIdByIsoCode($resource['amount']['currency']);
$this->orderId = $paypalOrderRepository->getPsOrderIdByPaypalOrderId($orderId);

if (false === $this->orderId) {
/*
* @TODO : Throw array exception
*/
}

$this->amount = (float) $resource['amount']->value;
$this->currencyId = (string) \Currency::getIdByIsoCode($resource['amount']->currency_code);
}

/**
Expand Down Expand Up @@ -181,13 +190,41 @@ private function refundOrder(\Order $order, $orderProductList)
$refundAddTax = true;
$refundVoucherChoosen = false;

return \OrderSlip::create(
$order,
$orderProductList,
$refundShipping,
$refundVoucher,
$refundVoucherChoosen,
$refundAddTax
// If all products have already been refunded, that catch
try {
$refundOrder = (bool) \OrderSlip::create(
$order,
$orderProductList,
$refundShipping,
$refundVoucher,
$refundVoucherChoosen,
$refundAddTax
);
} catch (\Exception $e) {
$refundOrder = false;
}

if (true !== $refundOrder) {
/*
* @TODO : Throw array exception
*/
return false;
}

$order = new \OrderHistory();
$order->id_order = $this->orderId;

$order->changeIdOrderState(
\Configuration::get(self::REFUND_STATE),
$this->orderId
);

if (true !== $order->save()) {
/*
* @TODO : Throw array exception
*/
}

return true;
}
}
83 changes: 54 additions & 29 deletions classes/webHookDispatcher/OrderDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,38 @@

namespace PrestaShop\Module\PrestashopCheckout;

class OrderDispatcher implements InterfaceDispatcher
class OrderDispatcher
{
const PS_CHECKOUT_PAYMENT_REVERSED = 'PAYMENT.CAPTURE.REVERSED';
const PS_CHECKOUT_PAYMENT_REFUNED = 'PAYMENT.CAPTURE.REFUNDED';
const PS_CHECKOUT_PAYMENT_AUTH_VOIDED = 'PAYMENT.AUTHORIZATION.VOIDED';
const PS_CHECKOUT_PAYMENT_PENDING = 'PAYMENT.CAPTURE.PENDING';
const PS_CHECKOUT_PAYMENT_COMPLETED = 'PAYMENT.CAPTURE.COMPLETED';
const PS_CHECKOUT_PAYMENT_DENIED = 'PAYMENT.CAPTURE.DENIED';
const PS_EVENTTYPE_TO_PS_STATE_ID = array(
self::PS_CHECKOUT_PAYMENT_AUTH_VOIDED => 6, // Canceled
self::PS_CHECKOUT_PAYMENT_PENDING => 3, // Processing in progress
self::PS_CHECKOUT_PAYMENT_COMPLETED => 2, // Payment accepted
self::PS_CHECKOUT_PAYMENT_DENIED => 8, // Payment error
);

/**
* Dispatch the Event Type to manage the merchant status
*
* @param string $eventType
* @param array $resource
* @param array $payload
*/
public function dispatchEventType($eventType, $resource)
public function dispatchEventType($payload)
{
if ($eventType === self::PS_CHECKOUT_PAYMENT_REFUNED
|| $eventType === self::PS_CHECKOUT_PAYMENT_REVERSED) {
$this->dispatchPaymentAction($eventType, $resource);
if ($payload['eventType'] === self::PS_CHECKOUT_PAYMENT_REFUNED
|| $payload['eventType'] === self::PS_CHECKOUT_PAYMENT_REVERSED) {
$this->dispatchPaymentAction($payload['eventType'], $payload['resource'], $payload['orderId']);
}

if ($eventType === self::PS_CHECKOUT_PAYMENT_PENDING
|| $eventType === self::PS_CHECKOUT_PAYMENT_COMPLETED
|| $eventType === self::PS_CHECKOUT_PAYMENT_DENIED
|| $eventType === self::PS_CHECKOUT_PAYMENT_AUTH_VOIDED) {
$this->dispatchPaymentStatus($eventType, $resource);
if ($payload['eventType'] === self::PS_CHECKOUT_PAYMENT_PENDING
|| $payload['eventType'] === self::PS_CHECKOUT_PAYMENT_COMPLETED
|| $payload['eventType'] === self::PS_CHECKOUT_PAYMENT_DENIED
|| $payload['eventType'] === self::PS_CHECKOUT_PAYMENT_AUTH_VOIDED) {
$this->dispatchPaymentStatus($payload['eventType'], $payload['orderId']);
}
}

Expand All @@ -61,12 +66,17 @@ public function dispatchEventType($eventType, $resource)
*
* @param string $eventType
* @param array $resource
* @param int $orderId
*/
private function dispatchPaymentAction($eventType, $resource)
private function dispatchPaymentAction($eventType, $resource, $orderId)
{
$orderError = (new WebHookValidation())->validateRefundResourceValues($resource);
$validationValues = new WebHookValidation();
$orderError = array_merge(
$validationValues->validateRefundResourceValues($resource),
$validationValues->validateRefundOrderIdValue($orderId)
);

if (true !== $orderError) {
if (!empty($orderError)) {
/*
* @TODO : Throw array exception
*/
Expand All @@ -78,34 +88,49 @@ private function dispatchPaymentAction($eventType, $resource)
$initiateBy = 'Paypal';
}

$order = new WebHookOrder($initiateBy, $resource);
$order = new WebHookOrder($initiateBy, $resource, $orderId);
$order->updateOrder();
}

/**
* Dispatch the event Type the the payment status PENDING / COMPLETED / DENIED
* Dispatch the event Type the the payment status PENDING / COMPLETED / DENIED / AUTH_VOIDED
*
* @param string $eventType
* @param array $resource
* @param int $orderIdgst
*/
private function dispatchPaymentStatus($eventType, $resource)
private function dispatchPaymentStatus($eventType, $orderId)
{
$states = new OrderStates();
$validationValues = new WebHookValidation();
$orderError = $validationValues->validateRefundOrderIdValue($orderId);

if ($eventType === self::PS_CHECKOUT_PAYMENT_PENDING) {
// $states->dispatchPaymentStatus($eventType, $resource);
if (!empty($orderError)) {
/*
* @TODO : Throw array exception
*/
}

if ($eventType === self::PS_CHECKOUT_PAYMENT_COMPLETED) {
// $states->dispatchPaymentStatus($eventType, $resource);
}
$paypalOrderRepository = new PaypalOrderRepository();
$psOrderId = $paypalOrderRepository->getPsOrderIdByPaypalOrderId($orderId);

if ($eventType === self::PS_CHECKOUT_PAYMENT_DENIED) {
// $states->dispatchPaymentStatus($eventType, $resource);
if (false === $psOrderId) {
/*
* @TODO : Throw array exception
*/
return false;
}

if ($eventType === self::PS_CHECKOUT_PAYMENT_AUTH_VOIDED) {
// $states->dispatchPaymentStatus($eventType, $resource);
$order = new \OrderHistory();
$order->id_order = $psOrderId;

$order->changeIdOrderState(
self::PS_EVENTTYPE_TO_PS_STATE_ID[$eventType],
$psOrderId
);

if (true !== $order->save()) {
/*
* @TODO : Throw array exception
*/
}
}
}
70 changes: 32 additions & 38 deletions classes/webHookValidation/WebHookValidation.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,38 +45,22 @@ public function validateHeaderDatas(array $headerValues)
$errors = array();

if (empty($headerValues)) {
return $errors['header'] = 'Header can\'t be empty';
return $errors[] = 'Header can\'t be empty';
}

if (empty($headerValues['Shop-Id'])) {
$errors['header'][] = 'Shop-Id can\'t be empty';
if (empty($headerValues['shop-id'])) {
$errors[] = 'Shop-Id can\'t be empty';
}

if (empty($headerValues['Merchant-Id'])) {
$errors['header'][] = 'Merchant-Id can\'t be empty';
if (empty($headerValues['merchant-id'])) {
$errors[] = 'Merchant-Id can\'t be empty';
}

if (empty($headerValues['Psx-Id'])) {
$errors['header'][] = 'Psx-Id can\'t be empty';
if (empty($headerValues['psx-id'])) {
$errors[] = 'Psx-Id can\'t be empty';
}

if (!in_array($headerValues['category'], self::ALLOWED_CATEGORIES)) {
$errors['header'][] = sprintf('Category must be one of these values: %s', implode(', ', self::ALLOWED_CATEGORIES));
}

if (!is_string($headerValues['eventType'])) {
$errors['header'][] = 'eventType must be a string';
}

if (empty($headerValues['eventType'])) {
$errors['header'][] = 'eventType can\'t be empty';
}

if (!empty($errors)) {
return $errors;
}

return true;
return $errors;
}

/**
Expand All @@ -91,33 +75,43 @@ public function validateRefundResourceValues(array $resource)
$errors = array();

if (empty($resource)) {
return $errors['resource'] = 'Resource can\'t be empty';
return $errors[] = 'Resource can\'t be empty';
}

if (empty($resource['amount'])) {
$errors['amount'][] = 'Amount can\'t be empty';
$errors[] = 'Amount can\'t be empty';
}

if (empty($resource['amount']['value'])) {
$errors['amount'][] = 'Amount value can\'t be empty';
if (empty($resource['amount']->value)) {
$errors[] = 'Amount value can\'t be empty';
}

if (0 >= $resource['amount']['value']) {
$errors['amount'][] = 'Amount value must be higher than 0';
if (0 >= (float) $resource['amount']->value) {
$errors[] = 'Amount value must be higher than 0';
}

if (empty($resource['amount']['currency'])) {
$errors['amount'][] = 'Amount currency can\'t be empty';
if (empty($resource['amount']->currency)) {
$errors[] = 'Amount currency can\'t be empty';
}

if (empty($resource['orderId'])) {
$errors['amount'][] = 'OrderId can\'t be empty';
}
return $errors;
}

/**
* Validates the webHook orderId
*
* @param int $orderId
*
* @return array|bool Error lists, bool if ok
*/
public function validateRefundOrderIdValue($orderId)
{
$errors = array();

if (!is_int($resource['orderId'])) {
$errors['amount'][] = 'OrderId must be a int';
if (empty($orderId)) {
$errors[] = 'orderId must not be empty';
}

return true;
return $errors;
}
}
Loading

0 comments on commit 42203b8

Please sign in to comment.