I have a WC payment gateway which was build and working until WP version 4.1. Today I started testing it on WP 4.9.8 and WC 3.5.1.
When I try to complete purchase the payment gateway is not taking me to the payment screen to fill credit card details. It get stuck on redirection state.
Hope someone can help me out to solve this.
Below the image reference and the code I am using:
<?php
/**
* Plugin Name: CustomPaymentGateway
*/
add_action('plugins_loaded', 'init_mpay', 0);
function init_mpay() {
if ( ! class_exists( 'WC_Payment_Gateway' ) ) return;
class woocommerce_mpay extends WC_Payment_Gateway {
public function __construct() {
global $woocommerce;
$this->id = 'mpay';
$this->method_title = __('MPay', 'mpay-chearaan-woo');
$this->icon = plugins_url( 'mpay.png', __FILE__ );
$this->has_fields = false;
$this->notify_url = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'woocommerce_mpay', home_url( '/' ) ) );
// Load the form fields.
$this->init_form_fields();
// Load the settings.
$this->init_settings();
// Define user set variables
$this->mpayurl = $this->settings['mpayurl'];
$this->title = $this->settings['title'];
$this->description = $this->settings['description'];
$this->merchantid = $this->settings['merchantid'];
$this->hashKey = $this->settings['hashKey'];
$this->transactionDate = date('Y-m-d H:i:s O');
$this->woo_version = $this->get_woo_version();
// Actions
add_action('init', array(&$this, 'successful_request'));
add_action('woocommerce_api_woocommerce_mpay', array( &$this, 'successful_request' ));
add_action('woocommerce_receipt_mpay', array(&$this, 'receipt_page'));
if ( version_compare( WOOCOMMERCE_VERSION, '2.0.0', '>=' ) ) {
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array( &$this, 'process_admin_options' ));
} else {
add_action('woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ));
}
}
/**
* Initialise Gateway Settings Form Fields
*/
function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable:', 'mpay-chearaan-woo' ),
'type' => 'checkbox',
'label' => __( 'Enable MPay', 'mpay-chearaan-woo' ),
'default' => 'yes'
),
'mpayurl' => array(
'title' => __( 'UAT/Production:', 'mpay-chearaan-woo' ),
'type' => 'checkbox',
'label' => __( 'UAT', 'mpay-chearaan-woo' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title:', 'mpay-chearaan-woo' ),
'type' => 'text',
'description' => __( 'The title which the user sees during checkout.', 'mpay-chearaan-woo' ),
'default' => __( 'MPay Online Payment Gateway', 'mpay-chearaan-woo' )
),
'description' => array(
'title' => __( 'Description:', 'mpay-chearaan-woo' ),
'type' => 'textarea',
'description' => __( 'Description which the user sees during checkout.', 'mpay-chearaan-woo' ),
'default' => __('Pay securely through MPay\'s Secure Servers.', 'mpay-chearaan-woo')
),
'merchantid' => array(
'title' => __( 'Merchant ID:', 'mpay-chearaan-woo' ),
'type' => 'text',
'description' => __( 'Please enter your Merchant ID as provided by MPay.', 'mpay-chearaan-woo' ),
'default' => ''
),
'hashKey' => array(
'title' => __( 'Merchant hashKey:', 'mpay-chearaan-woo' ),
'type' => 'text',
'description' => __( 'Please enter your Merchant hashKey as provided by MPay.', 'mpay-chearaan-woo' ),
'default' => ''
)
);
}
public function admin_options() {
?>
<h3>MPay</h3>
<p><?php _e('MPay works by sending the user to MPay to enter their payment information.', 'mpay-chearaan-woo'); ?></p>
<table class="form-table">
<?php
// Generate the HTML For the settings form.
$this->generate_settings_html();
?>
</table><!--/.form-table-->
<?php
} // End admin_options()
/**
* There are no payment fields, but we want to show the description if set.
**/
function payment_fields() {
if ($this->description) echo wpautop(wptexturize($this->description));
}
/**
* Generate the button link
**/
public function generate_mpay_form( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
if ($this->mpayurl == "yes"){
$mpay_adr = "https://pcimdex.mpay.my/mdex2/payment/eCommerce";
}else{
$mpay_adr = "https://www.mdex.my/mdex/payment/eCommerce";
}
$sHash = strtoupper(hash('sha256', $this->hashKey."Continue".str_pad($this->merchantid, 10, '0', STR_PAD_LEFT).str_pad($order->id, 20, '0', STR_PAD_LEFT).str_pad(($order->order_total*100), 12, '0', STR_PAD_LEFT)));
$mpay_args = array(
'secureHash' => $sHash,
'mid' => str_pad($this->merchantid, 10, '0', STR_PAD_LEFT),
'invno' => str_pad($order->id, 20, '0', STR_PAD_LEFT),
'amt' => str_pad(($order->order_total*100), 12, '0', STR_PAD_LEFT),
'desc' => str_pad("Order No ".$order_id, 255, ' ', STR_PAD_RIGHT),
'postURL' => $this->notify_url,
'phone' => $order->billing_phone,
'email' => $order->billing_email,
'param' => 'WC|V1'
);
$mpay_args_array = array();
foreach ($mpay_args as $key => $value) {
$mpay_args_array[] = '<input type="hidden" name="'.$key.'" value="'. $value .'" /><br>';
}
wc_enqueue_js('
jQuery(function(){
jQuery("body").block(
{
message: "<img src=\"'.$woocommerce->plugin_url().'/images/uploading.gif\" alt=\"Redirecting…\" style=\"float:left; margin-right: 10px;\" />'.__('Thank you for your order. We are now redirecting you to MPay to make payment.', 'mpay-chearaan-woo').'",
overlayCSS:
{
background: "#fff",
opacity: 0.5
},
css: {
padding: 18,
textAlign: "center",
color: "#555",
border: "2px solid #aaa",
backgroundColor:"#fff",
cursor: "wait",
lineHeight: "30px"
}
});
jQuery("#submit_mpay_payment_form").click();
});
');
return '<form action="'.$mpay_adr.'" method="post">
' . implode('', $mpay_args_array) . '
<input type="submit" class="button-alt" id="submit_mpay_payment_form" value="'.__('Pay via MPay', 'mpay-chearaan-woo').'" /> <a class="button cancel" href="'.$order->get_cancel_order_url().'">'.__('Cancel order & restore cart', 'mpay-chearaan-woo').'</a>
</form>';
}
/**
* Process the payment and return the result
**/
function process_payment( $order_id ) {
$order = new WC_Order( $order_id );
if($this->woo_version >= 2.1){
$redirect = $order->get_checkout_payment_url( true );
}else if( $this->woo_version < 2.1 ){
$redirect = add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(get_option('woocommerce_pay_page_id'))));
}else{
$redirect = add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(get_option('woocommerce_pay_page_id'))));
}
return array(
'result' => 'success',
'redirect' => $redirect
);
}
/**
* receipt_page
**/
function receipt_page( $order ) {
echo '<p>'.__('Please click the button below to pay with MPay.', 'mpay-chearaan-woo').'</p>';
echo $this->generate_mpay_form( $order );
}
/**
* Server callback was valid, process callback (update order as passed/failed etc).
**/
function successful_request($mpay_response) {
global $woocommerce;
if (isset($_GET['wc-api']) && $_GET['wc-api'] == 'woocommerce_mpay') {
/** need to trim from result **/
$Url_result = $_GET['result'];
$order = new WC_Order( (int) substr($Url_result,7,20) );
$tranID = (int)substr($Url_result,1,6);
if (substr($Url_result,0,1) == '0'){
$r_status = 0;
}else{
$r_status = 33;
}
/*
$order = new WC_Order( (int) $_POST['invno'] );
$r_status = (int) $_POST['result'];
*/
if ($r_status == '0' ){
$order->payment_complete();
$order->add_order_note('MPay Payment was SUCCESSFUL '.'<br>AuthCode is ' . $tranID);
wp_redirect( $this->get_return_url($order) ); exit;
//wp_redirect( $this->order->get_checkout_order_received_url() ); exit;
}else{
$order->update_status('failed', sprintf(__('MPay Payment Failed. Error Communicating with Bank.', 'mpay-chearaan-woo') ) );
wp_redirect($order->get_cancel_order_url()); exit;
}
}
}
function get_woo_version() {
// If get_plugins() isn't available, require it
if ( ! function_exists( 'get_plugins' ) )
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
// Create the plugins folder and file variables
$plugin_folder = get_plugins( '/woocommerce' );
$plugin_file = 'woocommerce.php';
// If the plugin version number is set, return it
if ( isset( $plugin_folder[$plugin_file]['Version'] ) ) {
return $plugin_folder[$plugin_file]['Version'];
} else {
// Otherwise return null
return NULL;
}
}
}
}
/**
* Add the gateway to WooCommerce
**/
function add_mpay( $methods ) {
$methods[] = 'woocommerce_mpay'; return $methods;
}
add_filter('woocommerce_payment_gateways', 'add_mpay' );
Related
I am using a plugin that is creating a custom payment type where the user can fill in a custom payment ID. The thing is, I want that custom payment ID stored in an ACF field as post meta on the WooCommerce order edit page. I have created an ACF field named 'kkpayment' for this task. I figured the rest should be done using update_field($selector, $value, [$post_id]);. I have created a PHP function for this task. However, my code doesn't seem to work. Am I missing something obvious?
My function for updating the ACF field:
add_action( 'woocommerce_checkout_update_order_meta', 'custom_payment_update_order_meta_acf' );
function custom_payment_update_order_meta_acf( $order_id ) {
$transaction = get_post_meta( $order->id, 'transaction', true );
if($_POST['payment_method'] = 'custom')
return $transaction;
update_field('kkpayment', $transaction, $order_id);
}
The custom payment is made with this code:
<?php
/*
Plugin Name: KK Payment Gateway
Description: Modtag betaling med kontostreng
Author: Arvin Aliari & Tobias Hyrup
Author URI: https://aliari.dk
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Baseret på StackOverlow: https://stackoverflow.com/questions/17081483/custom-payment-method-in-woocommerce
*
* Tilpasninger til dette projekt, se linje 135 - 161
*
*
*
* Custom Payment Gateway.
*
* Provides a Custom Payment Gateway.
*/
add_action('plugins_loaded', 'init_custom_gateway_class');
function init_custom_gateway_class(){
class WC_Gateway_Custom extends WC_Payment_Gateway {
public $domain;
/**
* Constructor for the gateway.e Number
*/
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 = __( 'Prisme', $this->domain );
$this->method_description = __( 'Tag i mod betaling fra Prisme.', $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_' . $this->id, 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' => __( 'Aktiver/Deaktiver', $this->domain ),
'type' => 'checkbox',
'label' => __( 'Tillad betaling med kontostreng', $this->domain ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Titel', $this->domain ),
'type' => 'text',
'description' => __( 'Angiver den titel som brugeren ser under checkout.', $this->domain ),
'default' => __( 'Betaling med kontostreng', $this->domain ),
'desc_tip' => true,
),
'order_status' => array(
'title' => __( 'Ordrestatus', $this->domain ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'description' => __( 'Vælg hvilken status du ønsker efter chekout.', $this->domain ),
'default' => 'wc-completed',
'desc_tip' => true,
'options' => wc_get_order_statuses()
),
'description' => array(
'title' => __( 'Beskrivelse', $this->domain ),
'type' => 'textarea',
'description' => __( 'Beskrivelse af betalingsmetoden som brugerene ser under chekout.', $this->domain ),
'default' => __('Payment Information', $this->domain),
'desc_tip' => true,
),
'instructions' => array(
'title' => __( 'Instruktioner', $this->domain ),
'type' => 'textarea',
'description' => __( 'Besked som brugerene vil se på efter gennemført ordre.', $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 email_instructions( $order, $sent_to_admin, $plain_text = false ) {
if ( $this->instructions && ! $sent_to_admin && 'custom' === $order->payment_method && $order->has_status( 'on-hold' ) ) {
echo wpautop( wptexturize( $this->instructions ) ) . PHP_EOL;
}
}
public function payment_fields(){
if ( $description = $this->get_description() ) {
echo wpautop( wptexturize( $description ) );
}
?>
<div id="custom_input">
<p class="form-row form-row-wide">
<label for="transaction" class=""><?php _e('26-cifret kontostreng:', $this->domain); ?></label>
<input type="text" class="" name="transaction" id="transaction" placeholder="12345-1234-123-123456789-123-12" value="" style="width: 225px;">
</p>
<p style="opacity: 0.75; margin-top:-10px; font-size: 13.5px;">Eks: 12345-1234-123-123456789-123-12</p>
<p>Hvis du ikke har en kontostreng, så kontakt din nærmeste leder eller økonomimedarbejder.</p>
</div>
<?php
}
public function validate_fields(){
$paymentString = $_POST['transaction'];
$strLength = strlen($paymentString);
/*$stringContains = preg_match("/^\d{5}[-]\d{4}[-]\d{3}[-]\d{7}[-]\d{3}[-]\d{2}$/", $paymentString);*/
$stringContains = preg_match("/^\d{5}[-]\d{4}[-]\d{3}[-]\d{9}[-]\d{3}[-]\d{2}$/", $paymentString);
if($stringContains && !empty($_POST['transaction']) && $_POST['transaction'] != "") {
return true;
} else {
$stringOldPattern = preg_match("/^\d{5}[-]\d{4}[-]\d{3}[-]\d{7}[-]\d{3}[-]\d{2}$/", $paymentString);
if($stringOldPattern){
wc_add_notice( "Ugyldig kontostreng - Husk at bruge det nye format på 26 cifre der inkluderer funktionskode. Tjek at du har indtastet kontostrengen korrekt. Eksempel: 12345-1234-123-123456789-123-12", 'error' );
} else {
wc_add_notice( "Ugyldig kontostreng - Tjek at du har indtastet kontostrengen korrekt. Eksempel: 12345-1234-123-123456789-123-12", 'error' );
}
return false;
}
}
/**
* 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 );
$status = 'wc-' === substr( $this->order_status, 0, 3 ) ? substr( $this->order_status, 3 ) : $this->order_status;
// Set order status
$order->update_status( $status, __( 'Checkout with custom payment. ', $this->domain ) );
// 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 )
);
}
}
}
add_filter( 'woocommerce_payment_gateways', 'add_custom_gateway_class' );
function add_custom_gateway_class( $methods ) {
$methods[] = 'WC_Gateway_Custom';
return $methods;
}
add_action('woocommerce_checkout_process', 'process_custom_payment');
function process_custom_payment(){
if($_POST['payment_method'] != 'custom')
return;
if( !isset($_POST['transaction']) || empty($_POST['transaction']) )
//wc_add_notice( __( 'Angiv venligst dit 26-cifret kontostreng til Prisme', $this->domain ), 'error' );
wc_add_notice( __( 'Angiv venligst dit 26-cifret kontostreng til Prisme', ), 'error' );
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'custom_payment_update_order_meta' );
function custom_payment_update_order_meta( $order_id ) {
if($_POST['payment_method'] != 'custom')
return;
// echo "<pre>";
// print_r($_POST);
// echo "</pre>";
// exit();
update_post_meta( $order_id, 'transaction', $_POST['transaction'] );
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
function custom_checkout_field_display_admin_order_meta($order){
$method = get_post_meta( $order->id, '_payment_method', true );
if($method != 'custom')
return;
$transaction = get_post_meta( $order->id, 'transaction', true );
echo '<p><strong>'.__( '26 cifret kontostreng').':</strong> ' . $transaction . '</p>';
}
/**
* Add payment to metadata
*/
add_action( 'woocommerce_checkout_update_order_meta', 'custom_payment_update_order_meta_acf' );
function custom_payment_update_order_meta_acf( $order_id ) {
$transaction = get_post_meta( $order->id, 'transaction', true );
if($_POST['payment_method'] = 'custom')
return $transaction;
update_field('kkpayment', $transaction, $order_id);
}
Use this code to update acf field on successful transaction.
add_action( 'woocommerce_thankyou', 'bks_post_transaction_after_order_completion', 10, 1 );
function bks_post_transaction_after_order_completion( $order_id ) {
$order = wc_get_order( $order_id ); // phpcs:ignore.
$status = $order->get_status();
// Try to post only when order status is completed or processing.
if ( ! ( 'completed' === $status || 'processing' === $status ) ) {
return;
}
// get transaction.
$transaction = get_post_meta( $order->id, 'transaction', true );
update_field('kkpayment', $transaction, $order_id);
$order->update_meta_data( 'kkpayment', $transaction ); // phpcs:ignore
$order->save();
}
I have a custom gateway, I am new to the custom plugins for woocommerce, now my problem I have is that I am able to redirect to my payment gateway but in my payment gateway (HTML) how do I redirect back after payment was made? I don't understand the whole process as yet, I know once payment is selected then I can redirect to my custom payment gateway but the confusing part is returning from payment gateway to woocommerce to say it was a success or not
<?php
/**
* Plugin Name: Woocommerce CloudCart Payment Gateway
* Plugin URI: http://cloudcart.online
* Description: Payment Gateway to use CloudCart points.
* Author: Cornelis Kuijpers
* Author URI: http://kuijpersconsulting.co.za
* Version: 1.0.1
*
*/
add_action('plugins_loaded', 'init_Cloudcart', 0);
function init_Cloudcart() {
if ( ! class_exists( 'WC_Payment_Gateway' ) ) return;
class woocommerce_Cloudcart extends WC_Payment_Gateway {
public function __construct() {
global $woocommerce;
$this->id = 'Cloudcart';
$this->method_title = __('Cloudcart', 'Cloudcart-chearaan-woo');
$this->icon = plugins_url( 'Cloudcart.png', __FILE__ );
$this->has_fields = false;
$this->notify_url = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'woocommerce_Cloudcart', home_url( '/' ) ) );
// Load the form fields.
$this->init_form_fields();
// Load the settings.
$this->init_settings();
// Define user set variables
$this->Cloudcarturl = $this->settings['Cloudcarturl'];
$this->title = $this->settings['title'];
$this->description = $this->settings['description'];
$this->merchantid = $this->settings['merchantid'];
$this->hashKey = $this->settings['hashKey'];
$this->transactionDate = date('Y-m-d H:i:s O');
$this->woo_version = $this->get_woo_version();
// Actions
add_action('init', array(&$this, 'successful_request'));
add_action('woocommerce_api_woocommerce_Cloudcart', array( &$this, 'successful_request' ));
add_action('woocommerce_receipt_Cloudcart', array(&$this, 'receipt_page'));
if ( version_compare( WOOCOMMERCE_VERSION, '2.0.0', '>=' ) ) {
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array( &$this, 'process_admin_options' ));
} else {
add_action('woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ));
}
}
/**
* Initialise Gateway Settings Form Fields
*/
function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable:', 'Cloudcart-chearaan-woo' ),
'type' => 'checkbox',
'label' => __( 'Enable Cloudcart', 'Cloudcart-chearaan-woo' ),
'default' => 'yes'
),
'Cloudcarturl' => array(
'title' => __( 'Test/Production:', 'Cloudcart-chearaan-woo' ),
'type' => 'checkbox',
'label' => __( 'Test', 'Cloudcart-chearaan-woo' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title:', 'Cloudcart-chearaan-woo' ),
'type' => 'text',
'description' => __( 'The title which the user sees during checkout.', 'Cloudcart-chearaan-woo' ),
'default' => __( 'Cloudcart Online Payment Gateway', 'Cloudcart-chearaan-woo' )
),
'description' => array(
'title' => __( 'Description:', 'Cloudcart-chearaan-woo' ),
'type' => 'textarea',
'description' => __( 'Description which the user sees during checkout.', 'Cloudcart-chearaan-woo' ),
'default' => __('Pay securely through Cloudcart\'s Secure Servers.', 'Cloudcart-chearaan-woo')
),
'merchantid' => array(
'title' => __( 'Merchant ID:', 'Cloudcart-chearaan-woo' ),
'type' => 'text',
'description' => __( 'Please enter your Merchant ID as provided by Cloudcart.', 'Cloudcart-chearaan-woo' ),
'default' => ''
),
'hashKey' => array(
'title' => __( 'Merchant hashKey:', 'Cloudcart-chearaan-woo' ),
'type' => 'text',
'description' => __( 'Please enter your Merchant hashKey as provided by Cloudcart.', 'Cloudcart-chearaan-woo' ),
'default' => ''
)
);
}
public function admin_options() {
?>
<h3>Cloudcart</h3>
<p><?php _e('Cloudcart works by sending the user to Cloudcart to enter their payment information.', 'Cloudcart-chearaan-woo'); ?></p>
<table class="form-table">
<?php
// Generate the HTML For the settings form.
$this->generate_settings_html();
?>
</table><!--/.form-table-->
<?php
} // End admin_options()
/**
* There are no payment fields, but we want to show the description if set.
**/
function payment_fields() {
if ($this->description) echo wpautop(wptexturize($this->description));
}
/**
* Generate the button link
**/
public function generate_Cloudcart_form( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
if ($this->Cloudcarturl == "yes"){
$Cloudcart_adr = "https://ckconsulting.ddns.net/API/CloudCart/";
}else{
$Cloudcart_adr = "https://ckconsulting.ddns.net/API/CloudCart/";
}
$sHash = strtoupper(hash('sha256', $this->hashKey."Continue".str_pad($this->merchantid, 10, '0', STR_PAD_LEFT).str_pad($order->id, 20, '0', STR_PAD_LEFT).str_pad(($order->order_total*100), 12, '0', STR_PAD_LEFT)));
$Cloudcart_args = array(
'secureHash' => $sHash,
'mid' => str_pad($this->merchantid, 10, '0', STR_PAD_LEFT),
'invno' => str_pad($order->id, 20, '0', STR_PAD_LEFT),
'amt' => str_pad(($order->order_total*100), 12, '0', STR_PAD_LEFT),
'desc' => str_pad("Order No ".$order_id, 255, ' ', STR_PAD_RIGHT),
'postURL' => $this->notify_url,
'phone' => $order->billing_phone,
'email' => $order->billing_email,
'param' => 'WC|V1'
);
$Cloudcart_args_array = array();
foreach ($Cloudcart_args as $key => $value) {
$Cloudcart_args_array[] = '<input type="hidden" name="'.$key.'" value="'. $value .'" /><br>';
}
wc_enqueue_js('
jQuery(function(){
jQuery("body").block(
{
message: "<img src=\"'.$woocommerce->plugin_url().'/images/uploading.gif\" alt=\"Redirecting…\" style=\"float:left; margin-right: 10px;\" />'.__('Thank you for your order. We are now redirecting you to Cloudcart to make payment.', 'Cloudcart-chearaan-woo').'",
overlayCSS:
{
background: "#fff",
opacity: 0.5
},
css: {
padding: 18,
textAlign: "center",
color: "#555",
border: "2px solid #aaa",
backgroundColor:"#fff",
cursor: "wait",
lineHeight: "30px"
}
});
jQuery("#submit_Cloudcart_payment_form").click();
});
');
return '<form action="'.$Cloudcart_adr.'" method="post">
' . implode('', $Cloudcart_args_array) . '
<input type="submit" class="button-alt" id="submit_Cloudcart_payment_form" value="'.__('Pay via Cloudcart', 'Cloudcart-chearaan-woo').'" /> <a class="button cancel" href="'.$order->get_cancel_order_url().'">'.__('Cancel order & restore cart', 'Cloudcart-chearaan-woo').'</a>
</form>';
}
/**
* Process the payment and return the result
**/
function process_payment( $order_id ) {
$order = new WC_Order( $order_id );
echo get_permalink(get_option('woocommerce_pay_page_id'));
if($this->woo_version >= 2.1){
$redirect = $order->get_checkout_payment_url( true );
}else if( $this->woo_version < 2.1 ){
$redirect = add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(get_option('woocommerce_pay_page_id'))));
}else{
$redirect = add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(get_option('woocommerce_pay_page_id'))));
}
return array(
'result' => 'success',
'redirect' => $redirect
);
}
/**
* receipt_page
**/
function receipt_page( $order ) {
echo '<p>'.__('Please click the button below to pay with Cloudcart.', 'Cloudcart-chearaan-woo').'</p>';
echo $this->generate_Cloudcart_form( $order );
}
/**
* Server callback was valid, process callback (update order as passed/failed etc).
**/
function successful_request($Cloudcart_response) {
global $woocommerce;
echo 'Hello from the other side';
if (isset($_GET['wc-api']) && $_GET['wc-api'] == 'woocommerce_Cloudcart') {
/** need to trim from result **/
$Url_result = $_GET['result'];
$order = new WC_Order( (int) substr($Url_result,7,20) );
$tranID = (int)substr($Url_result,1,6);
if (substr($Url_result,0,1) == '0'){
$r_status = 0;
}else{
$r_status = 33;
}
/*
$order = new WC_Order( (int) $_POST['invno'] );
$r_status = (int) $_POST['result'];
*/
if ($r_status == '0' ){
$order->payment_complete();
$order->add_order_note('Cloudcart Payment was SUCCESSFUL '.'<br>AuthCode is ' . $tranID);
wp_redirect( $this->get_return_url($order) ); exit;
//wp_redirect( $this->order->get_checkout_order_received_url() ); exit;
}else{
$order->update_status('failed', sprintf(__('Cloudcart Payment Failed. Error Communicating with Bank.', 'Cloudcart-chearaan-woo') ) );
wp_redirect($order->get_cancel_order_url()); exit;
}
}
}
function get_woo_version() {
// If get_plugins() isn't available, require it
if ( ! function_exists( 'get_plugins' ) )
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
// Create the plugins folder and file variables
$plugin_folder = get_plugins( '/woocommerce' );
$plugin_file = 'woocommerce.php';
// If the plugin version number is set, return it
if ( isset( $plugin_folder[$plugin_file]['Version'] ) ) {
return $plugin_folder[$plugin_file]['Version'];
} else {
// Otherwise return null
return NULL;
}
}
}
}
/**
* Add the gateway to WooCommerce
**/
function add_Cloudcart( $methods ) {
$methods[] = 'woocommerce_Cloudcart'; return $methods;
}
add_filter('woocommerce_payment_gateways', 'add_Cloudcart' );
Using Woocommerce, I want to force a shipping method when a certain valid coupon is applied at the cart/checkout phase.
Below my code. It extends WC_Shipping_Method, gets the whole woocommerce coupon list, let admin to select one or more, save them and then, when a costumer applies one of those chosen coupons checking out, forces to use only one this shipping method.
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
/* Custom LocalPickup Class */
class WC_Shipping_LocalPickUp_On_Coupon extends WC_Shipping_Method {
public $requires = '';
public function __construct( $instance_id = 0 ) {
$this->id = 'localpickup_on_coupon';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Pickup with Coupon', 'Valeo' );
$this->method_description = __( 'Pickup with Coupon', 'Valeo' );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
/*Getting Coupon List */
$args = array(
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
);
$coupons = get_posts( $args );
$this->list = [];
foreach($coupons as $item){
$this->list[$item->post_name] = $item->post_title;
}
$this->init();
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
public function init() {
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
$this->requires = $this->get_option( 'requires' );
}
public function init_form_fields() {
$this->instance_form_fields = array(
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => $this->method_title,
'desc_tip' => true,
),
'requires' => array(
'title' => __( 'Il ritiro in sede richiede...', 'Valeo' ),
'type' => 'multiselect',
'class' => 'valeo_multiselect',
'default' => '',
'options' => $this->list
),
);
}
public function is_available( $package ) {
$has_coupon = false;
$coupons = WC()->cart->get_coupons();
if(!empty($coupons)) {
$couponKey = array_keys($coupons)[0];
if ( in_array( $couponKey, $this->requires ) ) {
if ( $coupons ) {
foreach ( $coupons as $code => $coupon ) {
if ( $coupon->is_valid() ) {
$has_coupon = true;
break;
}
}
}
}
}
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $has_coupon, $package, $this );
}
public function calculate_shipping( $package = array() ) {
$rate = array(
'id' => $this->get_rate_id(),
'label' => $this->title,
'cost' => 0,
'taxes' => 0,
'package' => $package,
);
$this->add_rate($rate);
do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate );
}
}
add_filter( 'woocommerce_shipping_methods', 'register_devso_method' );
function register_devso_method( $methods ) {
$methods[ 'localpickup_on_coupon' ] = 'WC_Shipping_LocalPickUp_On_Coupon';
return $methods;
}
}
Here the filter that checks if customer has inserted the chosen coupon/s and (in a "bad" way) removes all woocommerce package rates but the one I declared in the class.
function filter_woocommerce_package_rates( $array ) {
$check = FALSE;
foreach($array as $index => $value){
if(strpos($index, 'localpickup_on_coupon') !== false) { $check = TRUE; }
}
if($check){
foreach($array as $index => $value){
if(!(strpos($index, 'localpickup_on_coupon') !== false)) { unset($array[$index]); }
}
}
return $array;
};
// add the filter
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 1 );
Is there a better way to do this?
Hi there, I'm trying to build a very simple plugin for woocommerce to show some information about delivery without taxes. The diference for the other methods is the extra HTML field.
I read a lot of the documentation but I think there is something miss on the configuration. The admin it seems working. But the method didn't appear on checkout screen. The code is below:
<?php
if ( ! defined( 'WPINC' ) ) {
die('security by preventing any direct access to your plugin file');
}
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
function shipping_delivery_info() {
if (!class_exists('shipping_delivery_info')) {
class shipping_delivery_info extends WC_Shipping_Method {
public function __construct( $instance_id = 0) {
$this->id = 'shipping_delivery_info';
$this->instance_id = absint( $instance_id );
$this->method_title = __('Shipping Delivery Info', 'shipping_delivery_info');
$this->method_description = __('A Woocommerce custom shipping method plugin, that shows ' .
'some shipping information to costumer, like free shipping but with HTML field.',
'shipping_delivery_info');
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
/**
* Load the settings API
*/
function init() {
// Load the settings
$this->init_form_fields();
$this->init_settings();
$this->enabled = $this->get_option( 'enabled' );
$this->title = $this->get_option( 'title' );
$this->info = $this->get_option( 'info' );
add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
}
function init_form_fields() {
$this->instance_form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'shipping_delivery_info'),
'type' => 'checkbox',
'label' => __( 'Enable this shipping method', 'shipping_delivery_info'),
'default' => 'yes',
),
'title' => array(
'title' => __('Title', 'shipping_delivery_info'),
'type' => 'text',
'description' => __( 'The title to be displayed during checkout.', 'shipping_delivery_info' ),
'default' => __('Shipping Information', 'shipping_delivery_info'),
),
'info' => array(
'title' => __('Information', 'shipping_delivery_info'),
'type' => 'text',
'description' => __( 'Information about delivery and its taxes.', 'shipping_delivery_info' ),
'default' => __('Insert here some HTML.'),
),
);
}
}
}
}
add_action('woocommerce_shipping_init', 'shipping_delivery_info');
function add_shipping_delivery_info($methods)
{
$methods['shipping_delivery_info'] = 'shipping_delivery_info';
return $methods;
}
add_filter('woocommerce_shipping_methods', 'add_shipping_delivery_info');
function shipping_delivery_info_message($posted)
{
$packages = WC()->shipping->get_packages();
$chosen_methods = WC()->session->get('chosen_shipping_methods');
if (is_array($chosen_methods) && in_array('shipping_delivery_info', $chosen_methods)) {
foreach ($packages as $i => $package) {
if ($chosen_methods[$i] != "shipping_delivery_info") {
continue;
}
$shipping_delivery_info = new shipping_delivery_info();
$message = $shipping_delivery_info->settings['info'];
return $message;
/*$messageType = "info";
wc_add_notice($message, $messageType);*/
}
}
}
add_action('woocommerce_review_order_before_cart_contents', 'shipping_delivery_info_message', 10);
add_action('woocommerce_after_checkout_validation', 'shipping_delivery_info_message', 10);
}
You need to add the calculate_shipping function to your class
/**
* function calculate_shipping.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package = array() ) {
$rate = array(
'id' => 'My Method id',
'label' => 'New method',
'cost' => 0,
'calc_tax' => 'per_item'
);
$this->add_rate( $rate );
}
}
Anyway, i think you don't need to add a new shipping method just to show some info at the cart, instead you can use these actions:
add_action( 'woocommerce_review_order_before_submit', 'add_tracking_notification', 12 );
add_action('woocommerce_proceed_to_checkout', 'add_tracking_notification');
function add_tracking_notification() {
echo '<h5 style="margin-bottom:10px">This is a custom message</h5>';
}
I'm working on a custom payment gateway for the WordPress plugin WooCommerce. I cannot seem to save the settings for the payment gateway. When I enter information into the fields and then click save, the page refreshes with all of the fields blank. What am I doing wrong?
Here is my code.
<?php
/**
* Plugin Name: Bitcoin WooCommerce Integration Made Easy
* Description: A Bitcoin processing plugin that integrates into WooCommerce made specifically for Bitcoin Publish.
* Version: 0.01
* Author: Cammy_the_block
*/
add_action( 'plugins_loaded', 'init_your_gateway_class' );
function init_your_gateway_class() {
class WC_Gateway_Your_Gateway extends WC_Payment_Gateway {
function __construct() {
$this->id = "Bitcoin WooCommerce Integration Gateway";
$this->method_title = "Bitcoin with BWCIME";
$this->method_description = "More later";
$this->init_form_fields();
$this->init_settings();
if ( version_compare( WOOCOMMERCE_VERSION, '2.0.0', '>=' ) ) {
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( &$this, 'process_admin_options' ) );
}
else {
add_action( 'woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ) );
}
}
function init_form_fields(){
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable Cheque Payment', 'woocommerce' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'Cheque Payment', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Customer Message', 'woocommerce' ),
'type' => 'textarea',
'default' => ''
)
);
}
}
function process_payment( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
$productArray = array();
$x = 0;
foreach( $order->get_items() as $item_id => $item ) {
$productArray[x] = $order->get_product_from_item( $item );
$x++;
}
// Mark as on-hold (we're awaiting the cheque)
$order->update_status('on-hold',
__( 'Awaiting cheque payment. there are ' + $productArray.length + 'items', 'woocommerce' )
);
// Remove cart
$woocommerce->cart->empty_cart();
// Return thankyou redirect
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
}
function add_your_gateway_class ($methods ) {
$methods[] = 'WC_Gateway_Your_Gateway';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_your_gateway_class' );
?>
EDIT:
The add filter code runs add_your_gateway_class, which in turn causes it to run WC_Gateway_Your_Gateway.
you have to call them on the constructor after the init_settings();
$this->init_settings();
// Define user set variables
$this->access_key = $this->get_option( 'access_key' );
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
edit:
you also need another action/hook, just at the end of the constructor, no need to create that new function that you came up with:
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
edit 2:
sorry you already have it, my bad :p, dont realy know what happened there, glad its solved
The actual problem is your this->id="example_gateway": id is always case sensitive and it should be without space and lowercase.
Example:
function __construct() {
$this->id = "bitcoin_woocommerce_integration_gateway";
$this->method_title =( "Bitcoin with BWCIME", 'bitcoin_woocommerce_integration_gateway' );
$this->title = __( "Bitcoin with BWCIME", 'bitcoin_woocommerce_integration_gateway' );
$this->method_description = "More later";
//further as same as your code.....
}
I'm not completely sure how I fixed it, but I believe it had to do with adding the function admin_options().
public function admin_options() {
?>
<h3><?php _e('Bitcoin Payment', 'woothemes'); ?></h3>
<p><?php _e('Message!.', 'woothemes'); ?></p>
<table class="form-table">
<?php
// Generate the HTML For the settings form.
$this->generate_settings_html();
?>
</table>
<?php
}
EDIT: I'm not sure what causes it but you have to clear the plugin's settings by interfacing with the database. The easy way to do this is to change the ID of the plugin. I'm not actually sure where the settings are stored in the database.