Я начал писать свой плагин под wordpress для woocommerce. Хочу написать плагин, который добавит дополнительный способ оплаты "Оплата по счету".
Отличительная особенность этого платежного шлюза заключается в том, что он имеет свою отдельную форму. И после заполнения формы и отправки данных, будет формироваться pdf файл.
Теперь о проблеме с которой я столкнулся в ходе написания плагина. Я не знаю как сделать правильно так, чтобы при выборе моего способа оплаты, менялась форма. Я попытался реализовать это через js, но это привело к некоторым проблемам: с проверкой валидацией, с тем что старая форма возвращается если обновить корзину и нажать на input.
Вот код моего плагина:
<?php
/**
* Plugin Name: Оплата по счету для Woocommerce
* Plugin URI: -
* Description: Данный плагин предоставляет дополнительный способ олпаты предназначенный для юр. лиц.
* Author: -
* Author URI: -
* Version: 0.0.1
* Text Domain: wc-gateway-offline
* Domain Path: /i18n/languages/
*
* Copyright: (c) 2015-2016 SkyVerge, Inc. (info@skyverge.com) and WooCommerce
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*
* @package WC-Gateway-Offline
* @author SkyVerge
* @category Admin
* @copyright Copyright (c) 2015-2016, SkyVerge, Inc. and WooCommerce
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
*
* This offline gateway forks the WooCommerce core "Cheque" payment gateway to create another offline payment method.
*/
defined( 'ABSPATH' ) or exit;
// Make sure WooCommerce is active
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
return;
}
/**
* Add the gateway to WC Available Gateways
*
* @since 1.0.0
* @param array $gateways all available WC gateways
* @return array $gateways all WC gateways + offline gateway
*/
function wc_offline_add_to_gateways( $gateways ) {
$gateways[] = 'WC_Gateway_Offline';
return $gateways;
}
add_filter( 'woocommerce_payment_gateways', 'wc_offline_add_to_gateways' );
/**
* Adds plugin page links
*
* @since 1.0.0
* @param array $links all plugin links
* @return array $links all plugin links + our custom links (i.e., "Settings")
*/
function wc_offline_gateway_plugin_links( $links ) {
$plugin_links = array(
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=offline_gateway' ) . '">' . __( 'Configure', 'wc-gateway-offline' ) . '</a>'
);
return array_merge( $plugin_links, $links );
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'wc_offline_gateway_plugin_links' );
/**
* Offline Payment Gateway
*
* Provides an Offline Payment Gateway; mainly for testing purposes.
* We load it later to ensure WC is loaded first since we're extending it.
*
* @class WC_Gateway_Offline
* @extends WC_Payment_Gateway
* @version 1.0.0
* @package WooCommerce/Classes/Payment
* @author SkyVerge
*/
add_action( 'plugins_loaded', 'wc_offline_gateway_init', 11 );
function wc_offline_gateway_init() {
class WC_Gateway_Offline extends WC_Payment_Gateway {
/**
* Constructor for the gateway.
*/
public function __construct() {
$this->plugin_url = trailingslashit(WP_PLUGIN_URL.'/'.dirname(plugin_basename(__FILE__)));
$this->id = 'payment-on-account';
$this->icon = apply_filters('woocommerce_offline_icon', '');
$this->has_fields = false;
$this->method_title = __( 'Offline', 'wc-gateway-offline' );
$this->method_description = __( 'Allows offline payments. Very handy if you use your cheque gateway for another payment method, and can help with testing. Orders are marked as "on-hold" when received.', 'wc-gateway-offline' );
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->instructions = $this->get_option( 'instructions', $this->description );
// Actions
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) );
// Customer Emails
add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
add_action('wp_print_scripts', array(&$this, 'include_scripts'));
}
function include_scripts() {
wp_enqueue_script( 'pa-shape-change', $this->plugin_url . '/js/shape-change.js');
}
/**
* Initialize Gateway Settings Form Fields
*/
public function init_form_fields() {
$this->form_fields = apply_filters( 'wc_offline_form_fields', array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'wc-gateway-offline' ),
'type' => 'checkbox',
'label' => __( 'Enable Offline Payment', 'wc-gateway-offline' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title', 'wc-gateway-offline' ),
'type' => 'text',
'description' => __( 'This controls the title for the payment method the customer sees during checkout.', 'wc-gateway-offline' ),
'default' => __( 'Оплата по счету', 'wc-gateway-offline' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'wc-gateway-offline' ),
'type' => 'textarea',
'description' => __( 'Payment method description that the customer will see on your checkout.', 'wc-gateway-offline' ),
'default' => __( 'Пожалуйста, отправьте платеж на имя магазина при получении или доставке.', 'wc-gateway-offline' ),
'desc_tip' => true,
),
'instructions' => array(
'title' => __( 'Instructions', 'wc-gateway-offline' ),
'type' => 'textarea',
'description' => __( 'Инструкции, которые будут добавлены на страницу благодарности и электронные письма.', 'wc-gateway-offline' ),
'default' => '',
'desc_tip' => true,
),
) );
}
/**
* Output for the order received page.
*/
public function thankyou_page() {
if ( $this->instructions ) {
echo wpautop( wptexturize( $this->instructions ) );
echo 'test: bla bla';
}
}
/**
* Add content to the WC emails.
*
* @access public
* @param WC_Order $order
* @param bool $sent_to_admin
* @param bool $plain_text
*/
public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
if ( $this->instructions && ! $sent_to_admin && $this->id === $order->payment_method && $order->has_status( 'on-hold' ) ) {
echo wpautop( wptexturize( $this->instructions ) ) . PHP_EOL;
}
}
/**
* Process the payment and return the result
*
* @param int $order_id
* @return array
*/
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
// Mark as on-hold (we're awaiting the payment)
$order->update_status( 'on-hold', __( 'Awaiting offline payment', 'wc-gateway-offline' ) );
// Reduce stock levels
$order->reduce_order_stock();
// Remove cart
WC()->cart->empty_cart();
// Return thankyou redirect
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
} // end \WC_Gateway_Offline class
}
Вот код js файла:
window.onload = function() {
console.log($().jquery);
var formContent = $('#customer_details').html();
var formDefault = true;
$(document).ajaxComplete(function(header) {
$('input').on('click', function() {
console.log($(this).get(0).id);
if($(this).get(0).id == 'payment_method_payment-on-account') {
$('#customer_details').children('div').remove();
formDefault = false;
$('#customer_details').append("<div class='woocommerce-billing-fields'><div class='woocommerce-billing-fields__field-wrapper'><p class='form-row form-row-first validate-required' id='billing_first_name_field' data-priority='10'><label for='billing_first_name' class=''>Имя <abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='text' class='input-text ' name='name-ep' id='billing_first_name' placeholder='Полное наименование организации или ИП' autocomplete='given-name'></span></p><p class='form-row form-row-wide validate-required validate-phone' id='billing_phone_field' data-priority='100'><label for='billing_phone' class=''>Телефон <abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='tel' class='input-text ' name='enn' id='billing_phone' placeholder='ИНН' autocomplete='tel'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email <abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='kpp' id='billing_email' placeholder='КПП' autocomplete='email username'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email <abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='legal-address' id='billing_email' placeholder='Юридический адрес' autocomplete='email username'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email <abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='contact-number' id='billing_email' placeholder='Контактный телефон' autocomplete='email username'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email <abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='email' id='billing_email' placeholder='Электронная почта' autocomplete='email username'></span></p></div></div>");
}
else {
if(formDefault != true) {
$('#customer_details').children('div').remove();
$('#customer_details').append(formContent);
}
formDefault = true;
}
});
});
}
Пока "плагин" состоит из 2 файлов.
Что мне собственно нужно: я очень хочу разобраться в том, как это должно быть устроено. Так же было бы не плохо, если бы мне указали на мои ошибки, чтобы впредь я их больше не совершал.
P.s. Я искал информацию о том, как это сделать в google, но не нашел ответа. Буду рад любой информации или ссылке.
P.s.s. Я вообще это затеял, потому что не смог найти аналогичного решения, если вдруг он уже существует, буду рад получить ссылку на него.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости