I am developing a payment gateway on WordPress Plugins. I'm having a callback problem between Java Backend and WordPress Plugins. Java Backend wants to send order updates to WordPress Plugins. I have 2 options:
Option 1: I use the callback function (follow instructions https://woocommerce.com/document/payment-gateway-api/#section-2)
Here is the code I integrated
<?php
/**
* Plugin Name: H Payments
* Plugin URI:
* Author Name: H Team
* Author URI:
* Description:
* Version: 0.1.0
* License: 0.1.0
* License URL:
* text-domain: woocommerce-h-pay-woo
*/
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
return;
}
add_action( 'plugins_loaded', 'payment_init' );
function payment_init() {
if ( class_exists( 'WC_Payment_Gateway' ) ) {
class WC_H_Payment_Gateway extends WC_Payment_Gateway {
function __construct() {
$this->code = 'WC_H_Payment_Gateway';
$this->path = 'hpay/v1';
$this->id = 'h_payment';
$this->icon = apply_filters( 'woocommerce_h_icon', plugins_url( '/assets/icon/icon.png', __FILE__ ) );
$this->has_fields = true;
$this->method_title = __( 'H Payment', 'woocommerce-h-pay-woo' );
$this->method_description = __( 'H Payment Systems', 'woocommerce-h-pay-woo' );
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->init_form_fields();
$this->init_settings();
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array(
$this,
'process_admin_options'
) );
add_action( 'woocommerce_api_wc_h_payment_gateway', array( $this, 'check_h_payment_response' ) );
}
public function init_rest_api_callback() {
register_rest_route( 'hpay/v1', '/callback', [
'methods' => 'GET',
'callback' => [ $this, 'check_h_payment_response' ],
] );
}
public function init_form_fields() {
$this->form_fields = apply_filters( 'h_payment_fields', array(
'enable' => array(
'title' => __( 'Enable/Disable', 'woocommerce-h-pay-woo' ),
'type' => 'checkbox',
'label' => __( 'Enable or Disable H Payment', 'woocommerce-h-pay-woo' ),
'default' => true
),
'title' => array(
'title' => __( 'H Payments Gateway', 'woocommerce-h-pay-woo' ),
'type' => 'text',
'default' => __( 'H Payments Gateway', 'woocommerce-h-pay-woo' ),
'desc_tip' => true,
'description' => __( 'Add a new title for the H Payments Gateway that customers will see when they are in the checkout page.', 'noob-pay-woo' )
),
'description' => array(
'title' => __( 'H Pay Description', 'woocommerce-h-pay-woo' ),
'type' => 'textarea',
'default' => __( 'By using H Payment you agree to our terms of service and privacy statement', 'woocommerce-h-pay-woo' ),
'description' => __( 'Simple description', 'woocommerce-h-pay-woo' ),
'desc_tip' => true
),
) );
}
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
$order->update_status( 'on-hold', __( 'Awaiting Payment', 'woocommerce-h-pay-woo') );
$order->reduce_order_stock();
WC()->cart->empty_cart();
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
public function check_h_payment_response() {
// do sth
if ( isset( $_GET['h_transaction_uuid'] ) ) {
return "SUCCESS";
} else {
return "ERROR";
}
}
}
}
}
add_filter( 'woocommerce_payment_gateways', 'add_to_h_payment_gateway' );
function add_to_h_payment_gateway( $gateways ) {
$gateways[] = 'WC_H_Payment_Gateway';
return $gateways;
}
Then I call through the URL http://localhost/mystore/wc-api/wc_h_payment_gateway?h_transaction_uuid=1234 but the result is -1 (https://i.stack.imgur.com/FhSry.png)
Option 2: I register a rest api using register_rest_route: (https://i.stack.imgur.com/jle1Z.png)
Here is the code I integrated
<?php
/**
* Plugin Name: H Payments
* Plugin URI:
* Author Name: H Team
* Author URI:
* Description:
* Version: 0.1.0
* License: 0.1.0
* License URL:
* text-domain: woocommerce-h-pay-woo
*/
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
return;
}
add_action( 'plugins_loaded', 'payment_init' );
function payment_init() {
if ( class_exists( 'WC_Payment_Gateway' ) ) {
class WC_H_Payment_Gateway extends WC_Payment_Gateway {
function __construct() {
$this->code = 'WC_H_Payment_Gateway';
$this->path = 'hpay/v1';
$this->id = 'h_payment';
$this->icon = apply_filters( 'woocommerce_h_icon', plugins_url( '/assets/icon/icon.png', __FILE__ ) );
$this->has_fields = true;
$this->method_title = __( 'H Payment', 'woocommerce-h-pay-woo' );
$this->method_description = __( 'H Payment Systems', 'woocommerce-h-pay-woo' );
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->init_form_fields();
$this->init_settings();
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array(
$this,
'process_admin_options'
) );
add_action( 'rest_api_init_custom', array( $this, 'init_rest_api_callback' ) );
do_action( 'rest_api_init_custom' );
}
public function init_rest_api_callback() {
register_rest_route( 'hpay/v1', '/callback', [
'methods' => 'GET',
'callback' => [ $this, 'check_h_payment_response' ],
] );
}
public function init_form_fields() {
$this->form_fields = apply_filters( 'h_payment_fields', array(
'enable' => array(
'title' => __( 'Enable/Disable', 'woocommerce-h-pay-woo' ),
'type' => 'checkbox',
'label' => __( 'Enable or Disable H Payment', 'woocommerce-h-pay-woo' ),
'default' => true
),
'title' => array(
'title' => __( 'H Payments Gateway', 'woocommerce-h-pay-woo' ),
'type' => 'text',
'default' => __( 'H Payments Gateway', 'woocommerce-h-pay-woo' ),
'desc_tip' => true,
'description' => __( 'Add a new title for the H Payments Gateway that customers will see when they are in the checkout page.', 'noob-pay-woo' )
),
'description' => array(
'title' => __( 'H Pay Description', 'woocommerce-h-pay-woo' ),
'type' => 'textarea',
'default' => __( 'By using H Payment you agree to our terms of service and privacy statement', 'woocommerce-h-pay-woo' ),
'description' => __( 'Simple description', 'woocommerce-h-pay-woo' ),
'desc_tip' => true
),
) );
}
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
$order->update_status( 'on-hold', __( 'Awaiting Payment', 'woocommerce-h-pay-woo') );
$order->reduce_order_stock();
WC()->cart->empty_cart();
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
public function check_h_payment_response() {
// do sth
if ( isset( $_GET['h_transaction_uuid'] ) ) {
return "SUCCESS";
} else {
return "ERROR";
}
}
}
}
}
add_filter( 'woocommerce_payment_gateways', 'add_to_h_payment_gateway' );
function add_to_h_payment_gateway( $gateways ) {
$gateways[] = 'WC_H_Payment_Gateway';
return $gateways;
}
Rest API is registered but when I click checkout I get the error "Internal Server Error"
[15-May-2022 15:44:30 UTC] PHP Fatal error: Uncaught Error: Call to a member function get_payment_gateway_ids() on null in C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\Schemas\V1\CheckoutSchema.php:115
Stack trace:
#0 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\Schemas\V1\AbstractSchema.php(62): Automattic\WooCommerce\StoreApi\Schemas\V1\CheckoutSchema->get_properties()
#1 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\Routes\V1\AbstractRoute.php(85): Automattic\WooCommerce\StoreApi\Schemas\V1\AbstractSchema->get_item_schema()
#2 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\Routes\V1\AbstractRoute.php(263): Automattic\WooCommerce\StoreApi\Routes\V1\AbstractRoute->get_item_schema()
#3 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\Routes\V1\Checkout.php(70): Automattic\WooCommerce\StoreApi\Routes\V1\AbstractRoute->get_context_param(Array)
#4 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\RoutesController.php(113): Automattic\WooCommerce\StoreApi\Routes\V1\Checkout->get_args()
#5 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\RoutesController.php(68): Automattic\WooCommerce\StoreApi\RoutesController->register_routes('v1', 'wc/store')
#6 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\packages\woocommerce-blocks\src\StoreApi\StoreApi.php(26): Automattic\WooCommerce\StoreApi\RoutesController->register_all_routes()
#7 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(307): Automattic\WooCommerce\StoreApi\StoreApi->Automattic\WooCommerce\StoreApi\{closure}(Object(WP_REST_Server))
#8 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(331): WP_Hook->apply_filters(NULL, Array)
#9 C:\xampp\htdocs\hodlerext\wp-includes\plugin.php(474): WP_Hook->do_action(Array)
#10 C:\xampp\htdocs\hodlerext\wp-includes\rest-api.php(553): do_action('rest_api_init', Object(WP_REST_Server))
#11 C:\xampp\htdocs\hodlerext\wp-includes\rest-api.php(109): rest_get_server()
#12 C:\xampp\htdocs\hodlerext\wp-content\plugins\test-plugin\test-plugin.php(49): register_rest_route('hpay/v1', '/callback', Array)
#13 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(307): WC_H_Payment_Gateway->init_rest_api_callback('')
#14 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(331): WP_Hook->apply_filters('', Array)
#15 C:\xampp\htdocs\hodlerext\wp-includes\plugin.php(474): WP_Hook->do_action(Array)
#16 C:\xampp\htdocs\hodlerext\wp-content\plugins\test-plugin\test-plugin.php(43): do_action('rest_api_init_c...')
#17 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-wc-payment-gateways.php(97): WC_H_Payment_Gateway->__construct()
#18 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-wc-payment-gateways.php(70): WC_Payment_Gateways->init()
#19 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-wc-payment-gateways.php(43): WC_Payment_Gateways->__construct()
#20 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-woocommerce.php(890): WC_Payment_Gateways::instance()
#21 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-woocommerce.php(163): WooCommerce->payment_gateways()
#22 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-wc-checkout.php(880): WooCommerce->__get('payment_gateway...')
#23 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-wc-checkout.php(1172): WC_Checkout->validate_checkout(Array, Object(WP_Error))
#24 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-wc-ajax.php(461): WC_Checkout->process_checkout()
#25 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(307): WC_AJAX::checkout('')
#26 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(331): WP_Hook->apply_filters('', Array)
#27 C:\xampp\htdocs\hodlerext\wp-includes\plugin.php(474): WP_Hook->do_action(Array)
#28 C:\xampp\htdocs\hodlerext\wp-content\plugins\woocommerce\includes\class-wc-ajax.php(90): do_action('wc_ajax_checkou...')
#29 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(307): WC_AJAX::do_wc_ajax('')
#30 C:\xampp\htdocs\hodlerext\wp-includes\class-wp-hook.php(331): WP_Hook->apply_filters(false, Array)
#31 C:\xampp\htdocs\hodlerext\wp-includes\plugin.php(474): WP_Hook->do_action(Array)
#32 C:\xampp\htdocs\hodlerext\wp-includes\template-loader.php(13): do_action('template_redire...')
#33 C:\xampp\htdocs\hodlerext\wp-blog-header.php(19): require_once('C:\\xampp\\htdocs...')
#34 C:\xampp\htdocs\hodlerext\index.php(17): require('C:\\xampp\\htdocs...')
#35 {main}
What I am doing wrong?
I am new to PHP Woocommerce any help will be appreciated.
Thanks in advance
I chose method 1, I was wrong in naming the callback function
Create an id in __contruct:
$this->id = 'h_payment';
Add a callback action:
add_action( 'woocommerce_api_' . $this->id, array( $this, 'check_h_payment_response' ) );
Create function for handler callback:
public function check_h_payment_response() {//todo}
And the URL will be
home_url() . '/wc-api/' . $this->id
It seems that the result when calling postman will always be -1 however everything still works
Related
My woocommerce are not listing orders with status 'wc-expired'. I tried adding the 'wc_order_statuses' filter, but it still does not work.
add_filter('wc_order_statuses', function ($order_statuses){
$order_statuses['wc-expired'] = _x( 'Expired', 'Order status', 'woocommerce' );
return $order_statuses;
});
Row in Table wp_posts
The Orders List in Admin
Create new order status. Sample:
function register_expired_order_status() {
register_post_status( 'wc-expired', array(
'label' => 'Expired',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Expired <span class="count">(%s)</span>', 'Expired <span class="count">(%s)</span>' )
) );
}
add_action( 'init', 'register_expired_order_status' );
function add_expired_to_order_statuses( $order_statuses ) {
$new_order_statuses = array();
// add new order status after processing
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
if ( 'wc-processing' === $key ) {
$new_order_statuses['wc-expired'] = 'Expired';
}
}
return $new_order_statuses;
}
add_filter( 'wc_order_statuses', 'add_expired_to_order_statuses' );
Please consider the following php class extends the WP_REST_Controller class of Wordpress related to Rest API:
<?php
class MCQAcademy_Endpoint extends WP_REST_Controller {
/**
* Register the routes for the objects of the controller.
*/
public function register_routes() {
$version = '1';
$namespace = 'custompath/v' . $version;
$base = 'endpointbase';
register_rest_route(
$namespace,
'/' . $base,
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => array(),
)
)
);
}
/**
*
*/
public function get_items( $request ) {
$rs = array(
'data' => array(),
'request' => array(
'lang' => 'en',
),
);
$args = array();
$items = get_posts( $args );
foreach( $items as $item ) {
$itemdata = $this->prepare_item_for_response( $item, $request );
$rs['data'][] = $this->prepare_response_for_collection( $itemdata );
}
$rs['wp_get_current_user'] = wp_get_current_user(); // Does not output as expected
return new WP_REST_Response( $rs, 200 );
}
/**
* Check if a given request has access to get items
*/
public function get_items_permissions_check( $request ) {
return true; // to make readable by all
}
/**
* Prepare the item for create or update operation
*/
protected function prepare_item_for_database( $request ) {
return $request;
}
/**
* Prepare the item for the REST response
*/
public function prepare_item_for_response( $item, $request ) {
$data = array(
'ID' => $item->ID,
'post_content' => wpautop($item->post_content),
'post_title' => $item->post_title,
);
return $data;
}
/**
* Get the query params for collections
*/
public function get_collection_params() {
return array(
'page' => array(
'description' => 'Current page of the collection.',
'type' => 'integer',
'default' => 1,
'sanitize_callback' => 'absint',
),
'per_page' => array(
'description' => 'Maximum number of items to be returned in result set.',
'type' => 'integer',
'default' => 10,
'sanitize_callback' => 'absint',
),
'search' => array(
'description' => 'Limit results to those matching a string.',
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
),
);
}
// Register our REST Server
public function hook_rest_server(){
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}
}
$myEndpoint = new MCQAcademy_Endpoint();
$myEndpoint->hook_rest_server();
Everything is going well except calling the wp_get_current_user() function in the get_items() function return empty user even though the user is loggedin in the website.
What is the solution to get the loggedin user info in Rest API endpoint function?
I am building a plugin where I have a dropdown category filter on media library.
The filter works fine on list view but on grid view mode when I select a category, rather than media files getting filtered the page refreshes and nothing is filtering.
I am not using any custom taxonomy, so I have register the taxonomy (in my case it is category to attachment post type)
function register_taxonomy_for_post_type() {
//$this->taxonomy = apply_filters( 'cool_media_taxonomy', $this->taxonomy );
if( taxonomy_exists( $this->taxonomy ) ) {
register_taxonomy_for_object_type( $this->taxonomy, $this->post_type );
} else {
$args = array(
'hierarchical' => true,
'show_admin_column' => true,
'update_count_callback' => array( $this, 'update_count' ),
);
register_taxonomy( $this->taxonomy, array( $this->post_type ), $args );
}
}
add_action( 'init', array( $this, 'register_taxonomy_for_post_type' ), 0 );
Localization:
function enqueue_media_action() {
require_once plugin_dir_path( __FILE__ ) . 'classes/class-walker-category-mediagrid-filter.php';
global $pagenow;
if( wp_script_is( 'media-editor' ) && 'upload.php' === $pagenow ) {
if( $this->taxonomy !== 'category' ) {
$options = array(
'taxonomy' => $this->taxonomy,
'hierarchical' => true,
'hide_empty' => false,
'show_count' => true,
'orderby' => 'name',
'order' => 'ASC',
'value' => 'id',
'echo' => false,
'walker' => new WalkerCategoryMediaGridFilter(),
);
} else {
$options = array(
'taxonomy' => $this->taxonomy,
'hierarchical' => true,
'hide_empty' => false,
'show_count' => true,
'orderby' => 'name',
'order' => 'ASC',
'value' => 'id',
'echo' => false,
'walker' => new WalkerCategoryMediaGridFilter(),
);
}
$attachment_terms = wp_dropdown_categories( $options );
$attachment_terms = preg_replace( array( "/<select([^>]*)>/", "/<\/select>/" ), "", $attachment_terms );
echo '<script type="text/javascript">';
echo '/* <![CDATA[ */';
echo 'var coolmediafilter_taxonomies = {"' . $this->taxonomy . '":{"list_title":"' . html_entity_decode( __( 'All categories', $this->text_domain ), ENT_QUOTES, 'UTF-8' ) . '","term_list":[' . substr( $attachment_terms, 2 ) . ']}};';
echo '/* ]]> */';
echo '</script>';
wp_enqueue_script('coolmediafilter-media-views', plugins_url( 'js/cmf-media-views.js', __FILE__ ), array( 'media-views' ), '1.0.0', true );
$cats = $this->get_accessible_categories();
$filtered_cats = array(
'hide_empty' => false,
'include' => $cats,
'orderby' => 'name',
'order' => 'ASC',
);
wp_localize_script( 'coolmediafilter-media-views', 'MediaLibraryCategoryFilterOptions',
array(
'terms' => get_terms(
$this->taxonomy,
$filtered_cats
),
)
);
}
wp_enqueue_style( 'coolmediafilter', plugins_url( 'css/coolmediafilter.css', __FILE__ ), array(), '1.0.0' );
}
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_media_action' ) );
The script:
(function(){
/**
* Create a new MediaLibraryTaxonomyFilter we later will instantiate
*/
var MediaLibraryCategoryFilter = wp.media.view.AttachmentFilters.extend({
id: 'media-view-category-filter',
createFilters: function() {
var filters = {};
// Formats the 'terms' we've included via wp_localize_script()
_.each( MediaLibraryCategoryFilterOptions.terms || {}, function( value, index ) {
filters[ value.term_id ] = {
text: value.name,
props: {
// The WP_Query var for the taxonomy
category: value.term_id,
}
};
});
filters.all = {
// Default label
text: 'All categories',
props: {
// The WP_Query var for the taxonomy
category: ''
},
priority: 10
};
this.filters = filters;
}
});
/**
* Extend and override wp.media.view.AttachmentsBrowser to include our new filter
*/
var AttachmentsBrowser = wp.media.view.AttachmentsBrowser;
wp.media.view.AttachmentsBrowser = wp.media.view.AttachmentsBrowser.extend({
createToolbar: function() {
// Make sure to load the original toolbar
AttachmentsBrowser.prototype.createToolbar.call( this );
this.toolbar.set( 'MediaLibraryCategoryFilter', new MediaLibraryCategoryFilter({
controller: this.controller,
model: this.collection.props,
priority: -75
}).render() );
}
});
})()
what I am doing wrong? Any suggestion will be very helpful.
UPDATE: Screenshot of console from FireFox
I have created a plugins about to save Authorz data using wordpress custom fields and meta box. The Plugins has no errors and running but the Meta boxes are not showing.
The plugins is running and i have attached the screenshot.
http://i63.tinypic.com/2czebyh.png
Below is my plugin code
<?php
/*Plugin Name: CNSLounge
Description: This plugin registers the 'Authors CNSLounge' post type.
Version: 1.0
Author: Anita Mandal
Author URI: http://cosmoread.com/
License: GPLv2
*/
// Register Custom Post Type
function CNSLounge() {
register_post_type('CNSLounge', array(
'labels' => array(
'name' => 'Authorz',
'singular_name' => 'Authorz',
'add_new' => 'Add New',
'add_new_item' => 'Add New Authorz',
'edit' => 'Edit',
'edit_item' => 'Edit Authorz',
'new_item' => 'New Authorz',
'view' => 'View',
'view_item' => 'View Authorz',
'search_items' => 'Search Authorz',
'not_found' => 'No Authorz found',
'not_found_in_trash' => 'No Authorz found in Trash',
'parent' => 'Parent Authorz'
),
'public' => true,
'menu_position' => 15,
'supports' => array(
'title',
'editor',
'comments',
'thumbnail'
),
'taxonomies' => array(
''
),
'menu_icon' => plugins_url('images/image.png', __FILE__),
'has_archive' => true
));
register_post_type( 'post_type', $args );
}
add_action( 'init', 'CNSLounge', 0 );
class Rational_Meta_Box {
private $screens = array(
'post',
);
private $fields = array(
array(
'id' => 'authorz-name',
'label' => 'Authorz Name',
'type' => 'text',
),
array(
'id' => 'author-photo',
'label' => 'Author Photo',
'type' => 'media',
),
array(
'id' => 'active-since',
'label' => 'Active Since',
'type' => 'date',
),
array(
'id' => 'languages-expression',
'label' => 'Languages Expression',
'type' => 'text',
),
array(
'id' => 'now-based-at',
'label' => 'Now Based at',
'type' => 'text',
),
array(
'id' => 'location-of-author',
'label' => 'Location of Author',
'type' => 'text',
),
array(
'id' => 'mostly-writes',
'label' => 'Mostly Writes',
'type' => 'text',
),
array(
'id' => 'about-author',
'label' => 'About Author',
'type' => 'textarea',
),
array(
'id' => 'magazines',
'label' => 'Magazines',
'type' => 'media',
),
array(
'id' => 'publication',
'label' => 'Publication',
'type' => 'media',
),
array(
'id' => 'gallery',
'label' => 'Gallery',
'type' => 'media',
),
array(
'id' => 'author-s-website',
'label' => 'Author\'s Website',
'type' => 'url',
),
array(
'id' => 'author-s-email',
'label' => 'Author\'s Email',
'type' => 'email',
),
array(
'id' => 'author-s-phone',
'label' => 'Author\'s Phone',
'type' => 'number',
),
);
/**
* Class construct method. Adds actions to their respective WordPress hooks.
*/
public function __construct() {
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
add_action( 'admin_footer', array( $this, 'admin_footer' ) );
add_action( 'save_post', array( $this, 'save_post' ) );
}
/**
* Hooks into WordPress' add_meta_boxes function.
* Goes through screens (post types) and adds the meta box.
*/
public function add_meta_boxes() {
foreach ( $this->screens as $screen ) {
add_meta_box(
'cnslounge',
__( 'CNSLounge', 'rational-metabox' ),
array( $this, 'add_meta_box_callback' ),
$screen,
'advanced',
'default'
);
}
}
/**
* Generates the HTML for the meta box
*
* #param object $post WordPress post object
*/
public function add_meta_box_callback( $post ) {
wp_nonce_field( 'cnslounge_data', 'cnslounge_nonce' );
echo 'CNSLounge Author Meta Information';
$this->generate_fields( $post );
}
/**
* Hooks into WordPress' admin_footer function.
* Adds scripts for media uploader.
*/
public function admin_footer() {
?><script>
// https://codestag.com/how-to-use-wordpress-3-5-media-uploader-in-theme-options/
jQuery(document).ready(function($){
if ( typeof wp.media !== 'undefined' ) {
var _custom_media = true,
_orig_send_attachment = wp.media.editor.send.attachment;
$('.rational-metabox-media').click(function(e) {
var send_attachment_bkp = wp.media.editor.send.attachment;
var button = $(this);
var id = button.attr('id').replace('_button', '');
_custom_media = true;
wp.media.editor.send.attachment = function(props, attachment){
if ( _custom_media ) {
$("#"+id).val(attachment.url);
} else {
return _orig_send_attachment.apply( this, [props, attachment] );
};
}
wp.media.editor.open(button);
return false;
});
$('.add_media').on('click', function(){
_custom_media = false;
});
}
});
</script><?php
}
/**
* Generates the field's HTML for the meta box.
*/
public function generate_fields( $post ) {
$output = '';
foreach ( $this->fields as $field ) {
$label = '<label for="' . $field['id'] . '">' . $field['label'] . '</label>';
$db_value = get_post_meta( $post->ID, 'advanced_options_' . $field['id'], true );
switch ( $field['type'] ) {
case 'media':
$input = sprintf(
'<input class="regular-text" id="%s" name="%s" type="text" value="%s"> <input class="button rational-metabox-media" id="%s_button" name="%s_button" type="button" value="Upload" />',
$field['id'],
$field['id'],
$db_value,
$field['id'],
$field['id']
);
break;
case 'textarea':
$input = sprintf(
'<textarea class="large-text" id="%s" name="%s" rows="5">%s</textarea>',
$field['id'],
$field['id'],
$db_value
);
break;
default:
$input = sprintf(
'<input %s id="%s" name="%s" type="%s" value="%s">',
$field['type'] !== 'color' ? 'class="regular-text"' : '',
$field['id'],
$field['id'],
$field['type'],
$db_value
);
}
$output .= $this->row_format( $label, $input );
}
echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
}
/**
* Generates the HTML for table rows.
*/
public function row_format( $label, $input ) {
return sprintf(
'<tr><th scope="row">%s</th><td>%s</td></tr>',
$label,
$input
);
}
/**
* Hooks into WordPress' save_post function
*/
public function save_post( $post_id ) {
if ( ! isset( $_POST['cnslounge_nonce'] ) )
return $post_id;
$nonce = $_POST['cnslounge_nonce'];
if ( !wp_verify_nonce( $nonce, 'cnslounge_data' ) )
return $post_id;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
foreach ( $this->fields as $field ) {
if ( isset( $_POST[ $field['id'] ] ) ) {
switch ( $field['type'] ) {
case 'email':
$_POST[ $field['id'] ] = sanitize_email( $_POST[ $field['id'] ] );
break;
case 'text':
$_POST[ $field['id'] ] = sanitize_text_field( $_POST[ $field['id'] ] );
break;
}
update_post_meta( $post_id, 'cnslounge_' . $field['id'], $_POST[ $field['id'] ] );
} else if ( $field['type'] === 'checkbox' ) {
update_post_meta( $post_id, 'cnslounge_' . $field['id'], '0' );
}
}
}
}
new Rational_Meta_Box;
?>
private $screens = array(
'post',
);
So, you are adding the metaboxes to post, not to your custom post type.
Use your custom post type slug here. just like
private $screens = array(
'CNSLounge',
);
I am trying to make a Custom Gateway Plugin for my Merchant Account but I got stuck and I don't know how to continue.
Now, here is what I done so far:
<?php
/*
Plugin Name: Paysecure.ro Payment Gateway
Plugin URI: http://www.Paysecure.ro
Description: Allows you to use Paysecure.ro Payment Gateway with the WooCommerce plugin.
Version: 0.0.1
Author: Andrei Raileanu
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
add_action('plugins_loaded', 'woocommerce_Paysecure', 0);
function woocommerce_Paysecure(){
if (!class_exists('WC_Payment_Gateway'))
return; // if the WC payment gateway class is not available, do nothing
if(class_exists('WC_Paysecure'))
return;
class WC_Gateway_Paysecure extends WC_Payment_Gateway{
public function __construct(){
$plugin_dir = plugin_dir_url(__FILE__);
global $woocommerce;
$this->id = 'Paysecure';
$this->icon = apply_filters('woocommerce_Paysecure_icon', ''.$plugin_dir.'Paysecure.png');
$this->has_fields = true;
// Load the settings
$this->init_form_fields();
$this->init_settings();
// Define user set variables
$this->title = "Credit/Debit Card";
$this->description = "You will be redirected to paysecure.ro to complete your purchase.";
$this->cui = "XXXXXXXXX";
$this->encryption_key = "XXXXXXXXX";
$this->currency = "USD";
// Logs
if ($this->debug == 'yes'){
$this->log = $woocommerce->logger();
}
// Actions
add_action('woocommerce_receipt_' . $this->id, array($this, 'receipt_page'));
// Save options
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
// Payment listener/API hook
add_action('woocommerce_api_wc_' . $this->id, array($this, 'check_ipn_response'));
}
function init_form_fields()
{
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable Paysecure', 'woocommerce' ),
'default' => 'yes'
)
);
}
public function admin_options() {
?>
<h3><?php _e( 'Paysecure', 'woocommerce' ); ?></h3>
<p><?php _e( 'Paysecure Payment Gateway', 'woocommerce' ); ?></p>
<table class="form-table">
<?php $this->generate_settings_html(); ?>
</table>
<?php
}
function payment_fields() {
$plugin_dir = plugin_dir_url(__FILE__);
// Description of payment method from settings
if ($this->description) { ?>
<p><?php
echo $this->description; ?>
</p><?php
} ?>
<?php
}
function process_payment( $order_id ) {
global $woocommerce;
$order = new WC_Order($order_id);
// I WILL NEED THESE FIELDS
//$this->notify_url;
//$order->get_total();
//$order->get_order_number();
//$order->billing_first_name;
//$order->billing_email;
}
}
function add_Paysecure_gateway($methods){
$methods[] = 'WC_Gateway_Paysecure';
return $methods;
}
add_filter('woocommerce_payment_gateways', 'add_Paysecure_gateway');
}
Here are the PHP instructions from my merchant account provider:
<?php
require_once('./functions.php');
$key = 'THIS IS THE ENCRYPTION KEY';
$data = array( 'cui' => 'THIS IS THE CUI CODE',
'AMOUNT' => '200',
'CURRENCY' => 'USD',
'ORDER' => '12313',
'DESC' => ps_clean('SHORT DESCRIPTION'),
'PENTRU' => 'EMAIL ADDRESS',
'TRTYPE' => 0,
'BACKREF' => 'http://www.site.ro/test.php',
'TIMESTAMP'=>time()
);
echo '<form action="https://paysecure.ro/order/cgi-bin/" method="post" >';
foreach ($data as $l => $v ) echo '<input size="55" readonly type="text" name="'.$l.'" value="'.$v.'" /> : <label for="'.$l.'">'.$l.'</label><br>';
echo '<input size="55" type="text" name="P_SIGN" readonly value="'.calculateSign($data,$key).'" /><br>' ; //se calculeaza P_SIGN - ul , encriptarea datelor
?>
<input type="submit" />
</form>
Can someone help me with the rest of the code?
1st mistake I noticed you made, $this->id MUST be in lowercase. 'Paysecure' is not gonna work here come time for the API hook.
// Payment listener/API hook
add_action('woocommerce_api_wc_' . $this->id, array($this, 'check_ipn_response'));
change to this instead:
// Payment listener/API hook
add_action('woocommerce_api_wc_paysecure', array($this, 'check_ipn_response'));
2nd mistake is that you forgot to create the function check_ipn_response()
// Handles the callbacks received from the payment backend. give this url to your payment processing comapny as the ipn response URL:
// USAGE: http://myurl.com/?wc-api=WC_Gateway_Paysecure
function check_ipn_response() {
$http_contents = file_get_contents("php://input");
$json = json_decode($http_contents, true);
$order = new WC_Order($json['custom']);
if ($callback_json['status'] == 'Transaction approved')
{
$order->payment_complete(); //This will ensure stock reductions are made, and the status is changed to the correct value.
$order->add_order_note( __( 'KiwiPay Transaction Approved.', 'kiwipay' ) );
}
else
{
$order->update_status('failed');
$order->add_order_note('KiwiPay status received - ' . $callback_json['status']);
}
//references:
//http://docs.woothemes.com/document/payment-gateway-api/
//https://github.com/Paymium/WooCommerce/blob/master/checkout.php
//https://github.com/tubiz/voguepay-woocommerce-payment-gateway/blob/master/voguepay-woocommerce-payment-gateway.php
/*
{
"id":1863,
"amount":1750,
"status":"Transaction approved",
"created":1434198776,
"reference":"2626", //this is the order number $order->get_order_number()
"name":"HamishTest Test",
"email":"hamish#tst.xom",
"address":{"street":"my rd","region":"N/A","city":"tauranga","zip":"3175","country":"NZ"},
"test":true,
"price":"17.50",
"custom":"6589" //this is the wc order_id passed during process_payment to the paymen processor.
}
*/
How about this?
add_action( 'plugins_loaded', 'init_gateway_cash' );
function init_gateway_cash() {
class WC_Gateway_Cash extends WC_Payment_Gateway {
function __construct() {
$this->id = "Cash Gateway";
$this->title = "Cash";
$this->description = "More later";
$this->init_form_fields();
$this->init_settings();
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.', 'woocommerce' )
);
// Remove cart
$woocommerce->cart->empty_cart();
// Return thankyou redirect
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
}
}
function add_gateway_cash_class ($methods ) {
$methods[] = 'WC_Gateway_Cash';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_gateway_cash_class' );