From 77b4638be6468083bc2a48b8c3018795e16bc69d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 17 Oct 2020 08:53:24 +0200 Subject: use phpcbf to fix indentation --- .../class-wc-gnutaler-gateway.php | 1600 +++++++++++--------- 1 file changed, 876 insertions(+), 724 deletions(-) diff --git a/plugin/GNU-Taler-Payment-Gateway/class-wc-gnutaler-gateway.php b/plugin/GNU-Taler-Payment-Gateway/class-wc-gnutaler-gateway.php index 333c987..9559c3c 100644 --- a/plugin/GNU-Taler-Payment-Gateway/class-wc-gnutaler-gateway.php +++ b/plugin/GNU-Taler-Payment-Gateway/class-wc-gnutaler-gateway.php @@ -1,4 +1,6 @@ -GNU Taler requires WooCommerce plugin to work. Please activate it or install it from here.

Back to the WordPress Plugins page.', - 'gnutaler' ), - array( 'strong' => array(), + if (! in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')), true) ) { + deactivate_plugins(plugin_basename(__FILE__)); + wp_die( + sprintf( + wp_kses( + __( + 'GNU Taler requires WooCommerce plugin to work. Please activate it or install it from here.

Back to the WordPress Plugins page.', + 'gnutaler' + ), + array( 'strong' => array(), 'a' => array( 'href' => array(), - '_target' => array() ) ) ), - get_admin_url(null, 'plugins.php') ) ); - } - - /** - * GNU Taler Payment Gateway class. - * - * Handles the payments from the Woocommerce Webshop and sends the transactions to the GNU Taler Backend and the GNU Taler Wallet. - */ - class WC_GNUTaler_Gateway extends WC_Payment_Gateway { + '_target' => array() ) ) + ), + get_admin_url(null, 'plugins.php') + ) + ); + } + + /** + * GNU Taler Payment Gateway class. + * + * Handles the payments from the Woocommerce Webshop and sends the transactions to the GNU Taler Backend and the GNU Taler Wallet. + */ + class WC_GNUTaler_Gateway extends WC_Payment_Gateway + { // plugin logs - private static $logger = false; + private static $logger = false; // is logging enabled? - private static $log_enabled = false; - - /** - * Class constructor - */ - public function __construct(){ - $this->id = 'gnutaler'; // payment gateway plugin ID - $this->logger = new WC_logger ($this->id); // setup logging - $this->icon = plugins_url ( '/assets/images/taler.png', __FILE__ ); + private static $log_enabled = false; + + /** + * Class constructor + */ + public function __construct() + { + $this->id = 'gnutaler'; // payment gateway plugin ID + $this->logger = new WC_logger($this->id); // setup logging + $this->icon = plugins_url('/assets/images/taler.png', __FILE__); // We cannot use custom fields to show the QR code / do the wallet integration as WC doesn't give us the order_id at that time. Bummer. - $this->has_fields = false; + $this->has_fields = false; // The following texts will be displayed on the payment plugins settings page - $this->method_title = 'GNU Taler'; - $this->method_description = __( 'This plugin enables payments via the GNU Taler payment system', 'gnutaler' ); + $this->method_title = 'GNU Taler'; + $this->method_description = __('This plugin enables payments via the GNU Taler payment system', 'gnutaler'); - // This gateway can support refunds, saved payment methods, - $this->supports = array( - 'products', 'refunds', - ); + // This gateway can support refunds, saved payment methods, + $this->supports = array( + 'products', 'refunds', + ); // Setup logging. - $this->debug = 'yes' === $this->get_option( 'debug', 'no' ); + $this->debug = 'yes' === $this->get_option('debug', 'no'); self::$log_enabled = $this->debug; // setup 'form_fields' - $this->form_fields = array( - 'enabled' => array( - 'title' => __( 'Enable/Disable', 'gnutaler' ), - 'label' => __ ( 'Enable GNU Taler Gateway', 'gnutaler' ), - 'type' => 'checkbox', - 'description' => '', - 'default' => 'no', - ), - 'title' => array( - 'title' => __( 'Title', 'gnutaler' ), - 'type' => 'text', - 'description' => __( 'This is what the customer will see when choosing payment methods.', 'gnutaler' ), - 'default' => 'GNU Taler', - 'desc_tip' => true, - ), - 'description' => array( - 'title' => __( 'Description', 'gnutaler' ), - 'type' => 'textarea', - 'description' => __( 'This controls the description for the payment option which the customer sees during checkout.', 'gnutaler' ), - 'default' => __( 'Pay with GNU Taler', 'gnutaler' ), - ), - 'GNU_Taler_Backend_URL' => array( - 'title' => __( 'Taler backend URL', 'gnutaler' ), - 'type' => 'text', - 'description' => __( 'Set the URL of the Taler backend. (Example: https://backend.demo.taler.net/)', 'gnutaler' ), - 'default' => 'http://backend.demo.taler.net/instances/pos/', - ), - 'GNU_Taler_Backend_API_Key' => array( - 'title' => __( 'Taler Backend API Key', 'gnutaler' ), - 'type' => 'text', - 'description' => __( 'Enter your API key to authenticate with the Taler backend.', 'gnutaler' ), - 'default' => 'Sandbox ApiKey', - ), - 'Order_text' => array( - 'title' => __( 'Summary Text of the Order', 'gnutaler' ), - 'type' => 'text', - 'description' => __( 'Set the text the customer will see when confirming payment. %s will be substituted with the order number. (Example: MyShop #%s)', 'gnutaler' ), - 'default' => 'WooTalerShop #%s', - ), - 'GNU_Taler_refund_delay' => array( - 'title' => __( 'How long should refunds be possible', 'gnutaler' ), - 'type' => 'number', - 'description' => __( 'Set the number of days a customer has to request a refund', 'gnutaler' ), - 'default' => '14', - ), - 'debug' => array( - 'title' => __( 'Debug Log', 'woocommerce' ), - 'label' => __( 'Enable logging', 'woocommerce' ), - 'description' => sprintf( __( 'Log GNU Taler events inside %s.', 'gnutaler' ), - '' . WC_Log_Handler_File::get_log_file_path( 'gnutaler' ) . '' ), - 'type' => 'checkbox', - 'default' => 'no' - ) - ); - - // Load the settings. - $this->init_settings(); - $this->title = $this->get_option( 'title' ); - $this->description = $this->get_option( 'description' ); - $this->enabled = $this->get_option( 'enabled' ); - $this->GNU_Taler_Backend_URL = $this->get_option( 'GNU_Taler_Backend_URL' ); + $this->form_fields = array( + 'enabled' => array( + 'title' => __('Enable/Disable', 'gnutaler'), + 'label' => __('Enable GNU Taler Gateway', 'gnutaler'), + 'type' => 'checkbox', + 'description' => '', + 'default' => 'no', + ), + 'title' => array( + 'title' => __('Title', 'gnutaler'), + 'type' => 'text', + 'description' => __('This is what the customer will see when choosing payment methods.', 'gnutaler'), + 'default' => 'GNU Taler', + 'desc_tip' => true, + ), + 'description' => array( + 'title' => __('Description', 'gnutaler'), + 'type' => 'textarea', + 'description' => __('This controls the description for the payment option which the customer sees during checkout.', 'gnutaler'), + 'default' => __('Pay with GNU Taler', 'gnutaler'), + ), + 'GNU_Taler_Backend_URL' => array( + 'title' => __('Taler backend URL', 'gnutaler'), + 'type' => 'text', + 'description' => __('Set the URL of the Taler backend. (Example: https://backend.demo.taler.net/)', 'gnutaler'), + 'default' => 'http://backend.demo.taler.net/instances/pos/', + ), + 'GNU_Taler_Backend_API_Key' => array( + 'title' => __('Taler Backend API Key', 'gnutaler'), + 'type' => 'text', + 'description' => __('Enter your API key to authenticate with the Taler backend.', 'gnutaler'), + 'default' => 'Sandbox ApiKey', + ), + 'Order_text' => array( + 'title' => __('Summary Text of the Order', 'gnutaler'), + 'type' => 'text', + 'description' => __('Set the text the customer will see when confirming payment. %s will be substituted with the order number. (Example: MyShop #%s)', 'gnutaler'), + 'default' => 'WooTalerShop #%s', + ), + 'GNU_Taler_refund_delay' => array( + 'title' => __('How long should refunds be possible', 'gnutaler'), + 'type' => 'number', + 'description' => __('Set the number of days a customer has to request a refund', 'gnutaler'), + 'default' => '14', + ), + 'debug' => array( + 'title' => __('Debug Log', 'woocommerce'), + 'label' => __('Enable logging', 'woocommerce'), + 'description' => sprintf( + __('Log GNU Taler events inside %s.', 'gnutaler'), + '' . WC_Log_Handler_File::get_log_file_path('gnutaler') . '' + ), + 'type' => 'checkbox', + 'default' => 'no' + ) + ); + + // Load the settings. + $this->init_settings(); + $this->title = $this->get_option('title'); + $this->description = $this->get_option('description'); + $this->enabled = $this->get_option('enabled'); + $this->GNU_Taler_Backend_URL = $this->get_option('GNU_Taler_Backend_URL'); // remove trailing '/', we add one always ourselves... - if (substr($this->GNU_Taler_Backend_URL, -1) == '/') { - $this->GNU_Taler_Backend_URL = substr ($this->GNU_Taler_Backend_URL, 0, -1); - } + if (substr($this->GNU_Taler_Backend_URL, -1) == '/') { + $this->GNU_Taler_Backend_URL = substr($this->GNU_Taler_Backend_URL, 0, -1); + } // Make transaction ID a link. We use the public version // here, as a user clicking on the link could not supply @@ -196,39 +212,48 @@ function gnutaler_init_gateway_class(){ $this->view_transaction_url = $this->GNU_Taler_Backend_URL . '/orders/%s'; // Register handler for the fulfillment URL - $hname = 'woocommerce_api_' . strtolower( get_class( $this ) ); - add_action( $hname, - array( &$this, 'fulfillment_url_handler' ) ); - - // This action hook saves the settings - add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, - array( $this, 'process_admin_options' ) ); + $hname = 'woocommerce_api_' . strtolower(get_class($this)); + add_action( + $hname, + array( &$this, 'fulfillment_url_handler' ) + ); + + // This action hook saves the settings + add_action( + 'woocommerce_update_options_payment_gateways_' . $this->id, + array( $this, 'process_admin_options' ) + ); // Modify WC canonical refund e-mail notifications to add link to order status page. // (according to https://www.businessbloomer.com/woocommerce-add-extra-content-order-email/) - add_action( 'woocommerce_email_before_order_table', - array ($this, 'add_content_refund_email'), - 20, - 4 ); + add_action( + 'woocommerce_email_before_order_table', + array ($this, 'add_content_refund_email'), + 20, + 4 + ); - } + } /** * Called when WC sends out the e-mail notification for refunds. * Adds a Taler-specific notice for where to click to obtain * the refund. */ - function add_content_refund_email( $wc_order, $sent_to_admin, $plain_text, $email ){ - if ( $email->id == 'customer_refunded_order' ) { - $backend_url = $this->GNU_Taler_Backend_URL; - $wc_order_id = $wc_order->get_order_key() . '-' . $wc_order->get_order_number(); - $refund_url = $wc_order->get_meta ('GNU_TALER_REFUND_URL'); - echo sprintf ( __( 'Refund granted. Visit %s to obtain the refund.', 'gnutaler' ), - $refund_url, - $refund_url); - } - } + function add_content_refund_email( $wc_order, $sent_to_admin, $plain_text, $email ) + { + if ($email->id == 'customer_refunded_order' ) { + $backend_url = $this->GNU_Taler_Backend_URL; + $wc_order_id = $wc_order->get_order_key() . '-' . $wc_order->get_order_number(); + $refund_url = $wc_order->get_meta('GNU_TALER_REFUND_URL'); + echo sprintf( + __('Refund granted. Visit %s to obtain the refund.', 'gnutaler'), + $refund_url, + $refund_url + ); + } + } /** * Processes and saves options. @@ -237,176 +262,202 @@ function gnutaler_init_gateway_class(){ * * @return bool was anything saved? */ - public function process_admin_options(){ - $saved = parent::process_admin_options(); - - // Maybe clear logs. - if ( 'yes' !== $this->get_option( 'debug', 'no' ) ) { - if ( empty( self::$log ) ) { - self::$log = wc_get_logger(); - } - self::$log->clear( 'gnutaler' ); - } - - return $saved; + public function process_admin_options() + { + $saved = parent::process_admin_options(); + + // Maybe clear logs. + if ('yes' !== $this->get_option('debug', 'no') ) { + if (empty(self::$log) ) { + self::$log = wc_get_logger(); } - - - public function payment_fields(){ - // We do not have any. + self::$log->clear('gnutaler'); + } + + return $saved; + } + + + public function payment_fields() + { + // We do not have any. + } + + /** + * Callback is called, when the user goes to the fulfillment URL. + * + * We check that the payment actually was made, and update WC accordingly. + * If the order ID is unknown and/or the payment did not succeed, we + * redirect to the home page and/or the user's order page (for logged in users). + */ + function fulfillment_url_handler(): void + { + global $woocommerce; + + if (! isset($_GET['order_id']) ) { + $this->debug(__("Lacking 'order_id', forwarding user to neutral page", 'gnutaler')); + if (is_user_logged_in() ) { + wp_redirect(get_home_url() . wc_get_page_permalink('myaccount')); } - - /** - * Callback is called, when the user goes to the fulfillment URL. - * - * We check that the payment actually was made, and update WC accordingly. - * If the order ID is unknown and/or the payment did not succeed, we - * redirect to the home page and/or the user's order page (for logged in users). - */ - function fulfillment_url_handler(): void { - global $woocommerce; - - if (! isset( $_GET['order_id'] ) ) { - $this->debug( __( "Lacking 'order_id', forwarding user to neutral page", 'gnutaler' ) ); - if ( is_user_logged_in() ) { - wp_redirect( get_home_url() . wc_get_page_permalink( 'myaccount' )); - } - else { - wp_redirect( get_home_url() . wc_get_page_permalink( 'shop' )); - } - exit; - } - - // Gets the order id from the fulfillment url - $taler_order_id = $_GET['order_id']; - $order_id_array = explode( '-', $taler_order_id ); - $order_id_name = $order_id_array[0]; - $order_id = $order_id_array[1]; - $wc_order = wc_get_order( $order_id ); - $backend_url = $this->GNU_Taler_Backend_URL; - - $payment_confirmation = $this->call_api( 'GET', - $backend_url . "/private/orders/" . $taler_order_id, - false ); - $payment_body = $payment_confirmation['message']; - $payment_http_status = $payment_confirmation['http_code']; - - switch ($payment_http_status) { - case 200: - // Here we check what kind of http code came back from the backend - $merchant_order_status_response = json_decode( $payment_body, - $assoc=true ); - if (! $merchant_order_status_response ) { - wc_add_notice( __('Payment error:', 'gnutaler' ) . - __('backend did not respond', 'gnutaler' ) ); - $this->notice( __('Payment failed: no reply from Taler backend', 'gnutaler' ) ); - wp_redirect( $this->get_return_url ($order_id) ); + else { + wp_redirect(get_home_url() . wc_get_page_permalink('shop')); + } + exit; + } + + // Gets the order id from the fulfillment url + $taler_order_id = $_GET['order_id']; + $order_id_array = explode('-', $taler_order_id); + $order_id_name = $order_id_array[0]; + $order_id = $order_id_array[1]; + $wc_order = wc_get_order($order_id); + $backend_url = $this->GNU_Taler_Backend_URL; + + $payment_confirmation = $this->call_api( + 'GET', + $backend_url . "/private/orders/" . $taler_order_id, + false + ); + $payment_body = $payment_confirmation['message']; + $payment_http_status = $payment_confirmation['http_code']; + + switch ($payment_http_status) { + case 200: + // Here we check what kind of http code came back from the backend + $merchant_order_status_response = json_decode( + $payment_body, + $assoc = true + ); + if (! $merchant_order_status_response ) { + wc_add_notice( + __('Payment error:', 'gnutaler') . + __('backend did not respond', 'gnutaler') + ); + $this->notice(__('Payment failed: no reply from Taler backend', 'gnutaler')); + wp_redirect($this->get_return_url($order_id)); exit; - } - if ('paid' == $merchant_order_status_response['order_status']) { - $this->notice( __('Payment succeeded and the user was forwarded to the order confirmed page', 'gnutaler' ) ); - // Completes the order, storing a transaction ID - $wc_order->payment_complete ( $taler_order_id ); - // Empties the shopping cart - WC()->cart->empty_cart(); - } - else { - wc_add_notice( __('Payment error:', 'gnutaler' ) . - __('backend did not confirm payment', 'gnutaler' ) ); - $this->notice( __('Backend did not confirm payment', 'gnutaler' ) ); - } - wp_redirect( $this->get_return_url( $wc_order) ); - exit; - default: - $this->error( __( 'An error occurred during the second request to the GNU Taler backend: ', 'gnutaler') - . $payment_http_status . ' - ' . $payment_body ); - wc_add_notice( __('Payment error:', 'gnutaler' ) . $payment_http_status . ' - ' . $payment_body ); - wp_redirect( $this->get_return_url( $order_id ) ); - break; - } // end 'switch ($payment_http_status) - $cart_url = $woocommerce->cart->wc_get_cart_url(); - if (is_set( $cart_url )) { - wp_redirect( get_home_url() . $cart_url ); - } - else { - wp_redirect( wc_get_page_permalink ('shop') ); - } - exit; - } - - - /** - * Sends a request to a url via HTTP. - * - * Sends a request to a GNU Taler Backend over HTTP and returns the result. - * The request can be sent as POST, GET, PUT or another method. - * - * @param $method - POST, GET, PUT or another method. - * @param $url - URL for the request to make to the GNU Taler Backend. - * @param $body - The content of the request (for POST). - * @return array The return array will either have the successful return value or a detailed error message. - */ - function call_api( $method, $url, $body ): array { - $curl = curl_init(); - switch ( $method ) { - case 'POST': - curl_setopt( $curl, CURLOPT_POST, 1 ); - break; - case 'PUT': - curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, 'PUT' ); - break; - case 'PATCH': - curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, 'PATCH' ); - break; - case 'GET': - break; - default: - curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, $method ); - break; - } - if ( $body ) { - $jsonstr = json_encode ($body, JSON_UNESCAPED_SLASHES ); - $this->debug( "Using POST body " . $jsonstr . " for upload to " . $url ); - curl_setopt( $curl, - CURLOPT_POSTFIELDS, - $jsonstr ); - } else { - $this->debug( "No request body with " . $method . " to " . $url ); - } - $this->debug( "Requesting URL " . $url ); - curl_setopt( $curl, CURLOPT_URL, $url ); - $apikey = $this->get_option( 'GNU_Taler_Backend_API_Key' ); - curl_setopt( $curl, CURLOPT_HTTPHEADER, array( - 'Authorization: ' . $apikey, - 'Content-Type: application/json', - ) ); - curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 ); - curl_setopt ($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ); - - $result = curl_exec( $curl ); - - $http_code = curl_getinfo( $curl, CURLINFO_HTTP_CODE ); - if ( curl_error( $curl ) ) { - $error_msg = curl_error( $curl ); - $this->warning( sprintf( __( 'CURL failure %1$s with HTTP status %2$s', 'gnutaler' ), - $error_msg, - $http_code ) ); - - return array( - 'http_code' => $http_code, - 'message' => $error_msg, - ); - } - $this->debug ( sprintf( __( 'HTTP status %1$s with response body %2$s', 'gnutaler' ), - $http_code, - $result ) ); - $message_array = array( - 'http_code' => $http_code, - 'message' => $result, - ); - curl_close( $curl ); - return $message_array; - } + } + if ('paid' == $merchant_order_status_response['order_status']) { + $this->notice(__('Payment succeeded and the user was forwarded to the order confirmed page', 'gnutaler')); + // Completes the order, storing a transaction ID + $wc_order->payment_complete($taler_order_id); + // Empties the shopping cart + WC()->cart->empty_cart(); + } + else { + wc_add_notice( + __('Payment error:', 'gnutaler') . + __('backend did not confirm payment', 'gnutaler') + ); + $this->notice(__('Backend did not confirm payment', 'gnutaler')); + } + wp_redirect($this->get_return_url($wc_order)); + exit; + default: + $this->error( + __('An error occurred during the second request to the GNU Taler backend: ', 'gnutaler') + . $payment_http_status . ' - ' . $payment_body + ); + wc_add_notice(__('Payment error:', 'gnutaler') . $payment_http_status . ' - ' . $payment_body); + wp_redirect($this->get_return_url($order_id)); + break; + } // end 'switch ($payment_http_status) + $cart_url = $woocommerce->cart->wc_get_cart_url(); + if (is_set($cart_url)) { + wp_redirect(get_home_url() . $cart_url); + } + else { + wp_redirect(wc_get_page_permalink('shop')); + } + exit; + } + + + /** + * Sends a request to a url via HTTP. + * + * Sends a request to a GNU Taler Backend over HTTP and returns the result. + * The request can be sent as POST, GET, PUT or another method. + * + * @param $method - POST, GET, PUT or another method. + * @param $url - URL for the request to make to the GNU Taler Backend. + * @param $body - The content of the request (for POST). + * @return array The return array will either have the successful return value or a detailed error message. + */ + function call_api( $method, $url, $body ): array + { + $curl = curl_init(); + switch ( $method ) { + case 'POST': + curl_setopt($curl, CURLOPT_POST, 1); + break; + case 'PUT': + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + break; + case 'PATCH': + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH'); + break; + case 'GET': + break; + default: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + break; + } + if ($body ) { + $jsonstr = json_encode($body, JSON_UNESCAPED_SLASHES); + $this->debug("Using POST body " . $jsonstr . " for upload to " . $url); + curl_setopt( + $curl, + CURLOPT_POSTFIELDS, + $jsonstr + ); + } else { + $this->debug("No request body with " . $method . " to " . $url); + } + $this->debug("Requesting URL " . $url); + curl_setopt($curl, CURLOPT_URL, $url); + $apikey = $this->get_option('GNU_Taler_Backend_API_Key'); + curl_setopt( + $curl, CURLOPT_HTTPHEADER, array( + 'Authorization: ' . $apikey, + 'Content-Type: application/json', + ) + ); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + + $result = curl_exec($curl); + + $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); + if (curl_error($curl) ) { + $error_msg = curl_error($curl); + $this->warning( + sprintf( + __('CURL failure %1$s with HTTP status %2$s', 'gnutaler'), + $error_msg, + $http_code + ) + ); + + return array( + 'http_code' => $http_code, + 'message' => $error_msg, + ); + } + $this->debug( + sprintf( + __('HTTP status %1$s with response body %2$s', 'gnutaler'), + $http_code, + $result + ) + ); + $message_array = array( + 'http_code' => $http_code, + 'message' => $result, + ); + curl_close($curl); + return $message_array; + } /** @@ -414,448 +465,549 @@ function gnutaler_init_gateway_class(){ * the admin to the setup dialog if they enable the backend and * it is not properly configured. */ - public function needs_setup(){ - $backend_url = $this->GNU_Taler_Backend_URL; - return ! $this->verify_backend_url( $backend_url, - null); + public function needs_setup() + { + $backend_url = $this->GNU_Taler_Backend_URL; + return ! $this->verify_backend_url( + $backend_url, + null + ); + } + + + /** + * Verifying if the url to the backend given in the plugin options is valid or not. + * + * @param $url - URL to the backend + * @param $ecurrency - expected currency of the order + * @return bool - Returns if valid or not. + */ + function verify_backend_url( $url, $ecurrency ): bool + { + $config = $this->call_api('GET', $url . '/config', false); + $config_http_status = $config['http_code']; + $config_body = $config['message']; + switch ($config_http_status) + { + case 200: + $info = json_decode($config_body, $assoc = true); + if (! $info) { + $this->error( + sprintf( + __("/config response of backend at %s did not decode as JSON", 'gnutaler'), + $url + ) + ); + return false; } - - - /** - * Verifying if the url to the backend given in the plugin options is valid or not. - * - * @param $url - URL to the backend - * @param $ecurrency - expected currency of the order - * @return bool - Returns if valid or not. - */ - function verify_backend_url( $url, $ecurrency ): bool { - $config = $this->call_api( 'GET', $url . '/config', false); - $config_http_status = $config['http_code']; - $config_body = $config['message']; - switch ($config_http_status) - { - case 200: - $info = json_decode ($config_body, $assoc=true); - if (! $info) { - $this->error( sprintf( __("/config response of backend at %s did not decode as JSON", 'gnutaler' ), - $url ) ); - return false; - } - $version = $info['version']; - if (! $version) { - $this->error( sprintf( __( "No 'version' field in /config reply from Taler backend at %s", 'gnutaler' ), - $url ) ); - return false; - } - $ver = explode (":", $version, 3); - $current = $ver[0]; - $revision = $ver[1]; - $age = $ver[2]; - if ( (! is_numeric ($current)) || - (! is_numeric ($revision)) || - (! is_numeric ($age)) ) { - $this->error( sprintf( __( "/config response at backend malformed: '%s' is not a valid version", 'gnutaler'), - $version ) ); - return false; - } - if (MERCHANT_PROTOCOL_CURRENT < $current - $age) { - // Our implementation is too old! - $this->error( sprintf( __( "Backend protocol version %s is too new: please update the GNU Taler plugin", 'gnutaler' ), - $version ) ); - return false; - } - if (MERCHANT_PROTOCOL_CURRENT - MERCHANT_PROTOCOL_AGE > $current) { - // Merchant implementation is too old! - $this->error( sprintf( __( "Backend protocol version %s unsupported: please update the backend", 'gnutaler' ), - $version ) ); - return false; - } - $currency = $info['currency']; - if ( (! is_null( $ecurrency )) && - (0 != strcasecmp( $currency, $ecurrency )) ) { - $this->error( sprintf( __('Backend currency %1$s does not match order currency %2$s', 'gnutaler' ), - $currency, - $ecurrency ) ); - return false; - } - $this->debug( sprintf( __("/config check for Taler backend at %s succeeded", 'gnutaler'), - $url ) ); - return true; - default: - $this->error( sprintf( __("Backend failed /config request with unexpected HTTP status %s", 'gnutaler'), - $config_http_status ) ); - return false; - } - } - - /** - * Processes the payment after the checkout - * - * If the payment process finished successfully the user is being redirected to its GNU Taler Wallet. - * If an error occurs it returns void and throws an error. - * - * @param $order_id - ID of the order to get the Order from the WooCommerce Webshop - * @return array|void - Array with result => success and redirection url otherwise it returns void. - */ - public function process_payment( $order_id ){ - // we need it to get any order detailes - $wc_order = wc_get_order( $order_id ); - - // Gets the url of the backend from the WooCommerce Settings + $version = $info['version']; + if (! $version) { + $this->error( + sprintf( + __("No 'version' field in /config reply from Taler backend at %s", 'gnutaler'), + $url + ) + ); + return false; + } + $ver = explode(":", $version, 3); + $current = $ver[0]; + $revision = $ver[1]; + $age = $ver[2]; + if ((! is_numeric($current)) + || (! is_numeric($revision)) + || (! is_numeric($age)) + ) { + $this->error( + sprintf( + __("/config response at backend malformed: '%s' is not a valid version", 'gnutaler'), + $version + ) + ); + return false; + } + if (MERCHANT_PROTOCOL_CURRENT < $current - $age) { + // Our implementation is too old! + $this->error( + sprintf( + __("Backend protocol version %s is too new: please update the GNU Taler plugin", 'gnutaler'), + $version + ) + ); + return false; + } + if (MERCHANT_PROTOCOL_CURRENT - MERCHANT_PROTOCOL_AGE > $current) { + // Merchant implementation is too old! + $this->error( + sprintf( + __("Backend protocol version %s unsupported: please update the backend", 'gnutaler'), + $version + ) + ); + return false; + } + $currency = $info['currency']; + if ((! is_null($ecurrency)) + && (0 != strcasecmp($currency, $ecurrency)) + ) { + $this->error( + sprintf( + __('Backend currency %1$s does not match order currency %2$s', 'gnutaler'), + $currency, + $ecurrency + ) + ); + return false; + } + $this->debug( + sprintf( + __("/config check for Taler backend at %s succeeded", 'gnutaler'), + $url + ) + ); + return true; + default: + $this->error( + sprintf( + __("Backend failed /config request with unexpected HTTP status %s", 'gnutaler'), + $config_http_status + ) + ); + return false; + } + } + + /** + * Processes the payment after the checkout + * + * If the payment process finished successfully the user is being redirected to its GNU Taler Wallet. + * If an error occurs it returns void and throws an error. + * + * @param $order_id - ID of the order to get the Order from the WooCommerce Webshop + * @return array|void - Array with result => success and redirection url otherwise it returns void. + */ + public function process_payment( $order_id ) + { + // we need it to get any order detailes + $wc_order = wc_get_order($order_id); + + // Gets the url of the backend from the WooCommerce Settings $backend_url = $this->GNU_Taler_Backend_URL; - //Log entry that the customer started the payment process - $this->info( __( 'User started the payment process with GNU Taler.', 'gnutaler' ) ); - - if ( ! $this->verify_backend_url( $backend_url, $wc_order->get_currency() ) ) { - wc_add_notice( __('Something went wrong please contact the system administrator of the webshop and send the following error: GNU Taler backend URL invalid', 'gnutaler'), 'error' ); - $this->error( __('Checkout process failed: Invalid backend url.', 'gnutaler' ) ); - return; - } - $order_json = $this->convert_to_checkout_json( $order_id ); - - $this->info( __( 'Sending POST /private/orders request send to Taler backend', 'gnutaler' ) ); - $order_confirmation = $this->call_api( 'POST', - $backend_url . '/private/orders', - $order_json); - $order_body = $order_confirmation['message']; - $order_http_status = $order_confirmation['http_code']; - switch ($order_http_status) - { - case 200: - $post_order_response = json_decode( $order_body, $assoc=true ); - if (! $post_order_response ) { - $this->error( __('POST /private/orders request to Taler backend returned 200 OK, but not a JSON body: ', 'gnutaler' ) - . $order_body ); - wc_add_notice( __( 'Malformed response from Taler backend. Please contact the system administrator.' ) ); - $wc_order->set_status( 'cancelled' ); - return; - } - $taler_order_id = $post_order_response ['order_id']; - $taler_order_token = $post_order_response ['token']; - if (! $taler_order_id) { - $this->error( __('Response to POST /private/orders request to Taler backend lacks order_id field: ', 'gnutaler' ) - . $order_body ); - wc_add_notice( __('Malformed response from Taler backend. Please contact the system administrator.', 'gnutaler' ) ); - $wc_order->set_status( 'cancelled' ); - return; - } - $this->info( __('POST /private/orders successful. Redirecting user to Taler Backend.', 'gnutaler') ); - return array( - 'result' => 'success', - 'redirect' => $backend_url . "/orders/" . $taler_order_id . "?token=" . $taler_order_token, - ); - case 404: - $post_order_error = json_decode ($order_body, $assoc=true); - if (! $post_order_error ) { - $this->error( __( 'POST /private/orders request to Taler backend returned 404, but not a JSON body: ', 'gnutaler' ) - . $order_body ); - wc_add_notice( __( 'Malformed response from Taler backend. Please contact the system administrator.', 'gnutaler' ) ); - $wc_order->set_status( 'cancelled' ); - return; - } - $this->error( __('POST /private/orders request to Taler backend failed: ', 'gnutaler') + //Log entry that the customer started the payment process + $this->info(__('User started the payment process with GNU Taler.', 'gnutaler')); + + if (! $this->verify_backend_url($backend_url, $wc_order->get_currency()) ) { + wc_add_notice(__('Something went wrong please contact the system administrator of the webshop and send the following error: GNU Taler backend URL invalid', 'gnutaler'), 'error'); + $this->error(__('Checkout process failed: Invalid backend url.', 'gnutaler')); + return; + } + $order_json = $this->convert_to_checkout_json($order_id); + + $this->info(__('Sending POST /private/orders request send to Taler backend', 'gnutaler')); + $order_confirmation = $this->call_api( + 'POST', + $backend_url . '/private/orders', + $order_json + ); + $order_body = $order_confirmation['message']; + $order_http_status = $order_confirmation['http_code']; + switch ($order_http_status) + { + case 200: + $post_order_response = json_decode($order_body, $assoc = true); + if (! $post_order_response ) { + $this->error( + __('POST /private/orders request to Taler backend returned 200 OK, but not a JSON body: ', 'gnutaler') + . $order_body + ); + wc_add_notice(__('Malformed response from Taler backend. Please contact the system administrator.')); + $wc_order->set_status('cancelled'); + return; + } + $taler_order_id = $post_order_response ['order_id']; + $taler_order_token = $post_order_response ['token']; + if (! $taler_order_id) { + $this->error( + __('Response to POST /private/orders request to Taler backend lacks order_id field: ', 'gnutaler') + . $order_body + ); + wc_add_notice(__('Malformed response from Taler backend. Please contact the system administrator.', 'gnutaler')); + $wc_order->set_status('cancelled'); + return; + } + $this->info(__('POST /private/orders successful. Redirecting user to Taler Backend.', 'gnutaler')); + return array( + 'result' => 'success', + 'redirect' => $backend_url . "/orders/" . $taler_order_id . "?token=" . $taler_order_token, + ); + case 404: + $post_order_error = json_decode($order_body, $assoc = true); + if (! $post_order_error ) { + $this->error( + __('POST /private/orders request to Taler backend returned 404, but not a JSON body: ', 'gnutaler') + . $order_body + ); + wc_add_notice(__('Malformed response from Taler backend. Please contact the system administrator.', 'gnutaler')); + $wc_order->set_status('cancelled'); + return; + } + $this->error( + __('POST /private/orders request to Taler backend failed: ', 'gnutaler') . $post_order_error['code'] . '(' - . $order_http_status . '): ' . $order_body ); - wc_add_notice( __( 'Taler backend not configured correctly. Please contact the system administrator.', 'gnutaler' ) ); - $wc_order->set_status( 'cancelled' ); - return; - case 410: - // We don't use inventory management via GNU Taler's backend, so this error should never apply. - // Handle with 'default' case below. - default: - $this->error( __('POST /private/orders request to Taler backend failed: ', 'gnutaler' ) - . $post_order_error['code'] . '(' - . $order_http_status . '): ' - . $order_body ); - wc_add_notice( __( 'Unexpected problem with the Taler backend. Please contact the system administrator.', 'gnutaler' ) ); - $wc_order->set_status( 'cancelled' ); - return; - } // end switch ($order_http_status) - } - - - /** - * Converts the order into a JSON format that can be send to the GNU Taler Backend. - * - * @param $order_id - To get the order from the WooCommerce Webshop - * @return array - return the JSON Format. - */ - public function convert_to_checkout_json( $order_id ): array { - $wc_order = wc_get_order( $order_id ); - $wc_order_total_amount = $wc_order->get_total(); - $wc_order_currency = $wc_order->get_currency(); - $wc_cart = WC()->cart->get_cart(); - $wc_order_id = $wc_order->get_order_key() . '-' . $wc_order->get_order_number(); - $wc_order_products_array = $this->mutate_products_to_json_format( $wc_cart, $wc_order_currency, $wc_order ); - $refund_delay = $this->get_option( 'GNU_Taler_refund_delay' ); - $order_json = array( - 'order' => array( - 'amount' => $wc_order_currency . ':' . $wc_order_total_amount, - 'summary' => sprintf( $this->get_option( 'Order_text' ), - $wc_order->get_order_number() ), - // NOTE: This interacts with the 'add_action' call + . $order_http_status . '): ' . $order_body + ); + wc_add_notice(__('Taler backend not configured correctly. Please contact the system administrator.', 'gnutaler')); + $wc_order->set_status('cancelled'); + return; + case 410: + // We don't use inventory management via GNU Taler's backend, so this error should never apply. + // Handle with 'default' case below. + default: + $this->error( + __('POST /private/orders request to Taler backend failed: ', 'gnutaler') + . $post_order_error['code'] . '(' + . $order_http_status . '): ' + . $order_body + ); + wc_add_notice(__('Unexpected problem with the Taler backend. Please contact the system administrator.', 'gnutaler')); + $wc_order->set_status('cancelled'); + return; + } // end switch ($order_http_status) + } + + + /** + * Converts the order into a JSON format that can be send to the GNU Taler Backend. + * + * @param $order_id - To get the order from the WooCommerce Webshop + * @return array - return the JSON Format. + */ + public function convert_to_checkout_json( $order_id ): array + { + $wc_order = wc_get_order($order_id); + $wc_order_total_amount = $wc_order->get_total(); + $wc_order_currency = $wc_order->get_currency(); + $wc_cart = WC()->cart->get_cart(); + $wc_order_id = $wc_order->get_order_key() . '-' . $wc_order->get_order_number(); + $wc_order_products_array = $this->mutate_products_to_json_format($wc_cart, $wc_order_currency, $wc_order); + $refund_delay = $this->get_option('GNU_Taler_refund_delay'); + $order_json = array( + 'order' => array( + 'amount' => $wc_order_currency . ':' . $wc_order_total_amount, + 'summary' => sprintf( + $this->get_option('Order_text'), + $wc_order->get_order_number() + ), + // NOTE: This interacts with the 'add_action' call // to invoke the 'fulfillment_url_handler' when the // user goes to this URL! - 'fulfillment_url' => get_home_url() + 'fulfillment_url' => get_home_url() . '/?wc-api=' - . strtolower( get_class( $this ) ) + . strtolower(get_class($this)) . '&order_id=' . $wc_order_id, - 'order_id' => $wc_order_id, - 'products' => $wc_order_products_array, - 'delivery_location' => $this->mutate_shipping_information_to_json_format( $wc_order ), - ), - ); - if (isset ($refund_delay)) { - $order_json['refund_delay'] = array ( - 'd_ms' => 1000 * 60 * 60 * 24 * intval ($refund_delay) - ); - } - return $order_json; - } - - /** - * Mutates the products in the cart into a format which can be included in a JSON file. - * - * @param $wc_cart - The content of the WooCommerce Cart. - * @param $wc_order_currency - The currency the WooCommerce Webshop uses. - * @return array - Returns an array of products. - */ - function mutate_products_to_json_format( $wc_cart, $wc_order_currency, $wc_order ): array { - $wc_order_products_array = array(); - foreach ( $wc_cart as $product ) { - $wc_order_products_array[] = array( - 'description' => $product['data']->get_title(), - 'quantity' => $product['quantity'], - 'price' => $wc_order_currency . ':' . $product['data']->get_price(), - 'product_id' => strval( $product['data']->get_id() ), - ); - } - return $wc_order_products_array; - } - - - /** - * Processes the refund transaction if requested by the system administrator of the webshop - * - * If the refund request is finished successfully it returns an refund url, which can be send to the customer to finish the refund transaction. - * If an error it will throw a WP_Error message and inform the system administrator. - * - * @param $wc_order - * @return array - */ - function mutate_shipping_information_to_json_format($wc_order): array { - $whitechar_encounter = false; - $shipping_address_street = ''; - $shipping_address_streetNr = ''; - - $store_address = $wc_order->get_shipping_address_1(); - $store_address_inverted = strrev( $store_address ); - $store_address_array = str_split( $store_address_inverted ); - - // Split the address into street and street number - foreach ( $store_address_array as $char ) { - if ( ! $whitechar_encounter ) { - $shipping_address_street .= $char; - } - elseif ( ctype_space( $char ) ) { - $whitechar_encounter = true; - } - else { - $shipping_address_street .= $char; - } - } - $ret = array( - 'country' => $wc_order->get_shipping_country(), - 'country_subdivision' => $wc_order->get_shipping_state(), - 'town' => $wc_order->get_shipping_city(), - 'post_code' => $wc_order->get_shipping_postcode(), - 'street' => $shipping_address_street, - 'building_number' => $shipping_address_streetNr, - ); - if (null !== $wc_order->get_shipping_address_2()) - { - $address_lines = array( $wc_order->get_shipping_address_1(), - $wc_order->get_shipping_address_2() ); - $ret['address_lines'] = $address_lines; - } + 'order_id' => $wc_order_id, + 'products' => $wc_order_products_array, + 'delivery_location' => $this->mutate_shipping_information_to_json_format($wc_order), + ), + ); + if (isset($refund_delay)) { + $order_json['refund_delay'] = array ( + 'd_ms' => 1000 * 60 * 60 * 24 * intval($refund_delay) + ); + } + return $order_json; + } + + /** + * Mutates the products in the cart into a format which can be included in a JSON file. + * + * @param $wc_cart - The content of the WooCommerce Cart. + * @param $wc_order_currency - The currency the WooCommerce Webshop uses. + * @return array - Returns an array of products. + */ + function mutate_products_to_json_format( $wc_cart, $wc_order_currency, $wc_order ): array + { + $wc_order_products_array = array(); + foreach ( $wc_cart as $product ) { + $wc_order_products_array[] = array( + 'description' => $product['data']->get_title(), + 'quantity' => $product['quantity'], + 'price' => $wc_order_currency . ':' . $product['data']->get_price(), + 'product_id' => strval($product['data']->get_id()), + ); + } + return $wc_order_products_array; + } + + + /** + * Processes the refund transaction if requested by the system administrator of the webshop + * + * If the refund request is finished successfully it returns an refund url, which can be send to the customer to finish the refund transaction. + * If an error it will throw a WP_Error message and inform the system administrator. + * + * @param $wc_order + * @return array + */ + function mutate_shipping_information_to_json_format($wc_order): array + { + $whitechar_encounter = false; + $shipping_address_street = ''; + $shipping_address_streetNr = ''; + + $store_address = $wc_order->get_shipping_address_1(); + $store_address_inverted = strrev($store_address); + $store_address_array = str_split($store_address_inverted); + + // Split the address into street and street number + foreach ( $store_address_array as $char ) { + if (! $whitechar_encounter ) { + $shipping_address_street .= $char; + } + elseif (ctype_space($char) ) { + $whitechar_encounter = true; + } + else { + $shipping_address_street .= $char; + } + } + $ret = array( + 'country' => $wc_order->get_shipping_country(), + 'country_subdivision' => $wc_order->get_shipping_state(), + 'town' => $wc_order->get_shipping_city(), + 'post_code' => $wc_order->get_shipping_postcode(), + 'street' => $shipping_address_street, + 'building_number' => $shipping_address_streetNr, + ); + if (null !== $wc_order->get_shipping_address_2()) { + $address_lines = array( $wc_order->get_shipping_address_1(), + $wc_order->get_shipping_address_2() ); + $ret['address_lines'] = $address_lines; + } return $ret; - } - - - /** - * Processes the refund transaction if requested by the system administrator of the webshop - * - * If the refund request is finished successfully it returns an refund url, which can be send to the customer to finish the refund transaction. - * If an error it will throw a WP_Error message and inform the system administrator. - * - * @param $order_id - Order id for logging. - * @param null $amount - Amount that is requested to be refunded. - * @param string $reason - Reason for the refund request. - * @return bool|WP_Error - Returns true or throws an WP_Error message in case of error. - */ - public function process_refund( $order_id, $amount = null, $reason = '' ){ - $wc_order = wc_get_order( $order_id ); + } + + + /** + * Processes the refund transaction if requested by the system administrator of the webshop + * + * If the refund request is finished successfully it returns an refund url, which can be send to the customer to finish the refund transaction. + * If an error it will throw a WP_Error message and inform the system administrator. + * + * @param $order_id - Order id for logging. + * @param null $amount - Amount that is requested to be refunded. + * @param string $reason - Reason for the refund request. + * @return bool|WP_Error - Returns true or throws an WP_Error message in case of error. + */ + public function process_refund( $order_id, $amount = null, $reason = '' ) + { + $wc_order = wc_get_order($order_id); /* translators: first argument is numeric amount, second argument the name of the currency ("EUR", "USD"), and third the reason. */ - $this->info( sprintf( __( 'Refund process started with the refunded amount %1$s %2$s and the reason %3$s.'), - $amount, - $wc_order->get_currency(), - $reason ) ); - - // Gets the url of the backend from the WooCommerce Settings - $backend_url = $this->GNU_Taler_Backend_URL; - - //Get the current status of the order - $wc_order_status = $wc_order->get_status(); - - // Checks if current status is already set as paid - if (! ( $wc_order_status === 'processing' || - $wc_order_status === 'on hold' || - $wc_order_status === 'completed' ) ) { - $this->error( __( 'The status of the order does not allow a refund', 'gnutaler' ) ); - return new WP_Error( 'error', __('The status of the order does not allow for a refund.', 'gnutaler' ) ); - } - - $refund_request = array( - 'refund' => $wc_order->get_currency() . ':' . $amount, - 'reason' => $reason, - ); - $wc_order_id = $wc_order->get_order_key() . '-' . $wc_order->get_order_number(); - $refund_result = $this->call_api( 'POST', - $backend_url . '/private/orders/' . $wc_order_id . '/refund', - $refund_request); - - $refund_http_status = $refund_result['http_code']; - $refund_body = $refund_result['message']; - switch ($refund_http_status) - { - case 200: - $refund_response = json_decode ($refund_body, $assoc=true); - if (! $refund_response) { - $this->error( __( 'Malformed 200 response from Taler backend: not even in JSON', 'gnutaler' ) ); - return new WP_Error( 'error', __( 'Malformed response from Taler backend', 'gnutaler' ) ); - } - $refund_uri = $refund_response['taler_refund_uri']; - $h_contract = $refund_response['h_contract']; - if ( (! $refund_uri) || - (! $h_contract) ) { - $this->error( __( 'Malformed 200 response from Taler backend: lacks taler_refund_uri', 'gnutaler' ) ); - return new WP_Error( 'error', __( 'Malformed response from Taler backend', 'gnutaler' ) ); - } + $this->info( + sprintf( + __('Refund process started with the refunded amount %1$s %2$s and the reason %3$s.'), + $amount, + $wc_order->get_currency(), + $reason + ) + ); + + // Gets the url of the backend from the WooCommerce Settings + $backend_url = $this->GNU_Taler_Backend_URL; + + //Get the current status of the order + $wc_order_status = $wc_order->get_status(); + + // Checks if current status is already set as paid + if (! ( $wc_order_status === 'processing' + || $wc_order_status === 'on hold' + || $wc_order_status === 'completed' ) + ) { + $this->error(__('The status of the order does not allow a refund', 'gnutaler')); + return new WP_Error('error', __('The status of the order does not allow for a refund.', 'gnutaler')); + } + + $refund_request = array( + 'refund' => $wc_order->get_currency() . ':' . $amount, + 'reason' => $reason, + ); + $wc_order_id = $wc_order->get_order_key() . '-' . $wc_order->get_order_number(); + $refund_result = $this->call_api( + 'POST', + $backend_url . '/private/orders/' . $wc_order_id . '/refund', + $refund_request + ); + + $refund_http_status = $refund_result['http_code']; + $refund_body = $refund_result['message']; + switch ($refund_http_status) + { + case 200: + $refund_response = json_decode($refund_body, $assoc = true); + if (! $refund_response) { + $this->error(__('Malformed 200 response from Taler backend: not even in JSON', 'gnutaler')); + return new WP_Error('error', __('Malformed response from Taler backend', 'gnutaler')); + } + $refund_uri = $refund_response['taler_refund_uri']; + $h_contract = $refund_response['h_contract']; + if ((! $refund_uri) + || (! $h_contract) + ) { + $this->error(__('Malformed 200 response from Taler backend: lacks taler_refund_uri', 'gnutaler')); + return new WP_Error('error', __('Malformed response from Taler backend', 'gnutaler')); + } $refund_url = $backend_url . '/orders/' . $wc_order_id . '?h_contract=' . $h_contract; - $wc_order->add_meta_data( 'GNU_TALER_REFUND_URL', $refund_url ); - $wc_order->update_status( 'refunded' ); - $this->debug( sprintf( __('Received refund URI %s from Taler backend', 'gnutaler' ), - $refund_uri ) ); - $this->notice( sprintf( __('The user must visit %s to obtain the refund', 'gnutaler' ), - $refund_url ) ); - return true; - case 403: - return new WP_Error( 'error', - __('Refunds are disabled for this order. Check the refund_delay option for the Taler payment plugin.', 'gnutaler' ) ); - case 404: - $refund_error = json_decode ($refund_body, $assoc=true); - if (! $refund_error) { - return new WP_Error( 'error', - sprintf( __( 'Unexpected failure %s without Taler error code from Taler backend', 'gnutaler' ), - $refund_http_status ) ); - } - $ec = $refund_error['code']; - switch ($ec) - { - case 2000: // TALER_EC_INSTANCE_UNKNOWN - return new WP_Error( 'error', - __('Instance unknown reported by Taler backend', 'gnutaler' ) ); - case 2601: // TALER_EC_REFUND_ORDER_ID_UNKNOWN - return new WP_Error( 'error', - __('Order unknown reported by Taler backend', 'gnutaler' ) ); - default: - return new WP_Error( 'error', - sprintf( __('Unexpected error %s reported by Taler backend', 'gnutaler' ), - $ec ) ); - } - case 409: - return new WP_Error( 'error', - __('Requested refund amount exceeds original payment. This is not allowed!', 'gnutaler' ) ); - case 410: - return new WP_Error( 'error', - __('Wire transfer already happened. It is too late for a refund with Taler!', 'gnutaler' ) ); - default: - $refund_error = json_decode ($refund_body, $assoc=true); - if (! $refund_error) { + $wc_order->add_meta_data('GNU_TALER_REFUND_URL', $refund_url); + $wc_order->update_status('refunded'); + $this->debug( + sprintf( + __('Received refund URI %s from Taler backend', 'gnutaler'), + $refund_uri + ) + ); + $this->notice( + sprintf( + __('The user must visit %s to obtain the refund', 'gnutaler'), + $refund_url + ) + ); + return true; + case 403: + return new WP_Error( + 'error', + __('Refunds are disabled for this order. Check the refund_delay option for the Taler payment plugin.', 'gnutaler') + ); + case 404: + $refund_error = json_decode($refund_body, $assoc = true); + if (! $refund_error) { + return new WP_Error( + 'error', + sprintf( + __('Unexpected failure %s without Taler error code from Taler backend', 'gnutaler'), + $refund_http_status + ) + ); + } + $ec = $refund_error['code']; + switch ($ec) + { + case 2000: // TALER_EC_INSTANCE_UNKNOWN + return new WP_Error( + 'error', + __('Instance unknown reported by Taler backend', 'gnutaler') + ); + case 2601: // TALER_EC_REFUND_ORDER_ID_UNKNOWN + return new WP_Error( + 'error', + __('Order unknown reported by Taler backend', 'gnutaler') + ); + default: + return new WP_Error( + 'error', + sprintf( + __('Unexpected error %s reported by Taler backend', 'gnutaler'), + $ec + ) + ); + } + case 409: + return new WP_Error( + 'error', + __('Requested refund amount exceeds original payment. This is not allowed!', 'gnutaler') + ); + case 410: + return new WP_Error( + 'error', + __('Wire transfer already happened. It is too late for a refund with Taler!', 'gnutaler') + ); + default: + $refund_error = json_decode($refund_body, $assoc = true); + if (! $refund_error) { $ec = $refund_error['code']; - } - else { - $ec = 0; - } - return new WP_Error( 'error', - sprintf( __('Unexpected failure %s/%s from Taler backend', 'gnutaler' ), - $refund_http_status, - $ec) ); - } - } - - // *************** LOGGING ************************ - - /** - * Log $msg for debugging - */ - function debug( $msg ) : void { - $this->log ("debug", $msg); - } - - /** - * Log $msg as a informational - */ - function info( $msg ) : void { - $this->log ("info", $msg); - } - - /** - * Log $msg as a notice - */ - function notice( $msg ) : void { - $this->log ("notice", $msg); - } - - /** - * Log $msg as a warning. - */ - function warning( $msg ) : void { - $this->log ("warning", $msg); - } - - /** - * Log $msg as an error - */ - function error( $msg ) : void { - $this->log ("error", $msg); - } - - function log( $level, $msg ) { - if (! self::$log_enabled ) - return; - if ( function_exists ('wp_get_current_user()') ) { - $user_id = wp_get_current_user(); - if (! isset( $user_id )) { - $user_id = __( '', 'gnutaler' ); - } - } - else { - $user_id = 'Guest'; - } - $order_id = $_GET['order_id']; - if ( empty( self::$logger ) ) { - self::$logger = wc_get_logger(); - } - self::$logger->log( $level, $user_id . '-' . $order_id . ': ' . $msg, array ('source' => 'gnutaler' ) ); - } - - } + } + else { + $ec = 0; + } + return new WP_Error( + 'error', + sprintf( + __('Unexpected failure %s/%s from Taler backend', 'gnutaler'), + $refund_http_status, + $ec + ) + ); + } + } + + // *************** LOGGING ************************ + + /** + * Log $msg for debugging + */ + function debug( $msg ) : void + { + $this->log("debug", $msg); + } + + /** + * Log $msg as a informational + */ + function info( $msg ) : void + { + $this->log("info", $msg); + } + + /** + * Log $msg as a notice + */ + function notice( $msg ) : void + { + $this->log("notice", $msg); + } + + /** + * Log $msg as a warning. + */ + function warning( $msg ) : void + { + $this->log("warning", $msg); + } + + /** + * Log $msg as an error + */ + function error( $msg ) : void + { + $this->log("error", $msg); + } + + function log( $level, $msg ) + { + if (! self::$log_enabled ) { + return; + } + if (function_exists('wp_get_current_user()') ) { + $user_id = wp_get_current_user(); + if (! isset($user_id)) { + $user_id = __('', 'gnutaler'); + } + } + else { + $user_id = 'Guest'; + } + $order_id = $_GET['order_id']; + if (empty(self::$logger) ) { + self::$logger = wc_get_logger(); + } + self::$logger->log($level, $user_id . '-' . $order_id . ': ' . $msg, array ('source' => 'gnutaler' )); + } + + } } -- cgit v1.2.3