diff --git a/public/images/alma.svg b/public/images/alma.svg new file mode 100644 index 00000000..9133d203 --- /dev/null +++ b/public/images/alma.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/Payment/MollieObject.php b/src/Payment/MollieObject.php index 9a69a834..ba03f6e1 100644 --- a/src/Payment/MollieObject.php +++ b/src/Payment/MollieObject.php @@ -11,13 +11,17 @@ use Mollie\WooCommerce\PaymentMethods\Voucher; use Mollie\WooCommerce\SDK\Api; use Mollie\WooCommerce\Settings\Settings; -use Psr\Log\LogLevel; use WC_Order; use WC_Payment_Gateway; use Psr\Log\LoggerInterface as Logger; +use stdClass; class MollieObject { + public const MAXIMAL_LENGHT_ADDRESS = 100; + public const MAXIMAL_LENGHT_POSTALCODE = 20; + public const MAXIMAL_LENGHT_CITY = 200; + public const MAXIMAL_LENGHT_REGION = 200; protected $data; /** * @var string[] @@ -983,4 +987,220 @@ protected function replaceTagsDescription($order, $description) } return $description; } + + /** + * @param $order + * @return stdClass + */ + protected function createBillingAddress($order) + { + // Setup billing and shipping objects + $billingAddress = new stdClass(); + + // Get user details + $billingAddress->givenName = (ctype_space( + $order->get_billing_first_name() + )) ? null : $order->get_billing_first_name(); + $billingAddress->familyName = (ctype_space( + $order->get_billing_last_name() + )) ? null : $order->get_billing_last_name(); + $billingAddress->email = (ctype_space($order->get_billing_email())) + ? null : $order->get_billing_email(); + // Create billingAddress object + $billingAddress->streetAndNumber = (ctype_space( + $order->get_billing_address_1() + )) + ? null + : $this->maximalFieldLengths( + $order->get_billing_address_1(), + self::MAXIMAL_LENGHT_ADDRESS + ); + $billingAddress->streetAdditional = (ctype_space( + $order->get_billing_address_2() + )) + ? null + : $this->maximalFieldLengths( + $order->get_billing_address_2(), + self::MAXIMAL_LENGHT_ADDRESS + ); + $billingAddress->postalCode = (ctype_space( + $order->get_billing_postcode() + )) + ? null + : $this->maximalFieldLengths( + $order->get_billing_postcode(), + self::MAXIMAL_LENGHT_POSTALCODE + ); + $billingAddress->city = (ctype_space($order->get_billing_city())) + ? null + : $this->maximalFieldLengths( + $order->get_billing_city(), + self::MAXIMAL_LENGHT_CITY + ); + $billingAddress->region = (ctype_space($order->get_billing_state())) + ? null + : $this->maximalFieldLengths( + $order->get_billing_state(), + self::MAXIMAL_LENGHT_REGION + ); + $billingAddress->country = (ctype_space($order->get_billing_country())) + ? null + : $this->maximalFieldLengths( + $order->get_billing_country(), + self::MAXIMAL_LENGHT_REGION + ); + $billingAddress->organizationName = $this->billingCompanyField($order); + $phone = $this->getPhoneNumber($order); + $billingAddress->phone = (ctype_space($phone)) + ? null + : $this->getFormatedPhoneNumber($phone); + return $billingAddress; + } + + protected function getPhoneNumber($order) + { + + $phone = !empty($order->get_billing_phone()) ? $order->get_billing_phone() : $order->get_shipping_phone(); + if (empty($phone)) { + //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $phone = wc_clean(wp_unslash($_POST['billing_phone'] ?? '')); + } + return $phone; + } + + protected function getFormatedPhoneNumber(string $phone) + { + //remove whitespaces and all non numerical characters except + + $phone = preg_replace('/[^0-9+]+/', '', $phone); + + //check that $phone is in E164 format + if ($phone !== null && preg_match('/^\+[1-9]\d{1,14}$/', $phone)) { + return $phone; + } + return null; + } + + /** + * @param $order + * @return string|null + */ + public function billingCompanyField($order): ?string + { + if (!trim($order->get_billing_company())) { + return $this->checkBillieCompanyField($order); + } + return $this->maximalFieldLengths( + $order->get_billing_company(), + self::MAXIMAL_LENGHT_ADDRESS + ); + } + + private function checkBillieCompanyField($order) + { + $gateway = wc_get_payment_gateway_by_order($order); + if (!$gateway || !$gateway->id) { + return null; + } + $isBillieMethodId = $gateway->id === 'mollie_wc_gateway_billie'; + if ($isBillieMethodId) { + //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $fieldPosted = wc_clean(wp_unslash($_POST["billing_company"] ?? '')); + if ($fieldPosted === '' || !is_string($fieldPosted)) { + return null; + } + return $this->maximalFieldLengths( + $fieldPosted, + self::MAXIMAL_LENGHT_ADDRESS + ); + } + return null; + } + + /** + * @param $order + * @return stdClass + */ + protected function createShippingAddress($order) + { + $shippingAddress = new stdClass(); + // Get user details + $shippingAddress->givenName = (ctype_space( + $order->get_shipping_first_name() + )) ? null : $order->get_shipping_first_name(); + $shippingAddress->familyName = (ctype_space( + $order->get_shipping_last_name() + )) ? null : $order->get_shipping_last_name(); + $shippingAddress->email = (ctype_space($order->get_billing_email())) + ? null + : $order->get_billing_email(); // WooCommerce doesn't have a shipping email + + + // Create shippingAddress object + $shippingAddress->streetAndNumber = (ctype_space( + $order->get_shipping_address_1() + )) + ? null + : $this->maximalFieldLengths( + $order->get_shipping_address_1(), + self::MAXIMAL_LENGHT_ADDRESS + ); + $shippingAddress->streetAdditional = (ctype_space( + $order->get_shipping_address_2() + )) + ? null + : $this->maximalFieldLengths( + $order->get_shipping_address_2(), + self::MAXIMAL_LENGHT_ADDRESS + ); + $shippingAddress->postalCode = (ctype_space( + $order->get_shipping_postcode() + )) + ? null + : $this->maximalFieldLengths( + $order->get_shipping_postcode(), + self::MAXIMAL_LENGHT_POSTALCODE + ); + $shippingAddress->city = (ctype_space($order->get_shipping_city())) + ? null + : $this->maximalFieldLengths( + $order->get_shipping_city(), + self::MAXIMAL_LENGHT_CITY + ); + $shippingAddress->region = (ctype_space($order->get_shipping_state())) + ? null + : $this->maximalFieldLengths( + $order->get_shipping_state(), + self::MAXIMAL_LENGHT_REGION + ); + $shippingAddress->country = (ctype_space( + $order->get_shipping_country() + )) + ? null + : $this->maximalFieldLengths( + $order->get_shipping_country(), + self::MAXIMAL_LENGHT_REGION + ); + return $shippingAddress; + } + + /** + * Method that shortens the field to a certain length + * + * @param string $field + * @param int $maximalLength + * + * @return null|string + */ + protected function maximalFieldLengths($field, $maximalLength) + { + if (!is_string($field)) { + return null; + } + if (is_int($maximalLength) && strlen($field) > $maximalLength) { + $field = substr($field, 0, $maximalLength); + $field = !$field ? null : $field; + } + + return $field; + } } diff --git a/src/Payment/MollieOrder.php b/src/Payment/MollieOrder.php index 4a3e0feb..804e91b6 100644 --- a/src/Payment/MollieOrder.php +++ b/src/Payment/MollieOrder.php @@ -4,7 +4,6 @@ namespace Mollie\WooCommerce\Payment; -use DateTime; use Exception; use Mollie\Api\Exceptions\ApiException; use Mollie\Api\Resources\Payment; @@ -15,7 +14,6 @@ use Mollie\WooCommerce\SDK\Api; use Mollie\WooCommerce\Shared\SharedDataDictionary; use Psr\Log\LogLevel; -use stdClass; use WC_Order; use WP_Error; @@ -23,10 +21,7 @@ class MollieOrder extends MollieObject { public const ACTION_AFTER_REFUND_AMOUNT_CREATED = 'mollie-payments-for-woocommerce' . '_refund_amount_created'; public const ACTION_AFTER_REFUND_ORDER_CREATED = 'mollie-payments-for-woocommerce' . '_refund_order_created'; - public const MAXIMAL_LENGHT_ADDRESS = 100; - public const MAXIMAL_LENGHT_POSTALCODE = 20; - public const MAXIMAL_LENGHT_CITY = 200; - public const MAXIMAL_LENGHT_REGION = 200; + protected static $paymentId; protected static $customerId; @@ -831,26 +826,7 @@ public function updatePaymentDataWithOrderData($order, $orderId) } } - /** - * Method that shortens the field to a certain length - * - * @param string $field - * @param int $maximalLength - * - * @return null|string - */ - protected function maximalFieldLengths($field, $maximalLength) - { - if (!is_string($field)) { - return null; - } - if (is_int($maximalLength) && strlen($field) > $maximalLength) { - $field = substr($field, 0, $maximalLength); - $field = !$field ? null : $field; - } - return $field; - } /** * @param WC_Order $order @@ -889,153 +865,6 @@ protected function maybeUpdateStatus( ); } - /** - * @param $order - * @return stdClass - */ - protected function createBillingAddress($order) - { - // Setup billing and shipping objects - $billingAddress = new stdClass(); - - // Get user details - $billingAddress->givenName = (ctype_space( - $order->get_billing_first_name() - )) ? null : $order->get_billing_first_name(); - $billingAddress->familyName = (ctype_space( - $order->get_billing_last_name() - )) ? null : $order->get_billing_last_name(); - $billingAddress->email = (ctype_space($order->get_billing_email())) - ? null : $order->get_billing_email(); - // Create billingAddress object - $billingAddress->streetAndNumber = (ctype_space( - $order->get_billing_address_1() - )) - ? null - : $this->maximalFieldLengths( - $order->get_billing_address_1(), - self::MAXIMAL_LENGHT_ADDRESS - ); - $billingAddress->streetAdditional = (ctype_space( - $order->get_billing_address_2() - )) - ? null - : $this->maximalFieldLengths( - $order->get_billing_address_2(), - self::MAXIMAL_LENGHT_ADDRESS - ); - $billingAddress->postalCode = (ctype_space( - $order->get_billing_postcode() - )) - ? null - : $this->maximalFieldLengths( - $order->get_billing_postcode(), - self::MAXIMAL_LENGHT_POSTALCODE - ); - $billingAddress->city = (ctype_space($order->get_billing_city())) - ? null - : $this->maximalFieldLengths( - $order->get_billing_city(), - self::MAXIMAL_LENGHT_CITY - ); - $billingAddress->region = (ctype_space($order->get_billing_state())) - ? null - : $this->maximalFieldLengths( - $order->get_billing_state(), - self::MAXIMAL_LENGHT_REGION - ); - $billingAddress->country = (ctype_space($order->get_billing_country())) - ? null - : $this->maximalFieldLengths( - $order->get_billing_country(), - self::MAXIMAL_LENGHT_REGION - ); - $billingAddress->organizationName = $this->billingCompanyField($order); - $phone = $this->getPhoneNumber($order); - $billingAddress->phone = (ctype_space($phone)) - ? null - : $this->getFormatedPhoneNumber($phone); - return $billingAddress; - } - - protected function getPhoneNumber($order) - { - - $phone = !empty($order->get_billing_phone()) ? $order->get_billing_phone() : $order->get_shipping_phone(); - if (empty($phone)) { - //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized - $phone = wc_clean(wp_unslash($_POST['billing_phone'] ?? '')); - } - return $phone; - } - - /** - * @param $order - * @return stdClass - */ - protected function createShippingAddress($order) - { - $shippingAddress = new stdClass(); - // Get user details - $shippingAddress->givenName = (ctype_space( - $order->get_shipping_first_name() - )) ? null : $order->get_shipping_first_name(); - $shippingAddress->familyName = (ctype_space( - $order->get_shipping_last_name() - )) ? null : $order->get_shipping_last_name(); - $shippingAddress->email = (ctype_space($order->get_billing_email())) - ? null - : $order->get_billing_email(); // WooCommerce doesn't have a shipping email - - - // Create shippingAddress object - $shippingAddress->streetAndNumber = (ctype_space( - $order->get_shipping_address_1() - )) - ? null - : $this->maximalFieldLengths( - $order->get_shipping_address_1(), - self::MAXIMAL_LENGHT_ADDRESS - ); - $shippingAddress->streetAdditional = (ctype_space( - $order->get_shipping_address_2() - )) - ? null - : $this->maximalFieldLengths( - $order->get_shipping_address_2(), - self::MAXIMAL_LENGHT_ADDRESS - ); - $shippingAddress->postalCode = (ctype_space( - $order->get_shipping_postcode() - )) - ? null - : $this->maximalFieldLengths( - $order->get_shipping_postcode(), - self::MAXIMAL_LENGHT_POSTALCODE - ); - $shippingAddress->city = (ctype_space($order->get_shipping_city())) - ? null - : $this->maximalFieldLengths( - $order->get_shipping_city(), - self::MAXIMAL_LENGHT_CITY - ); - $shippingAddress->region = (ctype_space($order->get_shipping_state())) - ? null - : $this->maximalFieldLengths( - $order->get_shipping_state(), - self::MAXIMAL_LENGHT_REGION - ); - $shippingAddress->country = (ctype_space( - $order->get_shipping_country() - )) - ? null - : $this->maximalFieldLengths( - $order->get_shipping_country(), - self::MAXIMAL_LENGHT_REGION - ); - return $shippingAddress; - } - /** * @param $paymentObject * @param $item @@ -1167,42 +996,6 @@ protected function processOrderItemsRefund( unset($items[$item->get_id()]); } - /** - * @param $order - * @return string|null - */ - public function billingCompanyField($order): ?string - { - if (!trim($order->get_billing_company())) { - return $this->checkBillieCompanyField($order); - } - return $this->maximalFieldLengths( - $order->get_billing_company(), - self::MAXIMAL_LENGHT_ADDRESS - ); - } - - private function checkBillieCompanyField($order) - { - $gateway = wc_get_payment_gateway_by_order($order); - if (!$gateway || !$gateway->id) { - return null; - } - $isBillieMethodId = $gateway->id === 'mollie_wc_gateway_billie'; - if ($isBillieMethodId) { - //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized - $fieldPosted = wc_clean(wp_unslash($_POST["billing_company"] ?? '')); - if ($fieldPosted === '' || !is_string($fieldPosted)) { - return null; - } - return $this->maximalFieldLengths( - $fieldPosted, - self::MAXIMAL_LENGHT_ADDRESS - ); - } - return null; - } - protected function getCustomerBirthdate($order) { $gateway = wc_get_payment_gateway_by_order($order); @@ -1221,16 +1014,4 @@ protected function getCustomerBirthdate($order) } return null; } - - protected function getFormatedPhoneNumber(string $phone) - { - //remove whitespaces and all non numerical characters except + - $phone = preg_replace('/[^0-9+]+/', '', $phone); - - //check that $phone is in E164 format - if ($phone !== null && preg_match('/^\+[1-9]\d{1,14}$/', $phone)) { - return $phone; - } - return null; - } } diff --git a/src/Payment/MolliePayment.php b/src/Payment/MolliePayment.php index 82636f65..0d319e54 100644 --- a/src/Payment/MolliePayment.php +++ b/src/Payment/MolliePayment.php @@ -123,6 +123,7 @@ public function getPaymentRequestData($order, $customerId, $voucherDefaultCatego $encodedApplePayToken = json_encode($applePayToken); $paymentRequestData['applePayPaymentToken'] = $encodedApplePayToken; } + $paymentRequestData = $this->addCustomRequestFields($order, $paymentRequestData, $gateway); return $paymentRequestData; } @@ -530,4 +531,21 @@ protected function maybeUpdateStatus( } $gateway->paymentService()->updateOrderStatus($order, $newOrderStatus); } + + protected function addCustomRequestFields($order, array $paymentRequestData, MolliePaymentGateway $gateway) + { + if ($gateway->paymentMethod()->hasProperty('paymentAPIfields')) { + $paymentAPIfields = $gateway->paymentMethod()->getProperty('paymentAPIfields'); + foreach ($paymentAPIfields as $field) { + if (!method_exists($this, 'create' . ucfirst($field))) { + continue; + } + $value = $this->{'create' . ucfirst($field)}($order); + if ($value) { + $paymentRequestData[$field] = $value; + } + } + } + return $paymentRequestData; + } } diff --git a/src/PaymentMethods/Alma.php b/src/PaymentMethods/Alma.php new file mode 100644 index 00000000..57ac08fa --- /dev/null +++ b/src/PaymentMethods/Alma.php @@ -0,0 +1,36 @@ + 'alma', + 'defaultTitle' => __('Alma', 'mollie-payments-for-woocommerce'), + 'settingsDescription' => '', + 'defaultDescription' => '', + 'paymentFields' => false, + 'instructions' => false, + 'supports' => [ + 'products', + 'refunds', + ], + 'filtersOnBuild' => false, + 'confirmationDelayed' => false, + 'SEPA' => false, + 'paymentAPIfields' => [ + 'billingAddress', + 'shippingAddress', + ], + ]; + } + + public function getFormFields($generalFormFields): array + { + return $generalFormFields; + } +} diff --git a/src/Shared/SharedDataDictionary.php b/src/Shared/SharedDataDictionary.php index 7845ff63..d4f0c156 100644 --- a/src/Shared/SharedDataDictionary.php +++ b/src/Shared/SharedDataDictionary.php @@ -34,6 +34,7 @@ class SharedDataDictionary 'Mollie_WC_Gateway_Blik', 'Mollie_WC_Gateway_Twint', 'Mollie_WC_Gateway_Bancomatpay', + 'Mollie_WC_Gateway_Alma', ]; public const MOLLIE_OPTIONS_NAMES = [