Add a custom payment gateway with additional radio buttons in Woocommerce
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
php wordpress woocommerce payment-gateway custom-fields
add a comment |
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
php wordpress woocommerce payment-gateway custom-fields
add a comment |
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
php wordpress woocommerce payment-gateway custom-fields
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
php wordpress woocommerce payment-gateway custom-fields
php wordpress woocommerce payment-gateway custom-fields
edited Nov 21 '18 at 3:35
LoicTheAztec
85.2k136095
85.2k136095
asked Nov 20 '18 at 5:52
Subhan Sunny
163
163
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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§ion=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
$order->reduce_order_stock();
// 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:
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387002%2fadd-a-custom-payment-gateway-with-additional-radio-buttons-in-woocommerce%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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§ion=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
$order->reduce_order_stock();
// 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:
add a comment |
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§ion=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
$order->reduce_order_stock();
// 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:
add a comment |
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§ion=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
$order->reduce_order_stock();
// 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:
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§ion=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
$order->reduce_order_stock();
// 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:
answered Nov 21 '18 at 3:32
LoicTheAztec
85.2k136095
85.2k136095
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387002%2fadd-a-custom-payment-gateway-with-additional-radio-buttons-in-woocommerce%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown