Add a custom payment gateway with additional radio buttons in Woocommerce

梦想的初衷 提交于 2019-12-11 06:26:40

问题


I am developing a custom payment method for woocommerce follogin is my code :

class WC_Gateway_Custom extends WC_Payment_Gateway {

    public $domain;

    /**
     * Constructor for the gateway.
     */
    public function __construct() {

        $this->domain = 'custom_payment';

        $this->id                 = 'custom';
        $this->icon               = apply_filters('woocommerce_custom_gateway_icon', '');
        $this->has_fields         = false;
        $this->method_title       = __( 'Custom', $this->domain );
        $this->method_description = __( 'Allows payments with custom gateway.', $this->domain );

        // 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 );
        $this->order_status = $this->get_option( 'order_status', 'completed' );

        // Actions
        add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
        add_action( 'woocommerce_thankyou_custom', array( $this, 'thankyou_page' ) );

        // Customer Emails
        add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
    }

    /**
     * Initialise Gateway Settings Form Fields.
     */
    public function init_form_fields() {

        $this->form_fields = array(
            'enabled' => array(
                'title'   => __( 'Enable/Disable', $this->domain ),
                'type'    => 'checkbox',
                'label'   => __( 'Enable Custom Payment', $this->domain ),
                'default' => 'yes'
            ),
            'title' => array(
                'title'       => __( 'Title', $this->domain ),
                'type'        => 'text',
                'description' => __( 'This controls the title which the user sees during checkout.', $this->domain ),
                'default'     => __( 'Custom Payment', $this->domain ),
                'desc_tip'    => true,
            ),
            'order_status' => array(
                'title'       => __( 'Order Status', $this->domain ),
                'type'        => 'select',
                'class'       => 'wc-enhanced-select',
                'description' => __( 'Choose whether status you wish after checkout.', $this->domain ),
                'default'     => 'wc-completed',
                'desc_tip'    => true,
                'options'     => wc_get_order_statuses()
            ),
            'description' => array(
                'title'       => __( 'Description', $this->domain ),
                'type'        => 'textarea',
                'description' => __( 'Payment method description that the customer will see on your checkout.', $this->domain ),
                'default'     => __('Payment Information', $this->domain),
                'desc_tip'    => true,
            ),
            'instructions' => array(
                'title'       => __( 'Instructions', $this->domain ),
                'type'        => 'textarea',
                'description' => __( 'Instructions that will be added to the thank you page and emails.', $this->domain ),
                'default'     => '',
                'desc_tip'    => true,
            ),
        );
    }

    /**
     * Output for the order received page.
     */
    public function thankyou_page() {
        if ( $this->instructions )
            echo wpautop( wptexturize( $this->instructions ) );
    }

    /**
     * Add content to the WC emails.
     *
     * @access public
     * @param WC_Order $order
     * @param bool $sent_to_admin
     * @param bool $plain_text
     */        

    public function payment_fields(){

        if ( $description = $this->get_description() ) {
            echo wpautop( wptexturize( $description ) );
        }
        echo 'added custom field in radio buttons';
     /**
     * Process the payment and return the result.
     *
     * @param int $order_id
     * @return array
     */
    }
    public function generate_form($order_id){
        global $woocommerce;

    // Get this Order's information so that we know
    // who to charge and how much
    $customer_order = new WC_Order($order_id);

    $_instructions     = $this->instructions;
    $_order_status    = $this->order_status;


    $items = $customer_order->get_items();
    $product_name  = array();
    foreach ( $items as $item ) {
        array_push($product_name, $item['name']);
    }
    $_Description   = implode(", ", $product_name);
    echo 'here i want to get the value selected by the customer from front end';
    //here is the part where i want to get the value of form inside payment_fields() fucntion 
    exit;   
    } 

}

i need to set transaction type of my custom payment method attaching screen shot as well for better understanding, see:

there is no help on how to over ride this payment_fields() function i can get the html printed but don't have any idea how to get the value and set it as transaction type of the order


回答1:


There is some errors, mistakes and missing things in your code… Here is a complete plugin file that works adding to this "Special" payment radio buttons on the gateway when it's selected in checkout page.

