ltDescription, 'desc_tip' => true, ], 'allowed_countries' => [ 'title' => __( 'Sell to specific countries', 'mollie-payments-for-woocommerce' ), 'desc' => '', 'css' => 'min-width: 350px;', 'default' => [], 'type' => 'multi_select_countries', ], 'payment_surcharge' => [ 'title' => __( 'Payment Surcharge', 'mollie-payments-for-woocommerce' ), 'type' => 'select', 'options' => [ Mollie_WC_Helper_GatewaySurchargeHandler::NO_FEE => __( 'No fee', 'mollie-payments-for-woocommerce' ), Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE => __( 'Fixed fee', 'mollie-payments-for-woocommerce' ), Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE => __( 'Percentage', 'mollie-payments-for-woocommerce' ), Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_AND_PERCENTAGE => __( 'Fixed fee and percentage', 'mollie-payments-for-woocommerce' ), ], 'default' => 'no_fee', 'description' => __( 'Choose a payment surcharge for this gateway', 'mollie-payments-for-woocommerce' ), 'desc_tip' => true, ], 'fixed_fee' => [ 'title' => sprintf(__('Payment surcharge fixed amount in %s', 'mollie-payments-for-woocommerce'), html_entity_decode( get_woocommerce_currency_symbol() )), 'type' => 'number', 'description' => sprintf( __( 'Control the fee added on checkout. Default 0.01', 'mollie-payments-for-woocommerce' ) ), 'custom_attributes'=>['step'=>'0.01', 'min'=>'0.01', 'max'=>'999'], 'default' => '0.01', 'desc_tip' => true, ], 'percentage' => [ 'title' => __('Payment surcharge percentage amount %', 'mollie-payments-for-woocommerce'), 'type' => 'number', 'description' => sprintf( __( 'Control the percentage fee added on checkout. Default 0.01', 'mollie-payments-for-woocommerce' ) ), 'custom_attributes'=>['step'=>'0.01', 'min'=>'0.01', 'max'=>'999'], 'default' => '0.01', 'desc_tip' => true, ], 'surcharge_limit' => [ 'title' => sprintf(__('Payment surcharge limit in %s', 'mollie-payments-for-woocommerce'), html_entity_decode( get_woocommerce_currency_symbol())), 'type' => 'number', 'description' => sprintf( __( 'Limit the maximum fee added on checkout. Default 0', 'mollie-payments-for-woocommerce' ) ), 'custom_attributes'=>['step'=>'0.01', 'min'=>'0.01', 'max'=>'999'], 'default' => '0.01', 'desc_tip' => true, ], ]; if ($paymentConfirmation) { $formFields['initial_order_status'] = [ 'title' => __( 'Initial order status', 'mollie-payments-for-woocommerce' ), 'type' => 'select', 'options' => [ Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD => wc_get_order_status_name( Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD ) . ' (' . __( 'default', 'mollie-payments-for-woocommerce' ) . ')', Mollie_WC_Gateway_Abstract::STATUS_PENDING => wc_get_order_status_name( Mollie_WC_Gateway_Abstract::STATUS_PENDING ), ], 'default' => Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD, /* translators: Placeholder 1: Default order status, placeholder 2: Link to 'Hold Stock' setting */ 'description' => sprintf( __( 'Some payment methods take longer than a few hours to complete. The initial order state is then set to \'%s\'. This ensures the order is not cancelled when the setting %s is used.', 'mollie-payments-for-woocommerce' ), wc_get_order_status_name( Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD ), '' . __( 'Hold Stock (minutes)', 'woocommerce' ) . '' ), ]; } return $formFields; } /** * @return bool */ public function isTestModeEnabled() { return trim(get_option($this->getSettingId('test_mode_enabled'))) === 'yes'; } /** * @param bool $test_mode * @return null|string */ public function getApiKey($test_mode = false) { $setting_id = $test_mode ? 'test_api_key' : 'live_api_key'; $apiKeyId = $this->getSettingId($setting_id); $apiKey = get_option($apiKeyId); if (!$apiKey && is_admin()) { $apiKey = filter_input(INPUT_POST, $apiKeyId, FILTER_SANITIZE_STRING); } return trim($apiKey); } /** * Order status for cancelled payments * * @return string|null */ public function getOrderStatusCancelledPayments() { return trim(get_option($this->getSettingId('order_status_cancelled_payments'))); } /** * Retrieve the Payment Locale Setting from Database * * @return string */ protected function getPaymentLocaleSetting() { $option = (string)get_option( $this->getSettingId(self::SETTING_NAME_PAYMENT_LOCALE), self::SETTING_LOCALE_WP_LANGUAGE ); $option = $option ?: self::SETTING_LOCALE_WP_LANGUAGE; return trim($option); } /** * Retrieve the Payment Locale * * @return string */ public function getPaymentLocale() { $setting = $this->getPaymentLocaleSetting(); if ($setting === self::SETTING_LOCALE_DETECT_BY_BROWSER) { return $this->browserLanguage(); } $setting === self::SETTING_LOCALE_WP_LANGUAGE ? $languageCode = $this->getCurrentLocale() : $languageCode = $setting; // TODO Missing Post condition, $languageCode has to be check for a valid // language code. return $languageCode ?: self::SETTING_LOCALE_DEFAULT_LANGUAGE; } /** * Store customer details at Mollie * * @return string */ public function shouldStoreCustomer () { return get_option($this->getSettingId('customer_details'), 'yes') === 'yes'; } /** * @return bool */ public function isDebugEnabled () { return get_option($this->getSettingId('debug'), 'yes') === 'yes'; } /** * @return string */ public function getGlobalSettingsUrl () { return admin_url('admin.php?page=wc-settings&tab=mollie_settings#' . Mollie_WC_Plugin::PLUGIN_ID); } /** * @return string */ public function getLogsUrl() { return admin_url('admin.php?page=wc-status&tab=logs'); } /** * Update the profileId option on update keys or on changing live/test mode * * @param $optionValue * @param $optionName * * @return mixed */ public function updateMerchantIdOnApiKeyChanges($optionValue, $optionName) { $optionId = isset($optionName['id']) ? $optionName['id'] : ''; $allowedOptionsId = [ $this->getSettingId('live_api_key'), $this->getSettingId('test_api_key'), ]; if (!in_array($optionId, $allowedOptionsId, true)) { return $optionValue; } $merchantProfileIdOptionKey = Mollie_WC_Plugin::PLUGIN_ID . '_profile_merchant_id'; try { $merchantProfile = mollieWooCommerceMerchantProfile(); $merchantProfileId = isset($merchantProfile->id) ? $merchantProfile->id : ''; } catch (ApiException $exception) { $merchantProfileId = ''; } update_option($merchantProfileIdOptionKey, $merchantProfileId); return $optionValue; } /** * Called after the api keys are updated so we can update the profile Id * * @param $oldValue * @param $value * @param $optionName */ public function updateMerchantIdAfterApiKeyChanges($oldValue, $value, $optionName) { $option = ['id'=>$optionName]; $this->updateMerchantIdOnApiKeyChanges($value, $option); } /** * Get plugin status * * - Check compatibility * - Check Mollie API connectivity * * @return string */ protected function getPluginStatus() { $status = Mollie_WC_Plugin::getStatusHelper(); if (!$status->isCompatible()) { // Just stop here! return '' . '
' . __(
'Error',
'mollie-payments-for-woocommerce'
) . ': ' . implode('
', $status->getErrors())
. '
' . __('Mollie status:', 'mollie-payments-for-woocommerce') . ' ' . __('Connected', 'mollie-payments-for-woocommerce') . '' . '
'; $api_status_type = 'updated'; } catch (\Mollie\Api\Exceptions\ApiException $e) { $api_status = '' . 'Communicating with Mollie failed: ' . $e->getMessage() . '
' . 'Please view the FAQ item Communicating with Mollie failed if this does not fix your problem.'; $api_status_type = 'error'; } return '' . '
Please go to the signup page '; $presentationText .= __('to create a new Mollie account and start receiving payments in a couple of minutes. ', 'mollie-payments-for-woocommerce'); $presentationText .= 'Contact info@mollie.com'; $presentationText .= ' if you have any questions or comments about this plugin.
'; $presentationText .= 'Our pricing is always per transaction. No startup fees, no monthly fees, and no gateway fees. No hidden fees, period.
'; $presentation = '' . ''.$presentationText.'
%s
',
'mollie-payments-for-woocommerce'
),
defined('WC_LOG_DIR') ? WC_LOG_DIR
: WC()->plugin_path() . '/logs/'
);
// Global Mollie settings
$mollie_settings = array(
array(
'id' => $this->getSettingId('title'),
'title' => __('Mollie Settings', 'mollie-payments-for-woocommerce'),
'type' => 'title',
'desc' => '' . $content . '
' . '' . __('The following options are required to use the plugin and are used by all Mollie payment methods', 'mollie-payments-for-woocommerce') . '
', ), array( 'id' => $this->getSettingId('live_api_key'), 'title' => __('Live API key', 'mollie-payments-for-woocommerce'), 'default' => '', 'type' => 'text', 'desc' => sprintf( /* translators: Placeholder 1: API key mode (live or test). The surrounding %s's Will be replaced by a link to the Mollie profile */ __('The API key is used to connect to Mollie. You can find your %s API key in your %sMollie profile%s', 'mollie-payments-for-woocommerce'), 'live', '', '' ), 'css' => 'width: 350px', 'placeholder' => $live_placeholder = __('Live API key should start with live_', 'mollie-payments-for-woocommerce'), 'custom_attributes' => array( 'placeholder' => $live_placeholder, 'pattern' => '^live_\w{30,}$', ), ), array( 'id' => $this->getSettingId('test_mode_enabled'), 'title' => __('Enable test mode', 'mollie-payments-for-woocommerce'), 'default' => 'no', 'type' => 'checkbox', 'desc_tip' => __('Enable test mode if you want to test the plugin without using real payments.', 'mollie-payments-for-woocommerce'), ), array( 'id' => $this->getSettingId('test_api_key'), 'title' => __('Test API key', 'mollie-payments-for-woocommerce'), 'default' => '', 'type' => 'text', 'desc' => sprintf( /* translators: Placeholder 1: API key mode (live or test). The surrounding %s's Will be replaced by a link to the Mollie profile */ __('The API key is used to connect to Mollie. You can find your %s API key in your %sMollie profile%s', 'mollie-payments-for-woocommerce'), 'test', '', '' ), 'css' => 'width: 350px', 'placeholder' => $test_placeholder = __('Test API key should start with test_', 'mollie-payments-for-woocommerce'), 'custom_attributes' => array( 'placeholder' => $test_placeholder, 'pattern' => '^test_\w{30,}$', ), ), [ 'id' => $this->getSettingId('debug'), 'title' => __('Debug Log', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'desc' => $debug_desc, 'default' => 'yes', ], array( 'id' => $this->getSettingId('sectionend'), 'type' => 'sectionend', ), ); return $this->mergeSettings($settings, $mollie_settings); } public function getPaymentConfirmationCheckTime() { $time = strtotime(self::DEFAULT_TIME_PAYMENT_CONFIRMATION_CHECK); $date = new DateTime(); if ($date->getTimestamp() > $time){ $date->setTimestamp($time); $date->add(new DateInterval('P1D')); } else { $date->setTimestamp($time); } return $date->getTimestamp(); } /** * @param string $setting * @return string */ protected function getSettingId ($setting) { global $wp_version; $setting_id = Mollie_WC_Plugin::PLUGIN_ID . '_' . trim($setting); $setting_id_length = strlen($setting_id); $max_option_name_length = 191; /** * Prior to WooPress version 4.4.0, the maximum length for wp_options.option_name is 64 characters. * @see https://core.trac.wordpress.org/changeset/34030 */ if ($wp_version < '4.4.0') { $max_option_name_length = 64; } if ($setting_id_length > $max_option_name_length) { trigger_error("Setting id $setting_id ($setting_id_length) to long for database column wp_options.option_name which is varchar($max_option_name_length).", E_USER_WARNING); } return $setting_id; } /** * @param array $settings * @param array $mollie_settings * @return array */ protected function mergeSettings(array $settings, array $mollie_settings) { $new_settings = array(); $mollie_settings_merged = false; // Find payment gateway options index foreach ($settings as $index => $setting) { if (isset($setting['id']) && $setting['id'] == 'payment_gateways_options' && (!isset($setting['type']) || $setting['type'] != 'sectionend') ) { $new_settings = array_merge($new_settings, $mollie_settings); $mollie_settings_merged = true; } $new_settings[] = $setting; } // Mollie settings not merged yet, payment_gateways_options not found if (!$mollie_settings_merged) { // Append Mollie settings $new_settings = array_merge($new_settings, $mollie_settings); } return $new_settings; } /** * @param $content * * @return string */ protected function checkDirectDebitStatus( $content ) { $ideal_gateway = new Mollie_WC_Gateway_iDEAL(); $sepa_gateway = new Mollie_WC_Gateway_DirectDebit(); if ( ( class_exists( 'WC_Subscription' ) ) && ( $ideal_gateway->is_available() ) && ( ! $sepa_gateway->is_available() ) ) { $warning_message = __( 'You have WooCommerce Subscriptions activated, but not SEPA Direct Debit. Enable SEPA Direct Debit if you want to allow customers to pay subscriptions with iDEAL and/or other "first" payment methods.', 'mollie-payments-for-woocommerce' ); $content .= ''; $content .= $warning_message; $content .= '
'; $content .= __( 'You have the WooCommerce default Direct Bank Transfer (BACS) payment gateway enabled in WooCommerce. Mollie strongly advices only using Bank Transfer via Mollie and disabling the default WooCommerce BACS payment gateway to prevent possible conflicts.', 'mollie-payments-for-woocommerce' ); $content .= '
'; $content .= __( 'To accept Klarna payments via Mollie, all default WooCommerce checkout fields should be enabled and required. Please ensure that is the case.', 'mollie-payments-for-woocommerce' ); $content .= '