How to get the payment response url in woocommerce? - php

I have integrated pay4later api in my wordpress. I need to show the payment response details after payment success.
My Plugin file:
class WC_Pay4later extends WC_Payment_Gateway{
add_action('woocommerce_api_' . strtolower( get_class( $this ) ), array($this, 'check_response' ) );
function check_response()
{
/* Update Process*/
}
}
I set My return response url is:
www.mysite/pay4later/?wc-api=WC_Payment_GatewayPay4later_check_response.
When I call this it just displays 1.
How can I Fix this?

Here is the skeleton structure of the Pay4later payment gateway for woocommerce.
if ( ! defined( 'ABSPATH' ) ) { exit; }
add_action( 'plugins_loaded', 'wc_pay4later_init', 0 );
function wc_pay4later_init() {
class WCPay4later extends WC_Payment_Gateway{
public function __construct() {
// Put your initialization scripts here
// Which would be initializing merchan account info, secret keys, from this plugin's settings screen
/* This would be your gateway return url */
$this->callback = str_replace( 'https:', 'http:', home_url( '/wc-api/WCPay4later' ) );
/* This action will redirect the gateway response to your 'check_pay_4_later_response' function */
add_action( 'woocommerce_api_wcpay4later', array( $this, 'check_pay_4_later_response' ) );
/* This is the action where you prepare your digital form and submit to the gateway server */
add_action('woocommerce_receipt_wcpay4later', array( $this, 'receipt_page') );
}
function receipt_page( $order ) {
echo '<p>'.__('Thank you for your order, please click the button below to pay with Pay 4 Later Gateway Service.', 'sark').'</p>';
// prepare your digital form
echo $this -> generate_digital_form( $order );
}
function generate_digital_form( $order ) {
// prepare and redirect to gateway server
}
function check_pay_4_later_response() {
/* Update Process*/
}
}
function woocommerce_add_pay_4_later_gateway( $methods ) {
$methods[] = 'WCPay4later';
return $methods;
}
add_filter('woocommerce_payment_gateways', 'woocommerce_add_pay_4_later_gateway' );
}

Related

trigger function in custom class on WooCommerce action

I am using the following class to have a directory created with dynamic value - based on a woo custom checkout field. Works perfect on page refresh and directory is created like expected.
just need this to only trigger/instantiate on the WooCommerce actions
woocommerce_order_status_completed
or
woocommerce_order_status_changed
or
woocommerce_thankyou_page
how can this be done so that it does not always run every time a page is loaded to decrease the load and have better efficiency in general.
here is the complete class
//add_action( 'plugins_loaded', array( 'pos__URL', 'init' )); //uncomment to trigger on page refresh
class pos__URL {
public static function init() {
$POS__sys_URL = __CLASS__;
new $POS__sys_URL;
}
public function __construct()
{
add_action('init', array($this, 'pos__URL_Field'));
}
public function pos__URL_Field()
{
//--------to access the value----start-----
$orders = wc_get_orders(array(
'customer_id' => get_current_user_id(),
'return' => 'ids',
));
//add the id of the custom meta field that lies in the order
$meta_data = array();
foreach ($orders as $order_id) {
$meta_data[$order_id] = get_post_meta($order_id, '_engx_text_field_id', true);
}
//--------to access the value----end-----
if( isset($meta_data[$order_id]) ) { //is the field set
$curdir = getcwd(); //delcare variables
if (!file_exists($meta_data[$order_id])) {
if( mkdir( $curdir . "/" . $meta_data[$order_id], 0777) ) {
//below section for for testing purposes to see if the command ran - and yes shows correctly and creates directory as expected IF the POS url is set - (triggers at the moment on page refresh)
echo "directory created"; //comment out when done testing
}else{
echo "directory NOT created"; //comment out when done testing
}
}
}else{
if( empty($meta_data[$order_id]) ) {
//do nothing
}
}
}
} //end function
I have tried the following to set the action on the inside of class but I am not doing it right and it didn't work
class pos__URL
{
public function init()
{
add_action( 'woocommerce_order_status_changed', array('pos__URL') );
}
public function __construct()
{
add_action('init', array($this, 'pos__URL_Field'));
}
public function pos__URL_Field()
{
//--------to access the value----start-----
$orders = wc_get_orders(array(
'customer_id' => get_current_user_id(),
'return' => 'ids',
));
//add the id of the custom meta field that lies in the order
$meta_data = array();
foreach ($orders as $order_id) {
$meta_data[$order_id] = get_post_meta($order_id, '_engx_text_field_id', true);
}
//--------to access the value----end-----
if( isset($meta_data[$order_id]) ) { //is the field set
$curdir = getcwd(); //delcare variables
if (!file_exists($meta_data[$order_id])) {
if( mkdir( $curdir . "/" . $meta_data[$order_id], 0777) ) {
//below section for for testing purposes to see if the command ran - and yes shows correctly and creates directory as expected IF the POS url is set - triggers at momment on page refresh
echo "directory created"; //comment out when done testing
}else{
echo "directory NOT created"; //comment out when done testing
}
}
}else{
if( empty($meta_data[$order_id]) ) {
//do nothing
}
}
}
}
You should follow the same pattern you use for the plugins_loaded but this time replace it with whatever action you want to trigger the callback for. eg:
add_action( 'woocommerce_order_status_completed', array( 'pos__URL', 'init' ));
add_action( 'woocommerce_order_status_changed', array( 'pos__URL', 'init' ));
add_action( 'woocommerce_thankyou_page', array( 'pos__URL', 'init' ));
The init function of the pos_URL class will trigger when any of the above actions occur.

