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' );
Related
I'm trying to create a function.
My need is follow:
I have a cash on delivery payment method.
Sometime it happens that the shipping comes back because the address is wrong or not real.
Then I put this order in SPAM status.
I want that when I have a COD order, to check in all SPAM orders if address is present, if yes put the order in SPAM review status, so I can check it personally with client.
This is my code:
I put a check address button on "on hold" orders, that will check the addresses:
// 1. Create 2 new order statuses: SPAM and SPAM REVIEW
function create_new_order_statuses() {
register_post_status( 'wc-spam', array(
'label' => 'SPAM',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true
) );
register_post_status( 'wc-spam-review', array(
'label' => 'SPAM REVIEW',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true
) );
}
add_action( 'init', 'create_new_order_statuses' );
// 2. Register them in woocommerce
function add_spam_order_statuses_to_select( $order_statuses ) {
$order_statuses['wc-spam'] = 'SPAM';
$order_statuses['wc-spam-review'] = 'SPAM REVIEW';
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'add_spam_order_statuses_to_select' );
add_action( 'woocommerce_admin_order_data_after_order_details', 'check_address_button_on_order_page' );
function check_address_button_on_order_page( $order ) {
if ( $order->get_status() === 'on-hold' ) {
$address = $order->get_address( 'shipping' );
echo '<button class="button check-address-button">Check Address</button>';
?>
<script>
jQuery('.check-address-button').click( function() {
var data = {
'action': 'check_address',
'address': <?php echo json_encode( $address ); ?>
};
jQuery.post(ajaxurl, data, function(response) {
if(response.found) {
alert('Match found, order status changed to "SPAM REVIEW"');
} else {
alert('No match found');
}
});
});
</script>
<?php
}
}
add_action( 'wp_ajax_check_address', 'check_address' );
function check_address() {
$address = json_decode( $_POST['address'] );
$spam_orders = wc_get_orders( array(
'status' => 'spam',
) );
foreach ( $spam_orders as $spam_order ) {
if ( $address == $spam_order->get_address( 'shipping' ) ) {
$order_id = $_POST['order_id'];
$order = wc_get_order( $order_id );
$order->update_status( 'spam-review' );
echo json_encode( array( 'found' => true ) );
wp_die();
}
}
echo json_encode( array( 'found' => false ) );
wp_die();
}
Of course doesn't work... any suggestion?
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
I am researching more and use the code..
I have done this code.
if (!defined('ABSPATH')) {
die;
}
if(!class_exists('ArtistPublic')):
class ArtistPublic
{
public static function createTemplate( ) {
global $user_ID;
$new_post = array(
'post_title' => 'Artist',
'post_content' => 'hello Artist',
'post_status' => 'publish',
'post_date' => date('Y-m-d H:i:s'),
'post_author' => $user_ID,
'post_type' => 'page',
);
$post_id = wp_insert_post($new_post);
if( !$post_id )
wp_die('Error creating template page');
else
update_post_meta( $post_id, '_wp_page_template', 'artist.php' );
// Filter page template
// add_filter('page_template', 'catch_plugin_template');
}
// Page template filter callback
public static function catch_plugin_template($template) {
if( is_page_template('artist.php') )
$template = WP_PLUGIN_DIR . '/ItgArtist/public/templates/artist.php';
return $template;
}
}
endif;
but create multiple page after refresh.
Is there any good way to create the page like as woocommerce does??
So code be like something
if (!defined('ABSPATH')) {
die;
}
if(!class_exists('ArtistPublic')):
class ArtistPublic {
public static function createTemplate( ) {
if( get_option('artist_page_id') ) :
global $user_ID;
$new_post = array(
'post_title' => 'Artist',
'post_content' => 'hello Artist',
'post_status' => 'publish',
'post_date' => date('Y-m-d H:i:s'),
'post_author' => $user_ID,
'post_type' => 'page',
);
$post_id = wp_insert_post($new_post);
if( !$post_id ) :
wp_die('Error creating template page');
else :
update_option('artist_page_id', $post_id);
update_post_meta( $post_id, '_wp_page_template', 'artist.php' );
endif;
endif;
// Filter page template
// add_filter('page_template', 'catch_plugin_template');
}
// Page template filter callback
public static function catch_plugin_template($template) {
if( is_page_template('artist.php') )
$template = WP_PLUGIN_DIR . '/ItgArtist/public/templates/artist.php';
return $template;
}
}
endif;
I have a custom order status called Shipping Details which will be selected after the Order complete trigger is fired.
Code for the Order Status
function register_shipping_details_status() {
register_post_status( 'wc-shipping-details', array(
'label' => 'Send Shipping Details',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true
//'label_count' => _n_noop( 'Shipping Details <span class="count">(%s)</span>', 'Shipping Details <span class="count">(%s)</span>' )
) );
}
add_action( 'init', 'register_shipping_details_status' );
// Add to list of WC Order statuses
function add_shipping_details_to_order_statuses( $order_statuses ) {
$new_order_statuses = array();
// add new order status after completed
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
if ( 'wc-completed' === $key ) {
$new_order_statuses['wc-shipping-details'] = 'Send Shipping Details';
}
}
return $new_order_statuses;
}
add_filter( 'wc_order_statuses', 'add_shipping_details_to_order_statuses' );
and my email trigger code is here.
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Shipping_Details_Email' ) ) :
/**
* Customer Shipping Details Email
*/
class WC_Shipping_Details_Email extends WC_Email {
/**
* Constructor.
*/
public function __construct() {
$this->id = 'wc_shipping_details';
$this->customer_email = true;
$this->title = __( 'Shipping Details', 'woocommerce' );
$this->description = __( 'Shipping details emails are sent after the order has been marked completed .', 'woocommerce' );
$this->heading = __( 'Shipping Details for your order', 'woocommerce' );
$this->subject = __( 'Shipping details for your order from INAI', 'woocommerce' );
$this->template_html = 'emails/customer-shipping-details.php';
$this->template_plain = 'emails/plain/customer-shipping-details.php';
// Triggers for this email
add_action( 'woocommerce_order_status_shipping_details_notification', array( $this, 'trigger' ) );
// Call parent constuctor
parent::__construct();
}
/**
* Trigger.
*
* #param int $order_id
*/
public function trigger( $order_id ) {
if ( $order_id ) {
$this->object = wc_get_order( $order_id );
$this->recipient = $this->object->billing_email;
$this->find['order-date'] = '{order_date}';
$this->find['order-number'] = '{order_number}';
$this->replace['order-date'] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) );
$this->replace['order-number'] = $this->object->get_order_number();
}
if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
return;
}
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
The action for registering the email
//custom hooks for custom woocommerce order email
function register_custom_order_status_action( $actions ){
$actions[] = 'woocommerce_order_status_shipping_details';
return $actions;
}
add_filter( 'woocommerce_email_actions', 'register_custom_order_status_action' );
For some reason the mail is not getting triggered. I have looked around a lot and even found a few others for whom the problem has been solved. WooCommerce - send custom email on custom order status change.
My code is almost exactly the same, still don't know what i'm missing. Please help.
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',
);