The selected "Transaction type" radio button value will be saved in the order as custom meta data.

The selected "Transaction type" value will be displayed in:

  • Order recieved page, My account > View Order
  • Admin Edit order pages
  • On the email notifications

On Order view page:

Here is the complete plugin code:

<?php
/**
 * Plugin Name: WooCommerce Special Payment Gateway
 * Plugin URI:
 * Description: custom Special payment method.
 * Author: Me
 * Author URI: http://www.something.tld/
 * Version: 1.1.0
 * Text Domain: wcpg-special
 * Domain Path: /i18n/languages/
 *
 * Copyright: (c) 2018
 *
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 *
 * @package   wcpg-special
 * @author    Me
 * @category  Admin
 * @copyright Copyright (c)  2016-2018
 * @license   http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
 */
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 + Custom Special gateway
 */
function wc_add_special_to_gateways( $gateways ) {
    $gateways[] = 'WC_Gateway_Special';
    return $gateways;
}
add_filter( 'woocommerce_payment_gateways', 'wc_add_special_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_special_gateway_plugin_links( $links ) {
    $plugin_links = array(
        '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout&section=special_payment' ) . '">' . __( 'Configure', 'wcpg-special' ) . '</a>'
    );
    return array_merge( $plugin_links, $links );
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'wc_special_gateway_plugin_links' );
/**
 * Custom Payment Gateway
 *
 * Provides an Custom Payment Gateway; mainly for testing purposes.
 * We load it later to ensure WC is loaded first since we're extending it.
 *
 * @class       WC_Gateway_Special
 * @extends     WC_Payment_Gateway
 * @version     1.0.0
 * @package     WooCommerce/Classes/Payment
 * @author      Me
 */