disabling the action function of a class in woocommerce subscriptions

i use the woocommerce subscriptions plugin, i have a class class WC_Subscriptions_Cart {}, inside the function class is the following :
/**
* Display the recurring totals for items in the cart
*
* #since 2.0
*/
public static function display_recurring_totals() {
if ( self::cart_contains_subscription() ) {
// We only want shipping for recurring amounts, and they need to be calculated again here
self::$calculation_type = 'recurring_total';
$carts_with_multiple_payments = 0;
foreach ( WC()->cart->recurring_carts as $recurring_cart ) {
// Cart contains more than one payment
if ( 0 != $recurring_cart->next_payment_date ) {
$carts_with_multiple_payments++;
}
}
if ( apply_filters( 'woocommerce_subscriptions_display_recurring_totals', $carts_with_multiple_payments >= 1 ) ) {
wc_get_template(
'checkout/recurring-totals.php',
array(
'shipping_methods' => array(),
'recurring_carts' => WC()->cart->recurring_carts,
'carts_with_multiple_payments' => $carts_with_multiple_payments,
),
'',
WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory( 'templates/' )
);
}
self::$calculation_type = 'none';
}
}
its action is as follows :
public static function init() {
add_action( 'woocommerce_cart_totals_after_order_total', __CLASS__ . '::display_recurring_totals' );
}
i want to disable this action, my code is not working :
function remove_my_class_action(){
remove_action( 'woocommerce_cart_totals_after_order_total', array( 'WC_Subscriptions_Cart', 'display_recurring_totals' ) );
} add_action( 'woocommerce_cart_totals_after_order_total', 'remove_my_class_action' );
how can i disable this action through the function.php file? i appreciate any reply from you.
after repeated attempts, i got the answer :
remove_action( 'woocommerce_cart_totals_after_order_total', array( 'WC_Subscriptions_Cart', 'display_recurring_totals' ), 10 );

Don't understand WooCommerce Paypal Standard Gateway

