diff --git a/resources/js/blocks/molliePaymentMethod.js b/resources/js/blocks/molliePaymentMethod.js index 3eeb5bc0..30a9d3f2 100644 --- a/resources/js/blocks/molliePaymentMethod.js +++ b/resources/js/blocks/molliePaymentMethod.js @@ -174,11 +174,16 @@ const MollieComponent = (props) => { } } let isPhoneEmpty = (billing.billingData.phone === '' && shippingData.shippingAddress.phone === '') && inputPhone === ''; - let isBirthdateEmpty = inputBirthdate === '' + let isBirthdateValid = inputBirthdate === '' + let today = new Date(); + let birthdate = new Date(inputBirthdate); + if (birthdate > today) { + isBirthdateValid = false + } const unsubscribeProcessing = onCheckoutValidation( () => { - if (activePaymentMethod === 'mollie_wc_gateway_in3' && (isPhoneEmpty || isBirthdateEmpty)) { + if (activePaymentMethod === 'mollie_wc_gateway_in3' && (isPhoneEmpty || isBirthdateValid)) { return { errorMessage: item.errorMessage, }; diff --git a/src/Gateway/GatewayModule.php b/src/Gateway/GatewayModule.php index ad652069..ba00c453 100644 --- a/src/Gateway/GatewayModule.php +++ b/src/Gateway/GatewayModule.php @@ -8,6 +8,7 @@ use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController; use Automattic\WooCommerce\StoreApi\Exceptions\RouteException; +use DateTime; use Mollie\WooCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule; use Mollie\WooCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait; use Mollie\WooCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule; @@ -276,6 +277,7 @@ static function () { 11 ); add_action('woocommerce_rest_checkout_process_payment_with_context', [$this, 'addPhoneWhenRest'], 11); + add_action('woocommerce_rest_checkout_process_payment_with_context', [$this, 'addBirthdateWhenRest'], 11); } // Set order to paid and processed when eventually completed without Mollie @@ -659,7 +661,7 @@ public function in3FieldsMandatory($fields, $errors) $phoneLabel = __('Phone', 'mollie-payments-for-woocommerce'); $birthDateLabel = __('Birthdate', 'mollie-payments-for-woocommerce'); $fields = $this->addPaymentMethodMandatoryFieldsPhoneVerification($fields, $gatewayName, $phoneField, $phoneLabel, $errors); - return $this->addPaymentMethodMandatoryFields($fields, $gatewayName, $birthdateField, $birthDateLabel, $errors); + return $this->addPaymentMethodMandatoryFieldsBirthVerification($fields, $gatewayName, $birthdateField, $birthDateLabel, $errors); } /** @@ -675,6 +677,25 @@ public function in3FieldsMandatoryPayForOrder($order) $birthdateValue = filter_input(INPUT_POST, self::FIELD_IN3_BIRTHDATE, FILTER_SANITIZE_SPECIAL_CHARS) ?? false; $birthDateLabel = __('Birthdate', 'mollie-payments-for-woocommerce'); + if (!$birthdateValue) { + wc_add_notice( + sprintf( + __('%s is a required field.', 'woocommerce'), + "$birthDateLabel" + ), + 'error' + ); + } + $birthdateValue = $birthdateValue && $this->isBirthValid($birthdateValue) ? $birthdateValue : false; + if (!$birthdateValue) { + wc_add_notice( + sprintf( + __('%s is not a valid birthdate value.', 'woocommerce'), + "$birthDateLabel" + ), + 'error' + ); + } if (!$birthdateValue) { wc_add_notice( @@ -803,6 +824,46 @@ public function addPaymentMethodMandatoryFieldsPhoneVerification( return $fields; } + public function addPaymentMethodMandatoryFieldsBirthVerification( + $fields, + string $gatewayName, + string $field, + string $fieldLabel, + $errors + ) { + if ($fields['payment_method'] !== $gatewayName) { + return $fields; + } + if (isset($fields['billing_birthdate']) && $this->isBirthValid($fields['billing_birthdate'])) { + return $fields; + } + $fieldPosted = filter_input(INPUT_POST, $field, FILTER_SANITIZE_SPECIAL_CHARS) ?? false; + if (!$fieldPosted) { + $errors->add( + 'validation', + sprintf( + __('%s is a required field.', 'woocommerce'), + "$fieldLabel" + ) + ); + return $fields; + } + + if (!$this->isBirthValid($fieldPosted)) { + $errors->add( + 'validation', + sprintf( + __('%s is not a valid birthdate value.', 'woocommerce'), + "$fieldLabel" + ) + ); + return $fields; + } else { + $fields['billing_birthdate'] = $fieldPosted; + } + return $fields; + } + public function switchFields($data) { if (isset($data['payment_method']) && $data['payment_method'] === 'mollie_wc_gateway_in3') { @@ -825,6 +886,16 @@ private function isPhoneValid($billing_phone) return preg_match('/^\+[1-9]\d{10,13}$/', $billing_phone); } + private function isBirthValid($billing_birthdate) + { + $today = new DateTime(); + $birthdate = DateTime::createFromFormat('Y-m-d', $billing_birthdate); + if ($birthdate >= $today) { + return false; + } + return true; + } + public function addPhoneWhenRest($arrayContext) { $context = $arrayContext; @@ -849,4 +920,25 @@ public function addPhoneWhenRest($arrayContext) } } } + + public function addBirthdateWhenRest($arrayContext) + { + $context = $arrayContext; + $birthMandatoryGateways = ['mollie_wc_gateway_in3']; + $paymentMethod = $context->payment_data['payment_method']; + if (in_array($paymentMethod, $birthMandatoryGateways)) { + $billingBirthdate = $context->payment_data['billing_birthdate']; + if ($billingBirthdate && $this->isBirthValid($billingBirthdate)) { + $context->order->update_meta_data('billing_birthdate', $billingBirthdate); + $context->order->save(); + } else { + $message = __('Please introduce a valid birthdate number.', 'mollie-payments-for-woocommerce'); + throw new RouteException( + 'woocommerce_rest_checkout_process_payment_error', + $message, + 402 + ); + } + } + } } diff --git a/src/PaymentMethods/In3.php b/src/PaymentMethods/In3.php index be4b7ec3..1bd847fb 100644 --- a/src/PaymentMethods/In3.php +++ b/src/PaymentMethods/In3.php @@ -23,7 +23,7 @@ public function getConfig(): array 'confirmationDelayed' => false, 'orderMandatory' => true, 'errorMessage' => __( - 'Required field is empty. Phone and birthdate fields are required.', + 'Required field is empty or invalid. Phone and birthdate fields are required.', 'mollie-payments-for-woocommerce' ), 'phonePlaceholder' => __('Please enter your phone here. +00..', 'mollie-payments-for-woocommerce'),