diff --git a/CHANGES.md b/CHANGES.md index c17babe..b6e042e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,43 @@ Changelog ========= + +1.10.3 +----- +* Common: Integration of PayFrame to enable use of SAQ A for easier PCI DSS 3.0 compliance. + +PayFrame +We’ve introduced a “payment form” option for easier compliance with PCI requirements. + +In addition to having a payment form directly integrated in your checkout page, you +can use our embedded PayFrame solution to ensure that payment data never +touches your website. + +PayFrame is enabled by default, but you can choose between both options in the +plugin settings. Later this year, we’re bringing you the ability to customise the +appearance and text content of the PayFrame version. + +To learn more about the benefits of PayFrame, please visit our FAQ: +https://www.paymill.com/en/faq/howdoespaymillspayframesolutionwork + +1.10.2 +----- +* Subscriptions: "required_offer_or_amount_and_currency_and_interval" error fixed + +1.10.1 +----- +* WooCommerce: Error Management Fix +* Common: Checkout Form fix + + +1.10.0 +----- +* WooCommerce: Error Management on Checkout fixed +* WooCommerce: Subscription Handling reviewed and optimized +* Common: Support for PCI DSS 3.0 (iframe-based credit card form) +* WooCommerce: Several improvements and bugfixes + + 1.9.0 ----- * Common: Update to v2.1 Paymill API diff --git a/README.md b/README.md index 398ff05..4d8ed14 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ PAYMILL for WordPress * Contributors: Matthias Reuter * Donate link: * Tags: paymill, creditcard, elv, payment, woocommerce, paybutton, ecommerce, debitcard, subscriptions -* Requires at least: 4.1 -* Tested up to: 4.1.1 -* Stable tag: 1.9 +* Requires at least: 4.2.2 +* Tested up to: 4.2.2 +* Stable tag: 1.10.3 * License: [GPLv3 or later](http://www.gnu.org/licenses/gpl-3.0.html) With PAYMILL you are able to provide credit card based payments for your customers. diff --git a/lib/config.inc.php b/lib/config.inc.php index 122c68d..fb108dd 100644 --- a/lib/config.inc.php +++ b/lib/config.inc.php @@ -113,6 +113,7 @@ public function paymill_register_general_settings(){ 'api_key_public' => __('Paymill PUBLIC API key', 'paymill'), 'payments_display' => __('Display Payment Types', 'paymill'), 'no_default_css' => __('Do not load default CSS', 'paymill'), + 'pci_dss_3' => __('Deactivate PCI DSS 3.0 Compatibility', 'paymill'), ); foreach($settings as $setting => $description){ @@ -282,7 +283,7 @@ private function print_config_form_fields($args) { $descriptions['products_desc'] = __('Detailed description of the product', 'paymill'); $descriptions['products_price'] = __('Gross Price of the product, e.g. 40 or 6.99', 'paymill'); $descriptions['products_offer'] = __('If you have created a subscription in your Paymill Cockpit, you can select it here. If selected, it will overwrite the following settings for this product. Important: For Performance purposes, subscription plans will be cached. Open this page to recache it.', 'paymill'); - $descriptions['products_vat'] = __('Value-Added-Tax Rate in % for the product, e.g. 19 or 7', 'paymill'); + $descriptions['products_vat'] = __('Value-Added-Tax Rate in % for the product, e.g. 19 or 7', 'paymill'); $descriptions['products_delivery'] = __('Delivery Time of the product, e.g. 2 Days or 1 Week', 'paymill'); $descriptions['products_quantityhide'] = __('Hide quantity select field, quantity will be set to 1', 'paymill'); $descriptions['products_freeamount'] = __('Allow free amounts (donation feature)', 'paymill'); @@ -351,7 +352,14 @@ private function print_config_form_fields($args) { value="1" class="regular-text code" '.($value ? 'checked="checked"' : '').' /> '; - }elseif($args['desc'] == 'fields_show'){ + }elseif($args['desc'] == 'pci_dss_3'){ // pci_dss_3 + echo ' + + '; + }elseif($args['desc'] == 'fields_show'){ echo __('You may want to gather some additional information from your customers. Select them here:', 'paymill').'
'; $fields_show = array( @@ -433,20 +441,21 @@ private function paymill_do_settings_fields($page, $section){ $descriptions['thankyou_url'] = __('Redirect URL for custom thank your page.', 'paymill'); $descriptions['no_default_css'] = __('Advanced users want to fully customize the payment button. Disabling default CSS from Pay Button will make that much easier.', 'paymill'); + $descriptions['pci_dss_3'] = __('Please ask Paymill customer support for further information.', 'paymill'); $descriptions['currency'] = __('Currency, ISO 4217 e.g. "EUR" or "GBP"', 'paymill'); - $descriptions['currency_format'] = __('Currency Format - use the following variables: %n = number, %s = symbol.', 'paymill'); + $descriptions['currency_format'] = __('Currency Format - use the following variables: %n = number, %s = symbol.', 'paymill'); $descriptions['api_key_private'] = __('Insert your Paymill PRIVATE API key.', 'paymill'); $descriptions['api_key_public'] = __('Insert your Paymill PUBLIC API key.', 'paymill'); $descriptions['flat_shipping_country'] = __('Name of the available delivery country, e.g. England', 'paymill'); $descriptions['flat_shipping_costs'] = __('Gross fee for the flat shipping costs., e.g. 7 or 4.90', 'paymill'); - $descriptions['flat_shipping_vat'] = __('Value-Added-Tax Rate in % for the flat shipping costs., e.g. 19 or 7', 'paymill'); + $descriptions['flat_shipping_vat'] = __('Value-Added-Tax Rate in % for the flat shipping costs., e.g. 19 or 7', 'paymill'); $descriptions['products_title'] = __('Name of the product', 'paymill'); $descriptions['products_desc'] = __('Detailed description of the product', 'paymill'); $descriptions['products_price'] = __('Gross Price of the product, e.g. 40 or 6.99', 'paymill'); $descriptions['products_offer'] = __('If you have created a subscription in your Paymill Cockpit, can select it here. If selected, it will overwrite the following settings for this product. Important: For Performance purposes, subscription plans will be cached. Open this page to recache it.', 'paymill'); - $descriptions['products_vat'] = __('Value-Added-Tax Rate in % for the product, e.g. 19 or 7', 'paymill'); + $descriptions['products_vat'] = __('Value-Added-Tax Rate in % for the product, e.g. 19 or 7', 'paymill'); $descriptions['products_delivery'] = __('Delivery Time of the product, e.g. 2 Days or 1 Week', 'paymill'); $descriptions['products_quantityhide'] = __('Hide quantity select field, quantity will be set to 1', 'paymill'); $descriptions['products_freeamount'] = __('Allow free amounts (donation feature)', 'paymill'); diff --git a/lib/css/paymill.css b/lib/css/paymill.css index eaec1b4..2a4f01a 100644 --- a/lib/css/paymill.css +++ b/lib/css/paymill.css @@ -83,7 +83,6 @@ background-image:url('../img/payment_logos.png'); background-repeat:no-repeat; background-position:0px 30px; - font-size:90%; } #paymill_framebox img{ box-shadow:none !important; @@ -131,6 +130,9 @@ paymill_#form_credit, paymill_#form_elv{ .paymill_payment_logos{ margin-bottom:10px; } +.paymill_payment_logos img{ + display:inline; +} /* error box */ .paymill_payment_errors{ diff --git a/lib/img/logos/dc.png b/lib/img/logos/dc.png index 9ab8017..911a4b2 100644 Binary files a/lib/img/logos/dc.png and b/lib/img/logos/dc.png differ diff --git a/lib/img/payment_logos.png b/lib/img/payment_logos.png index bc474e5..8e9255e 100644 Binary files a/lib/img/payment_logos.png and b/lib/img/payment_logos.png differ diff --git a/lib/integration/cart66.inc.php b/lib/integration/cart66.inc.php index c6d1cb1..7719795 100644 --- a/lib/integration/cart66.inc.php +++ b/lib/integration/cart66.inc.php @@ -60,6 +60,8 @@ protected function _buildCheckoutView($gateway) { paymill_form_checkout_id = "#Cart66_paymill_for_wordpress_form"; paymill_form_checkout_submit_id = "#Cart66CheckoutButton"; paymill_shop_name = "cart66"; + paymill_pcidss3 = '.((empty($GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3']) || $GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3'] != '1') ? 1 : 0).'; + paymill_pcidss3_lang = "'.substr(apply_filters('plugin_locale', get_locale(), $domain),0,2).'"; '; @@ -163,7 +165,7 @@ private function processProducts(){ )); $this->transaction_id = $response['body']['data']['id']; - + return true; }else{ // total is zero, so just return true @@ -193,6 +195,7 @@ private function process_payment(){ // process subscriptions & products if($this->processProducts()){ // success + return true; }else{ if($GLOBALS['paymill_loader']->paymill_errors->status()){ $GLOBALS['paymill_loader']->paymill_errors->getErrors(); @@ -239,7 +242,6 @@ public function getCreditCardTypes() { public function initCheckout($total) { $this->_total = $total; - $this->process_payment(); } public function getTransactionResponseDescription() { @@ -247,8 +249,8 @@ public function getTransactionResponseDescription() { } public function doSale() { - return $this->transaction_id; + $this->process_payment(); + return $this->transaction_id; } - } } \ No newline at end of file diff --git a/lib/integration/magicmembers.inc.php b/lib/integration/magicmembers.inc.php index a2a5eb4..ebbbdb4 100644 --- a/lib/integration/magicmembers.inc.php +++ b/lib/integration/magicmembers.inc.php @@ -1427,6 +1427,8 @@ function process_html_redirect(){ paymill_form_checkout_id = ".checkout"; paymill_form_checkout_submit_id = "#place_order"; paymill_shop_name = "magicmembers"; + paymill_pcidss3 = '.((empty($GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3']) || $GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3'] != '1') ? 1 : 0).'; + paymill_pcidss3_lang = "'.substr(apply_filters('plugin_locale', get_locale(), $domain),0,2).'"; '; echo '
'; diff --git a/lib/integration/marketpress.inc.php b/lib/integration/marketpress.inc.php index c244d6d..35e491b 100644 --- a/lib/integration/marketpress.inc.php +++ b/lib/integration/marketpress.inc.php @@ -201,6 +201,8 @@ function payment_form($global_cart, $shipping_info) { paymill_form_checkout_id = "#mp_payment_form"; paymill_form_checkout_submit_id = "#mp_payment_confirm"; paymill_shop_name = "marketpress"; + paymill_pcidss3 = '.((empty($GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3']) || $GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3'] != '1') ? 1 : 0).'; + paymill_pcidss3_lang = "'.substr(apply_filters('plugin_locale', get_locale(), $domain),0,2).'"; '; echo do_shortcode($mp->get_setting('gateways->paymill-for-wordpress->instructions')); diff --git a/lib/integration/pay_button.inc.php b/lib/integration/pay_button.inc.php index 90bb3fa..383388e 100644 --- a/lib/integration/pay_button.inc.php +++ b/lib/integration/pay_button.inc.php @@ -304,6 +304,8 @@ function widget($args, $instance){ paymill_form_checkout_id = ".checkout"; paymill_form_checkout_submit_id = "#place_order"; paymill_shop_name = "paybutton"; + paymill_pcidss3 = '.((empty($GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3']) || $GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3'] != '1') ? 1 : 0).'; + paymill_pcidss3_lang = "'.substr(apply_filters('plugin_locale', get_locale(), $domain),0,2).'"; '; if($this->subscriptions === false){ @@ -365,9 +367,11 @@ function form($instance) { "); + paymill_youshallpass = true; + form.submit(); } + }); + }else{ + if (false == paymill.validateCardNumber(jQuery('#paymill_card_number').val())) { + jQuery(".paymill_payment_errors").text(paymill_lang.validateCardNumber); jQuery(paymill_form_checkout_submit_id).show(); - }else{ - - - jQuery(".paymill_payment_errors").text(""); - var form = jQuery(paymill_form_checkout_id); + return false; + } - // insert token into form - var token = result.token; - form.append(""); - paymill_youshallpass = true; - form.submit(); + if (false == paymill.validateExpiry(jQuery('#paymill_card_expiry_month').val(), jQuery('#paymill_card_expiry_year').val())) { + jQuery(".paymill_payment_errors").text(paymill_lang.validateExpiry); + jQuery(paymill_form_checkout_submit_id).show(); + return false; } - if(paymill_shop_name == 'shopplugin'){ + + if (false == paymill.validateCvc(jQuery('#paymill_card_cvc').val())) { + jQuery(".paymill_payment_errors").text(paymill_lang.validateCvc); jQuery(paymill_form_checkout_submit_id).show(); + return false; } - }); - }else if(jQuery('#paymill_form_sepa').is(':visible') || jQuery('#paymill_sepa_iban').val() != '' && (jQuery('#payment_method_paymill').is(':checked') || jQuery('.wgm-second-checkout input[name=payment_method]').val() == 'paymill')){ + + paymill.createToken({ + number:jQuery('#paymill_card_number').val(), + exp_month:jQuery('#paymill_card_expiry_month').val(), + exp_year:jQuery('#paymill_card_expiry_year').val(), + cvc:jQuery('#paymill_card_cvc').val(), + cardholder:jQuery('#paymill_holdername_c').val(), + amount_int:jQuery('.paymill_amount').val(), + currency:jQuery('.paymill_currency').val() + }, function (error, result) { + if(error){ + // shows error + if(typeof paymill_lang[error.apierror] != 'undefined'){ + jQuery(".paymill_payment_errors").text(paymill_lang[error.apierror]); + }else{ + jQuery(".paymill_payment_errors").text(error.apierror); + } + jQuery(paymill_form_checkout_submit_id).show(); + }else{ + jQuery(".paymill_payment_errors").text(""); + var form = jQuery(paymill_form_checkout_id); + + // insert token into form + var token = result.token; + form.append(""); + paymill_youshallpass = true; + form.submit(); + } + if(paymill_shop_name == 'shopplugin'){ + jQuery(paymill_form_checkout_submit_id).show(); + } + }); + } + }else if(jQuery('#paymill_form_sepa').is(':visible') || (jQuery('#paymill_sepa_iban').length > 0 && jQuery('#paymill_sepa_iban').val() != '') && (jQuery('#payment_method_paymill').is(':checked') || jQuery('.wgm-second-checkout input[name=payment_method]').val() == 'paymill')){ if (false == paymill.validateIban(jQuery('#paymill_sepa_iban').val())) { jQuery(".paymill_payment_errors").text(paymill_lang.validateIBAN); jQuery(paymill_form_checkout_submit_id).show(); @@ -117,7 +175,7 @@ jQuery(document).ready(function () { paymill.createToken({ iban:jQuery('#paymill_sepa_iban').val(), bic:jQuery('#paymill_sepa_bic').val(), - accountholder:jQuery('#paymill_holdername').val(), + accountholder:jQuery('#paymill_holdername_s').val(), amount_int:jQuery('.paymill_amount').val(), currency:jQuery('.paymill_currency').val() }, function (error, result) { @@ -140,7 +198,7 @@ jQuery(document).ready(function () { form.submit(); } }); - }else if(jQuery('#paymill_form_elv').is(':visible') || jQuery('#paymill_elv_number').val() != '' && (jQuery('#payment_method_paymill').is(':checked') || jQuery('.wgm-second-checkout input[name=payment_method]').val() == 'paymill')){ + }else if(jQuery('#paymill_form_elv').is(':visible') || (jQuery('#paymill_elv_number').length > 0 && jQuery('#paymill_elv_number').val() != '') && (jQuery('#payment_method_paymill').is(':checked') || jQuery('.wgm-second-checkout input[name=payment_method]').val() == 'paymill')){ if (false == paymill.validateAccountNumber(jQuery('#paymill_elv_number').val())) { jQuery(".paymill_payment_errors").text(paymill_lang.validateAccountNumber); jQuery(paymill_form_checkout_submit_id).show(); @@ -156,7 +214,7 @@ jQuery(document).ready(function () { paymill.createToken({ number:jQuery('#paymill_elv_number').val(), bank:jQuery('#paymill_elv_bank_code').val(), - accountholder:jQuery('#paymill_holdername').val(), + accountholder:jQuery('#paymill_holdername_e').val(), amount_int:jQuery('.paymill_amount').val(), currency:jQuery('.paymill_currency').val() }, function (error, result) { diff --git a/lib/scripts.inc.php b/lib/scripts.inc.php index 1d027f3..6ca1dbe 100644 --- a/lib/scripts.inc.php +++ b/lib/scripts.inc.php @@ -31,7 +31,11 @@ function paymill_load_frontend_scripts(){ if(paymill_BENCHMARK)paymill_doBenchmark(true,'paymill_load_frontend_scripts'); // benchmark wp_deregister_script(array('paymill_bridge','paymill_bridge_custom')); wp_enqueue_script('jquery.formatCurrency-1.4.0.js',PAYMILL_PLUGIN_URL.'lib/js/jquery.formatCurrency-1.4.0.js', array('jquery'), PAYMILL_VERSION); - wp_enqueue_script('paymill_bridge', 'https://bridge.paymill.de/', array('jquery'), PAYMILL_VERSION); + if(empty($GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3']) || $GLOBALS['paymill_settings']->paymill_general_settings['pci_dss_3'] != '1'){ + wp_enqueue_script('paymill_bridge', 'https://bridge.paymill.com/dss3', array('jquery'), PAYMILL_VERSION); + }else{ + wp_enqueue_script('paymill_bridge', 'https://bridge.paymill.de/', array('jquery'), PAYMILL_VERSION); + } wp_localize_script('paymill_bridge', 'paymill_lang', array( 'validateCardNumber' => esc_attr__('Invalid Credit Card Number', 'paymill'), 'validateExpiry' => esc_attr__('Invalid Expiration Date', 'paymill'), diff --git a/lib/tpl/checkout_form.php b/lib/tpl/checkout_form.php index f5c422f..9c7a14a 100644 --- a/lib/tpl/checkout_form.php +++ b/lib/tpl/checkout_form.php @@ -55,14 +55,15 @@ } echo '
'.__('ELV', 'paymill').'
'; } - ?> -
- -
-