So I'm building a custom payment gateway for WooCommerce which has been... challenging, mostly because I'm not a PHP developer so I have been learning as I go. I've started by dissecting the PayPal Standard Gateway which ships with WooCommerce. That gateway has an included class for handling IPN callbacks and I'm having trouble understanding why their code is set up the following way:
/**
* Constructor.
*
* #param bool $sandbox Use sandbox or not.
* #param string $receiver_email Email to receive IPN from.
*/
public function __construct( $sandbox = false, $receiver_email = '' ) {
add_action( 'woocommerce_api_wc_gateway_paypal', array( $this, 'check_response' ) );
add_action( 'valid-paypal-standard-ipn-request', array( $this, 'valid_response' ) );
$this->receiver_email = $receiver_email;
$this->sandbox = $sandbox;
}
/**
* Check for PayPal IPN Response.
*/
public function check_response() {
if ( ! empty( $_POST ) && $this->validate_ipn() ) { // WPCS: CSRF ok.
$posted = wp_unslash( $_POST ); // WPCS: CSRF ok, input var ok.
// phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
do_action( 'valid-paypal-standard-ipn-request', $posted );
exit;
}
wp_die( 'PayPal IPN Request Failure', 'PayPal IPN', array( 'response' => 500 ) );
}
/**
* There was a valid response.
*
* #param array $posted Post data after wp_unslash.
*/
public function valid_response( $posted ) {
$order = ! empty( $posted['custom'] ) ? $this->get_paypal_order( $posted['custom'] ) : false;
if ( $order ) {
// Lowercase returned variables.
$posted['payment_status'] = strtolower( $posted['payment_status'] );
WC_Gateway_Paypal::log( 'Found order #' . $order->get_id() );
WC_Gateway_Paypal::log( 'Payment status: ' . $posted['payment_status'] );
if ( method_exists( $this, 'payment_status_' . $posted['payment_status'] ) ) {
call_user_func( array( $this, 'payment_status_' . $posted['payment_status'] ), $order, $posted );
}
}
}
The first add_action registers a hook with a WooCommerce action and I totally get that - it's a way to extend functionality in an external package. However, the second add_action( 'valid-paypal-standard-ipn-request'...) seems to simply call valid_response() - which is a local function - inside the next function check_response(). Why couldn't they just call valid_response() directly within check_response()?

WordPress AJAX is_admin is true, causing issues.

i'm trying to make a plugin for WordPress, which is has got an admin section for some basic settings, and also registers some shortcode to display some HTML, which is basically a form.
Here is my main plugin file, plugins/my-plugin/my-plugin.php:
/**
* Plugin Name: Pathway
* Plugin URI: http://www.martynleeball.com/
* Description: Pathway integration.
* Version: 1.0
* Author: Martyn Lee Ball
* Author URI: https://www.martynleeball.com/
**/
define('PATHWAY_VERSION', '0.0.8');
define('PATHWAY_AUTHOR', 'Martyn Lee Ball');
define('PATHWAY__MINIMUM_WP_VERSION', '4.*');
define('PATHWAY_CONTACT', 'martynleeball#gmail.com');
add_action(
'plugins_loaded',
array ( Pathway::get_instance(), 'plugin_setup' )
);
class Pathway
{
protected static $instance = NULL;
public $plugin_url = '';
private $cpt = 'post'; # Adjust the CPT
public function __construct() {}
public static function get_instance()
{
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
public function plugin_setup()
{
$this->plugin_url = '';
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );
// if (is_admin()) {
//
// require_once( $this->plugin_url . 'admin/index.php' );
//
// register_activation_hook( __FILE__, 'install' );
//
// return;
// }
add_shortcode( 'pathway', array($this, 'shortcode'));
add_action( 'wp_ajax_ajax_login', array( $this, 'ajax_login' ) );
add_action( 'wp_ajax_nopriv_ajax_login', array( $this, 'ajax_login' ) );
add_action( 'wp_ajax_ajax_register', array( $this, 'ajax_register' ) );
add_action( 'wp_ajax_nopriv_ajax_register', array( $this, 'ajax_register' ) );
}
public function enqueue()
{
wp_enqueue_script( 'vuejs', 'https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js' );
wp_enqueue_script(
'ajax-handle-form',
"{$this->plugin_url}/wp-content/plugins/pathway/frontend/js/scripts.js"
);
wp_localize_script(
'ajax-handle-form',
'wp_ajax',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajaxnonce' => wp_create_nonce( 'ajax_post_validation' )
)
);
}
public function ajax_login()
{
echo 'login';exit;
}
public function ajax_register()
{
echo 'register';exit;
}
public function shortcode()
{
if (!isset($_SESSION['pathway_login'])) {
self::view('forms/login');
}
}
public static function view( $name, array $args = array() ) {
foreach ( $args AS $key => $val ) {
$$key = $val;
}
// $file = $this->plugin_url . 'views/'. $name . '.php';
$file = 'views/'. $name . '.php';
include( $file );
}
}
Please correct me if i'm going wrong somewhere, there's so many mixed guides online showing different ways. Within this file i'm basically:
Adding my scripts and assigning the PHP values.
I would be then starting the admin section however has to comment this out for the AJAX call, this is my issue.
Registering my shortcode.
Adding the actions for the AJAX form submit.
Obviously my issue is that when I hit the is_admin from the AJAX call it is returning true, when it should be false as an public visitor can submit this form. The wp_ajax_nopriv action doesn't appear to work which would solve the issue, this is probably due to me being logged into WordPress.
I have tried logging out of WordPress but the is_admin still returns true!
Can someone advise?
is_admin will return true on all ajax calls.
It is not actually a useful function to check the user as it checks the uri rather than the user details, i.e. if on a admin page = true, if not false.
Now I was a little confused about your question here, it appears you want the is_admin to return false if its actually an ajax call?
if ( is_admin() && ! wp_doing_ajax() ) {}
It will return false on ajax calls.
If you are checking there is an "admin" logged in, as in can edit posts, see the other capabilities here
if ( current_user_can( 'edit_post' ) ) {}
The no_priv hook will not work when logged in, its not called.