add_action( 'plugins_loaded', 'wc_special_gateway_init', 11 );
function wc_special_gateway_init() {
    class WC_Gateway_Special extends WC_Payment_Gateway {

        public $domain;

        /**
         * Constructor for the gateway.
         */
        public function __construct() {
            $this->id                 = 'special_payment';
            $this->domain             = 'wcpg-special';
            $this->icon               = apply_filters('woocommerce_payment_gateway_icon', '');
            $this->has_fields         = false;
            $this->method_title       = __( 'Custom Payment', $this->domain );

            // Define "payment type" radio buttons options field
            $this->options = array(
                'type1' => __( 'Type 1', $this->domain ),
                'type2' => __( 'Type 2', $this->domain ),
                'type3' => __( 'Type 3', $this->domain ),
            );

            // 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->order_status = $this->get_option( 'order_status' );
            $this->status_text  = $this->get_option( 'status_text' );

            // Actions
            add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
            add_action( 'woocommerce_checkout_create_order', array( $this, 'save_order_payment_type_meta_data' ), 10, 2 );
            add_filter( 'woocommerce_get_order_item_totals', array( $this, 'display_transaction_type_order_item_totals'), 10, 3 );
            add_action( 'woocommerce_admin_order_data_after_billing_address',  array( $this, 'display_payment_type_order_edit_pages'), 10, 1 );
            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 );
        }
        /**
         * Initialize Gateway Settings Form Fields
         */
        public function init_form_fields() {
            $this->form_fields = apply_filters( 'wc_special_payment_form_fields', array(
                'enabled' => array(
                    'title'   => __( 'Enable/Disable', $this->domain ),
                    'type'    => 'checkbox',
                    'label'   => __( 'Enable Special Payment', $this->domain ),
                    'default' => 'yes'
                ),
                'title' => array(
                    'title'       => __( 'Title', $this->domain ),
                    'type'        => 'text',
                    'description' => __( 'This controls the title for the payment method the customer sees during checkout.', $this->domain ),
                    'default'     => __( 'Special Payment', $this->domain ),
                    'desc_tip'    => true,
                ),
                'description' => array(
                    'title'       => __( 'Description', $this->domain ),
                    'type'        => 'textarea',
                    'description' => __( 'Payment method description that the customer will see on your checkout.', $this->domain ),
                    'default'     => __( 'Please remit payment to Store Name upon pickup or delivery.', $this->domain ),
                    'desc_tip'    => true,
                ),
                'instructions' => array(
                    'title'       => __( 'Instructions', $this->domain ),
                    'type'        => 'textarea',
                    'description' => __( 'Instructions that will be added to the thank you page and emails.', $this->domain ),
                    'default'     => '', // Empty by default
                    'desc_tip'    => true,
                ),
                'order_status' => array(
                    'title'       => __( 'Order Status', $this->domain ),
                    'type'        => 'select',
                    'description' => __( 'Choose whether order status you wish after checkout.', $this->domain ),
                    'default'     => 'wc-completed',
                    'desc_tip'    => true,
                    'class'       => 'wc-enhanced-select',
                    'options'     => wc_get_order_statuses()
                ),
                'status_text' => array(
                    'title'       => __( 'Order Status Text', $this->domain ),
                    'type'        => 'text',
                    'description' => __( 'Set the text for the selected order status.', $this->domain ),
                    'default'     => __( 'Order is completed', $this->domain ),
                    'desc_tip'    => true,
                ),
            ) );
        }

        /**
         * Output the "payment type" radio buttons fields in checkout.
         */
        public function payment_fields(){
            if ( $description = $this->get_description() ) {
                echo wpautop( wptexturize( $description ) );
            }

            echo '<style>#transaction_type_field label.radio { display:inline-block; margin:0 .8em 0 .4em}</style>';

            $option_keys = array_keys($this->options);

            woocommerce_form_field( 'transaction_type', array(
                'type'          => 'radio',
                'class'         => array('transaction_type form-row-wide'),
                'label'         => __('Payment Information', $this->domain),
                'options'       => $this->options,
            ), reset( $option_keys ) );
        }

        /**
         * Save the chosen payment type as order meta data.
         *
         * @param object $order
         * @param array $data
         */
        public function save_order_payment_type_meta_data( $order, $data ) {
            if ( $data['payment_method'] === $this->id && isset($_POST['transaction_type']) )
                $order->update_meta_data('_transaction_type', esc_attr($_POST['transaction_type']) );
        }

        /**
         * Output for the order received page.
         *
         * @param int $order_id
         */
        public function thankyou_page( $order_id ) {
            $order = wc_get_order( $order_id );

            if ( $this->instructions ) {
                echo wpautop( wptexturize( $this->instructions ) );
            }
        }

        /**
         * Display the chosen payment type on the order edit pages (backend)
         *
         * @param object $order
         */
        public function display_payment_type_order_edit_pages( $order ){
            if( $this->id === $order->get_payment_method() && $order->get_meta('_transaction_type') ) {
                $options  = $this->options;
                echo '<p><strong>'.__('Transaction type').':</strong> ' . $options[$order->get_meta('_transaction_type')] . '</p>';
            }
        }

        /**
         * Display the chosen payment type on order totals table
         *
         * @param array    $total_rows
         * @param WC_Order $order
         * @param bool     $tax_display
         * @return array
         */
        public function display_transaction_type_order_item_totals( $total_rows, $order, $tax_display ){
            if( is_a( $order, 'WC_Order' ) && $order->get_meta('_transaction_type') ) {
                $new_rows = []; // Initializing
                $options  = $this->options;

                // Loop through order total lines
                foreach( $total_rows as $total_key => $total_values ) {
                    $new_rows[$total_key] = $total_values;
                    if( $total_key === 'payment_method' ) {
                        $new_rows['payment_type'] = [
                            'label' => __("Transaction type", $this->domain) . ':',
                            'value' => $options[$order->get_meta('_transaction_type')],
                        ];
                    }
                }

                $total_rows = $new_rows;
            }
            return $total_rows;
        }

        /**
         * 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->get_payment_method()
            && $order->has_status( $this->order_status ) ) {
                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( $this->order_status, $this->status_text );

            // Reduce stock levels
            wc_reduce_stock_levels( $order->get_id() );

            // Remove cart
            WC()->cart->empty_cart();

            // Return thankyou redirect
            return array(
                'result'    => 'success',
                'redirect'  => $this->get_return_url( $order )
            );
        }
    }
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

On Email notifications:



来源:https://stackoverflow.com/questions/53387002/add-a-custom-payment-gateway-with-additional-radio-buttons-in-woocommerce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!