How to add iframe payment gateway in woocommerce? - php

I am trying to add another WooCommerce payment method called xxxx Bank Gateway on checkout page and when selected, this payment method will load an iframe like below (the iframe will redirect to the banks site lets call it $url).
How can I declare the content that will be displayed below the Checkout option?
//Frontend:
<input id="payment_method_xxxx" type="radio" class="input-radio" name="payment_method" value="xxxx" data-order_button_text="">
<label for="payment_method_xxx">
xxx Payment </label>
Here is my code so far:
<?php
/*
Plugin Name: xxxxxxx WooCommerce Payment Gateway
Plugin URI: http://www.xxxxxxx.com/
Description: xxxxxxx enables merchants to authorize, settle and manage credit card and electronic check transactions via Web sites, retail stores, mail order/telephone order (MOTO) call centers and mobile devices.
Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/*
* This action hook registers our PHP class as a WooCommerce payment gateway
*/
add_filter( 'woocommerce_payment_gateways', 'xxxxxxx_add_gateway_class' );
function xxxxxxx_add_gateway_class( $gateways ) {
$gateways[] = 'WC_xxxxxxx_Gateway'; // your class name is here
return $gateways;
}
/*
* The class itself, please note that it is inside plugins_loaded action hook
*/
add_action( 'plugins_loaded', 'xxxxxxx_init_gateway_class' );
function xxxxxxx_init_gateway_class() {
class WC_xxxxxxx_Gateway extends WC_Payment_Gateway {
/**
* Constructor
*/
public function __construct() {
// global ID
$this->id = 'xxxxxxx'; // payment gateway plugin ID
$this->icon = ''; // URL of the icon that will be displayed on checkout page near your gateway name
$this->has_fields = true; // in case you need a custom credit card form
// Show Title
$this->method_title = 'xxxxxxx Gateway';
// Show Description
$this->method_description = 'Description of xxxxxxx payment gateway'; // will be displayed on the options page
// setting defines
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
// further check of SSL if you want
//add_action( 'admin_notices', array( $this, 'do_ssl_check' ) );
// This action hook saves the settings
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ));
}
public function init_form_fields(){
$this->form_fields = array(
'enabled' => array(
'title' => 'Enable/Disable',
'label' => 'Enable Epcipay Gateway',
'type' => 'checkbox',
'description' => '',
'default' => 'no'
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'xxxxxxx Payment', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'textarea',
'default' => ''
),
'terminal_id' => array(
'title' => 'Terminal Id',
'type' => 'text'
),
'api_key' => array(
'title' => 'API Key',
'type' => 'password',
),
'password' => array(
'title' => 'Password',
'type' => 'text'
),
'pageid' => array(
'title' => 'Page Id',
'type' => 'text'
)
);
}
public function payment_fields() {
//how to add script tag to show the hosted checkout
// credit card form loaded from third party server -- Iframe
}
}

Related

Saving Woocommerce Payment Gateway settings on a custom admin page