Add an icon to custom WooCommerce payment gateway

I would like to add a custom icon to my payment gateway. I have read the WOO gateway API and have zero help. This is my code below. please help me find a functional way to include the icon so I have an icon on my front end. Thanks
<?php if ( ! defined( 'ABSPATH' ) ) { exit; }
add_filter( 'woocommerce_payment_gateways', 'init_wpuw_gateway' );
function init_wpuw_gateway ( $methods )
{
$methods[] = 'WC_Gateway_WPUW';
return $methods;
}
if( class_exists('WC_Payment_Gateway') ):
class WC_Gateway_WPUW extends WC_Payment_Gateway {
/**
* Constructor for the gateway.
*/
public function __construct() {
$plugin_dir = plugin_dir_url(__FILE__);
$this->id = 'wpuw';
//If you want to show an image next to the gateway’s name on the frontend, enter a URL to an image.
$this->icon = apply_filters( 'woocommerce_gateway_icon', ''.$plugin_dir.'/assets/paysecure.png' );
$this->method_title = __( 'User Wallet', 'woocommerce' );
$this->method_description = __( 'Have your customers pay with their user wallet balance.', 'woocommerce' );
$this->has_fields = false;
Try with backslash instead of slash without concatenating the initial empty string with the variable $plugin_dir
$this->icon = apply_filters( 'woocommerce_gateway_icon', $plugin_dir.'\assets\paysecure.png' );
Using the WooCommerce filter woocommerce_gateway_icon you can add the icon to the payment gateway this way:
/**
* Add Custom Icon
*/
function custom_gateway_icon( $icon, $id ) {
if ( $id === 'custom' ) {
return '<img src="' . plugins_url( 'img/custom.png', __FILE__ ) . '" > ';
} else {
return $icon;
}
}
add_filter( 'woocommerce_gateway_icon', 'custom_gateway_icon', 10, 2 );
I would suggest woocommerce_available_payment_gateways filter.
/**
Add Custom Icon For Cash On Delivery
**/
function cod_gateway_icon( $gateways ) {
if ( isset( $gateways['cod'] ) ) {
$gateways['cod']->icon = get_stylesheet_directory_uri() . '/images/cod.png';
}
return $gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'cod_gateway_icon' );
try this:
$this->icon = trailingslashit( WP_PLUGIN_URL ) . plugin_basename( dirname( __FILE__ ) ) . '/assets/paysecure.png';

Categories