I'm trying to create a custom admin page which has Woocommerce Stripe Payment gateway options. Specifically just the Stripe API keys related fields. Reason for this is I need to limit access to Woocommerce settings pages and only want to expose very few things, so bringing just the few things to a custom page seems like the simplest thing.
However, this has been trickier than I expected. I've been trying to do this through extending WC_Payment_Gateway class, but this now seems like the wrong idea. Since I don't think I can extend a specific Gateway's class? I would basically need to rewrite the Stripe plugin I guess.
Also thinking there must be an easier way. Has anyone done this before?
Is it possible to create a settings forms with Woocommerce Settings API outside of the normal WC settings page?
Using this method, I didn't actually even get the form to print out, just the fields (i.e. no Submit button).
class WoocommerceStripeInt extends WC_Payment_Gateway
{
public function __construct () {
$this->id = 'stripe';
$this->method_title = __( 'Stripe', 'woocommerce-gateway-stripe' );
/* translators: 1) link to Stripe register page 2) link to Stripe api keys page */
$this->method_description = __( 'Stripe works by adding payment fields on the checkout and then sending the details to Stripe for verification.', 'woocommerce-gateway-stripe' );
$this->has_fields = true;
// Load the settings fields.
$this->init_form_fields();
// Load the settings.
$this->init_settings();
// Get setting values.
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->instructions = $this->get_option( 'instructions' );
$this->order_status = $this->get_option( 'testmode' );
add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));
}
/**
* Initialise Gateway Settings Form Fields
*/
function init_form_fields() {
$this->form_fields = apply_filters(
'wc_stripe_settings', array(
'testmode' => [
'title' => __( 'Test mode', 'woocommerce-gateway-stripe' ),
'label' => __( 'Enable Test Mode', 'woocommerce-gateway-stripe' ),
'type' => 'checkbox',
'description' => __( 'Place the payment gateway in test mode using test API keys.', 'woocommerce-gateway-stripe' ),
'default' => 'yes',
'desc_tip' => true,
],
'test_publishable_key' => [
'title' => __( 'Test Publishable Key', 'woocommerce-gateway-stripe' ),
'type' => 'text',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "pk_test_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
'test_secret_key' => [
'title' => __( 'Test Secret Key', 'woocommerce-gateway-stripe' ),
'type' => 'password',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "sk_test_" or "rk_test_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
'publishable_key' => [
'title' => __( 'Live Publishable Key', 'woocommerce-gateway-stripe' ),
'type' => 'text',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "pk_live_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
'secret_key' => [
'title' => __( 'Live Secret Key', 'woocommerce-gateway-stripe' ),
'type' => 'password',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "sk_live_" or "rk_live_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
)
);
}
function admin_options() {
?>
<h2><?php _e('Stripe Settings','woocommerce'); ?></h2>
<table class="form-table">
<?php $this->generate_settings_html(); ?>
</table> <?php
}
}
Any help would be appreciated, thanks.

Create a new shipping method in woocommerce 3

I need help in generating new shipping method in woocommerce version 3+. The name for new field is "Nextday delivery". Like the flat rate it also need to be there in the method but it was not displayed in the drop down select field.
The below is the code which I tried. But it's not working for me.
function request_a_shipping_quote_init() {
if ( ! class_exists( 'WC_Request_Shipping_Quote_Method' ) ) {
class WC_Request_Shipping_Quote_Method extends WC_Shipping_Method {
public function __construct() {
$this->id = 'request_a_shipping_quote'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'Request a Shipping Quote' ); // Title shown in admin
$this->method_description = __( 'Shipping method to be used where the exact shipping amount needs to be quoted' ); // Description shown in admin
$this->title = "Request a Shipping Quote"; // This can be added as an setting but for this example its forced.
$this->supports = array(
'shipping-zones'
);
$this->init();
}
function init() {
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable', 'dc_raq' ),
'type' => 'checkbox',
'description' => __( 'Enable this shipping method.', 'dc_raq' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title', 'dc_raq' ),
'type' => 'text',
'description' => __( 'Title to be displayed on site', 'dc_raq' ),
'default' => __( 'Request a Quote', 'dc_raq' )
),
);
}
public function calculate_shipping( $packages = array() ) {
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => '0.00',
'calc_tax' => 'per_item'
);
$this->add_rate( $rate );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'request_a_shipping_quote_init' );
function request_shipping_quote_shipping_method( $methods ) {
$methods['request_shipping_quote_shipping_method'] = 'WC_Request_Shipping_Quote_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'request_shipping_quote_shipping_method' );
I need it to come in the dropdown like flatrate free shipping etc but it was not coming in the dropdown.
There were some missing things and others unnecessary. The correct way to make it work is:
add_action('woocommerce_shipping_init', 'request_shipping_quote_method');
function request_shipping_quote_method() {
if ( ! class_exists( 'WC_Request_Shipping_Quote_Method' ) ) {
class WC_Request_Shipping_Quote_Method extends WC_Shipping_Method {
public function __construct( $instance_id = 0) {
$this->id = 'request_shipping_quote';
$this->instance_id = absint( $instance_id );
$this->domain = 'rasq';
$this->method_title = __( 'Request a Shipping Quote', $this->domain );
$this->method_description = __( 'Shipping method to be used where the exact shipping amount needs to be quoted', $this->domain );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
## Load the settings API
function init() {
$this->init_form_fields();
$this->init_settings();
$this->enabled = $this->get_option( 'enabled', $this->domain );
$this->title = $this->get_option( 'title', $this->domain );
$this->info = $this->get_option( 'info', $this->domain );
add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
}
function init_form_fields() {
$this->instance_form_fields = array(
'title' => array(
'type' => 'text',
'title' => __('Title', $this->domain),
'description' => __( 'Title to be displayed on site.', $this->domain ),
'default' => __( 'Request a Quote ', $this->domain ),
),
'cost' => array(
'type' => 'text',
'title' => __('Coast', $this->domain),
'description' => __( 'Enter a cost', $this->domain ),
'default' => '',
),
);
}
public function calculate_shipping( $packages = array() ) {
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => '0',
'calc_tax' => 'per_item'
);
$this->add_rate( $rate );
}
}
}
}
add_filter('woocommerce_shipping_methods', 'add_request_shipping_quote');
function add_request_shipping_quote( $methods ) {
$methods['request_shipping_quote'] = 'WC_Request_Shipping_Quote_Method';
return $methods;
}
Code goes in function.php file of your active child theme (active theme).
Tested and works.
Here the shipping method selector now displays this "Request a shipping coast" method:
Once selected and added, it's created this time:
If you edit it:

Custom new tab in Woocommerce my account pages

This question is about my woocommerce shop. I am trying to add new tab in my-account page (ticket tab). Eeverything going right, but when I hit the "ticket" tab I getting "404 not found" error!
I thought it should be work, but its no working.
Here is changes log:
add ticket code to woocommerce/includes/wc-template-functions.php
if ( ! function_exists( 'woocommerce_account_ticket' ) ) {
/**
* My Account > Ticket template.
*/
function woocommerce_account_ticket() {
wc_get_template( 'myaccount/ticket.php' );
}
}
add ticket code to woocommerce/includes/wc-template-hooks.php
add_action( 'woocommerce_account_ticket_endpoint', 'woocommerce_account_ticket' );
add ticket code to woocommerce/includes/admin/settings/class-wc-settings-accounts.php
array(
'title' => __( 'Ticket', 'woocommerce' ),
'desc' => __( 'Endpoint for the "My account → ticket" page.', 'woocommerce' ),
'id' => 'woocommerce_myaccount_ticket_endpoint',
'type' => 'text',
'default' => 'ticket',
'desc_tip' => true,
),
add ticket code to woocommerce/includes/wc-account-functions.php
function wc_get_account_menu_items() {
$endpoints = array(
'ticket' => get_option( 'woocommerce_myaccount_ticket_endpoint', 'ticket' ),
);
$items = array(
'ticket' => __( 'Ticket', 'woocommerce' ),
);
add ticket code to woocommerce/includes/class-wc-query.php
'ticket' => get_option( 'woocommerce_myaccount_ticket_endpoint', 'ticket' ),
I don't want to update my woocommerce plugin, so there is no problem about playing with main plugin codes.

How to create simple Offline payment gateway for WooCommerce?

Good afternoon, I want to make simple copy of Cash on Delivery (COD) payment method in my store and rename it to Coupon on Delivery.
How to implement it?
Up
I have tried this code, but it shows error 500 on WC settings page:
<?php
/**
* Plugin Name: My New WooCommerce Gateway
* Plugin URI:
* Description: WooCommerce gateway to ....
* Author: .....
* Version: 1.0
* Author URI: https://example.org/
* Text Domain: woocommerce-my-gateway
* Domain Path: /languages/
*/
add_action( 'plugins_loaded', 'init_my_gateway_class' );
function init_my_gateway_class() {
if ( !class_exists( 'WooCommerce' ) ) return;
class WC_Gateway_COD_Renamed extends WC_Payment_Gateway {
}
}
function add_my_gateway_class( $methods ) {
$methods[] = 'WC_Gateway_my_gateway';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_my_gateway_class' );
function my_load_textdomain(){
load_plugin_textdomain( 'woocommerce-my-gateway', false, dirname( plugin_dir_path( __FILE__ ) . '/languages/' ) );
}
add_action('plugins_loaded', 'my_load_textdomain');
Source of code
In your main plugin file you can include the class and filter the gateways at the same time:
function add_my_gateway_class( $methods ) {
include( 'class-wc-gateway-cod-renamed.php');
$methods[] = 'WC_Gateway_COD_Renamed';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_my_gateway_class' );
There's no real need to check if WooCommerce is active this way as woocommerce_payment_gateways only exists if WooCommerce is running.
Then in another file called class-wc-gateway-cod-renamed.php you can define your class:
class WC_Gateway_COD_Renamed extends WC_Gateway_COD {
/**
* Setup general properties for the gateway.
*/
protected function setup_properties() {
$this->id = 'coupon-on-delivery';
$this->icon = apply_filters( 'woocommerce_coupon-on-deliver_icon', '' );
$this->method_title = __( 'Coupon on delivery', 'your-plugin' );
$this->method_description = __( 'Have your customers pay with a coupon upon delivery.', 'your-plugin' );
$this->has_fields = false;
}
/**
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$shipping_methods = array();
foreach ( WC()->shipping()->load_shipping_methods() as $method ) {
$shipping_methods[ $method->id ] = $method->get_method_title();
}
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'your-plugin' ),
'label' => __( 'Enable coupon on delivery', 'your-plugin' ),
'type' => 'checkbox',
'description' => '',
'default' => 'no',
),
'title' => array(
'title' => __( 'Title', 'your-plugin' ),
'type' => 'text',
'description' => __( 'Payment method description that the customer will see on your checkout.', 'your-plugin' ),
'default' => __( 'coupon on delivery', 'your-plugin' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'your-plugin' ),
'type' => 'textarea',
'description' => __( 'Payment method description that the customer will see on your website.', 'your-plugin' ),
'default' => __( 'Pay with coupon upon delivery.', 'your-plugin' ),
'desc_tip' => true,
),
'instructions' => array(
'title' => __( 'Instructions', 'your-plugin' ),
'type' => 'textarea',
'description' => __( 'Instructions that will be added to the thank you page.', 'your-plugin' ),
'default' => __( 'Pay with coupon upon delivery.', 'your-plugin' ),
'desc_tip' => true,
),
'enable_for_methods' => array(
'title' => __( 'Enable for shipping methods', 'your-plugin' ),
'type' => 'multiselect',
'class' => 'wc-enhanced-select',
'css' => 'width: 400px;',
'default' => '',
'description' => __( 'If coupon upon delivery is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'your-plugin' ),
'options' => $shipping_methods,
'desc_tip' => true,
'custom_attributes' => array(
'data-placeholder' => __( 'Select shipping methods', 'your-plugin' ),
),
),
'enable_for_virtual' => array(
'title' => __( 'Accept for virtual orders', 'your-plugin' ),
'label' => __( 'Accept coupon if the order is virtual', 'your-plugin' ),
'type' => 'checkbox',
'default' => 'yes',
),
);
}
}
Extend the WC_Gateway_COD class so that you can inherit methods from it and only override the methods that have to do with the naming of things.
In WooCommerce plugin, you can enable payment gateway COD from admin section:
Admin >> WooCommerce >> Settings >> Checkout >> Cash on delivery.
Check option for enable COD.
Please refer below link for create offline payment gateway.
How to Create A WooCommerce Payment gateway

WooCommerce custom email for custom payment gateway

So I have created an add on plugin for WooCommerce. I have a custom class to extend the 'cheque' payment gateway to allow a user to perform a wholesale checkout without payment. So far this functionality works perfect. The issue is I cannot get the custom email to work with this custom payment. I'm not sure if i'm connecting the two custom classes together. Am I missing something in my trigger or using the wrong hook for the trigger?
Right here I include the email class..
function add_dealer_invoice_woocommerce_email( $email_classes ) {
// include our custom email class
require_once( 'includes/class-wc-dealer-invoice-email.php' );
// add the email class to the list of email classes that WooCommerce loads
$email_classes['WC_Dealer_Invoice_Email'] = new WC_Dealer_Invoice_Email();
return $email_classes;
}
add_filter( 'woocommerce_email_classes', 'add_dealer_invoice_woocommerce_email' );
// Register new status for woocomerce 2.2+
function register_dealer_invoice_order_status() {
register_post_status( 'wc-dealer-invoice', array(
'label' => 'Dealer Invoice',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Awaiting payment <span class="count">(%s)</span>', 'Awaiting payment <span class="count">(%s)</span>' )
) );
}
add_action( 'init', 'register_dealer_invoice_order_status' );
And here is the custom email class that extends WC_Email
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
class WC_Dealer_Invoice_Email extends WC_Email {
public function __construct() {
// set ID, this simply needs to be a unique name
$this->id = 'wc_dealer_invoice';
// this is the title in WooCommerce Email settings
$this->title = 'Dealer Invoice';
// this is the description in WooCommerce email settings
$this->description = 'Dealer Invoice Notification emails are sent when a customer places a wholesale order on consignment';
// these are the default heading and subject lines that can be overridden using the settings
$this->heading = 'Dealer Invoice Order';
$this->subject = 'Dealer Invoice Order';
// these define the locations of the templates that this email should use, we'll just use the new order template since this email is similar
$this->template_html = 'emails/admin-new-order.php';
$this->template_plain = 'emails/plain/admin-new-order.php';
// Trigger on new paid orders
add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_checkout_order_processed', array( $this, 'trigger' ) );
// Call parent constructor to load any other defaults not explicity defined here
parent::__construct();
// this sets the recipient to the settings defined below in init_form_fields()
$this->recipient = $this->get_option( 'recipient' );
// if none was entered, just use the WP admin email as a fallback
if ( ! $this->recipient )
$this->recipient = get_option( 'admin_email' );
}
/**
* Determine if the email should actually be sent and setup email merge variables
*
* #since 0.1
* #param int $order_id
*/
public function trigger( $order_id ) {
// bail if no order ID is present
if ( ! $order_id )
return;
// setup order object
$this->object = new WC_Order( $order_id );
// bail if shipping method is not expedited
if ( 'cheque' != get_post_meta( $order_id, '_payment_method', true ))
return;
// replace variables in the subject/headings
$this->find[] = '{order_date}';
$this->replace[] = date_i18n( woocommerce_date_format(), strtotime( $this->object->order_date ) );
$this->find[] = '{order_number}';
$this->replace[] = $this->object->get_order_number();
if ( ! $this->is_enabled() || ! $this->get_recipient() )
return;
// woohoo, send the email!
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
/**
* get_content_html function.
*
* #since 0.1
* #return string
*/
public function get_content_html() {
ob_start();
woocommerce_get_template( $this->template_html, array(
'order' => $this->object,
'email_heading' => $this->get_heading()
) );
return ob_get_clean();
}
/**
* get_content_plain function.
*
* #since 0.1
* #return string
*/
public function get_content_plain() {
ob_start();
woocommerce_get_template( $this->template_plain, array(
'order' => $this->object,
'email_heading' => $this->get_heading()
) );
return ob_get_clean();
}
/**
* Initialize Settings Form Fields
*
* #since 2.0
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => 'Enable/Disable',
'type' => 'checkbox',
'label' => 'Enable this email notification',
'default' => 'yes'
),
'recipient' => array(
'title' => 'Recipient(s)',
'type' => 'text',
'description' => sprintf( 'Enter recipients (comma separated) for this email. Defaults to <code>%s</code>.', esc_attr( get_option( 'admin_email' ) ) ),
'placeholder' => '',
'default' => ''
),
'subject' => array(
'title' => 'Subject',
'type' => 'text',
'description' => sprintf( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', $this->subject ),
'placeholder' => '',
'default' => ''
),
'heading' => array(
'title' => 'Email Heading',
'type' => 'text',
'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.' ), $this->heading ),
'placeholder' => '',
'default' => ''
),
'email_type' => array(
'title' => 'Email type',
'type' => 'select',
'description' => 'Choose which format of email to send.',
'default' => 'html',
'class' => 'email_type',
'options' => array(
'plain' => __( 'Plain text', 'woocommerce' ),
'html' => __( 'HTML', 'woocommerce' ),
'multipart' => __( 'Multipart', 'woocommerce' ),
)
)
);
}
} // end \WC_Dealer_Invoice_Email class
I think you just need to add a code to your function.php
add_filter('woocommerce_cart_needs_payment', '__return_false');
to allow users to send their orders without proceeding with payment. The email notification you can setup from woocommerce settings.

Categories