Partnercenter-API: WooCommerce-Plugin (v1.3.3) als Referenz eingecheckt

Der in den Partner-Shops installierte WooCommerce-Connector, der Bestellungen
per REST an /api/wp/* uebertraegt (Kunde anlegen, Warenkorb, Status-Abgleich).
Grundlage fuer AP-13 (Shop-Bestandsabzug beim Versand).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-15 15:46:16 +00:00
parent a14751ed10
commit 592b03ace5
13 changed files with 2023 additions and 0 deletions

View file

@ -0,0 +1,156 @@
<?php
// Exit if accessed directly
if (! defined('ABSPATH')) {
exit;
}
/*
* Class to add a custom endpoint for vendor decisions
*
* @since 1.1.0
*/
class PARTNERCENTER_API_Custom_Document_Download_Endpoint_Class
{
/**
* Custom endpoint name.
*
* @since 1.1.0
*
* @var string
*/
public static $endpoint = 'partnercenter-document-download';
/*
* Setup the class.
*/
public function __construct()
{
add_action('init', [$this, 'rewrite']);
add_filter('query_vars', [$this, 'query_vars']);
add_filter('template_redirect', [$this, 'change_template'], 1, 0);
}
/*
* Allow custom url parameter.
*
* @since 1.1.0
*/
public function rewrite()
{
// Add some custom query vars
add_rewrite_tag('%order-id%', '([^&]+)');
add_rewrite_tag('%document-id%', '([^&]+)');
add_rewrite_tag('%request-token%', '([^&]+)');
// Add rewrite rule to map own query vars
add_rewrite_rule('^'.self::$endpoint.'/([^/]*)/([^/]*)/([^/]*)/?', 'index.php?'.self::$endpoint.'=1&order-id=$matches[1]&document-id=$matches[2]&request-token=$matches[3]', 'top');
}
/*
* Allow custom query var.
*
* @since 1.1.0
*/
public function query_vars($vars)
{
$vars[] = self::$endpoint;
return $vars;
}
/**
* Fetch and display the template for this virtual page.
*
* @since 1.1.0
*/
public function show_response(array $values)
{
/*
* Check for empty values
*/
if (empty($values['order-id'])) {
wp_die(__('Missing order ID', 'partnercenter-api'));
}
if (empty($values['document-id'])) {
wp_die(__('Missing document ID', 'partnercenter-api'));
}
if (empty($values['request-token'])) {
wp_die(__('Missing Request token', 'partnercenter-api'));
}
// Fetch order from DB
$order = wc_get_order($values['order-id']);
if ($order === false) {
wp_die(__('Invalid order', 'partnercenter-api'));
}
/*
* Validate token
*/
$token_from_db = get_post_meta($order->get_id(), '_partnercenter_invoice_token', true);
if ($token_from_db !== $values['request-token']) {
wp_die(__('Invalid token', 'partnercenter-api'));
}
// Get invoice from DB
$invoice_from_db = wc_gzdp_get_order_last_invoice($order->get_id());
// Check if the right invoice id was requested
if (intval($invoice_from_db->get_id()) !== intval($values['document-id'])) {
wp_die(__('Mismatching invoice number', 'partnercenter-api'));
}
// Check if file exists
if (! file_exists($invoice_from_db->get_pdf_path())) {
wp_die(__('File not found', 'partnercenter-api'));
}
// Send headers to download file
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header('Cache-Control: public'); // needed for internet explorer
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: Binary');
header('Content-Length:'.filesize($invoice_from_db->get_pdf_path()));
header('Content-Disposition: attachment; filename= '.$invoice_from_db->get_filename());
readfile($invoice_from_db->get_pdf_path());
// Stop the rest of the process
exit();
}
/*
* Load right template for custom virtual page.
*
* @since 1.1.0
*/
public function change_template()
{
/** @var $wp_query WP_Query */
global $wp_query;
if (! empty($wp_query->query_vars[self::$endpoint])) {
// Set some data
$wp_query->is_404 = false;
$wp_query->is_feed = false;
$wp_query->is_page = true;
$wp_query->is_singular = true;
$wp_query->is_home = false;
$wp_query->is_archive = false;
$wp_query->is_category = false;
// Collect values to pass on
$values = [
'order-id' => sanitize_title($wp_query->query_vars['order-id']),
'document-id' => sanitize_title($wp_query->query_vars['document-id']),
'request-token' => sanitize_title($wp_query->query_vars['request-token']),
];
self::show_response($values);
}
}
}
new PARTNERCENTER_API_Custom_Document_Download_Endpoint_Class;

View file

@ -0,0 +1,137 @@
<?php
/*
* Hold all auth related request.
*/
trait PARTNERCENTER_API_Auth
{
/**
* @var string Store fetched access token
*/
private $api_access_token;
/**
* @var int Timestamp until the access token is valid.
*/
private $api_login_lifetime;
/**
* Method to log in to API.
*
* @return bool
*/
private function login()
{
// Build URL
$url = $this->build_url('auth/login');
// Build body details
$request_body = [
'email' => PARTNERCENTER_API_EMAIL,
'password' => PARTNERCENTER_API_PASSWORD,
'remember_me' => true,
];
// Return the POST request responds
$login_response = wp_safe_remote_post($url, [
'blocking' => true,
'headers' => $this->get_headers(),
'body' => json_encode($request_body),
]
);
// Check if login went well
if (wp_remote_retrieve_response_code($login_response) !== 200) {
// Reset all login details on error
$this->reset_login();
return false;
}
// Get data to work with
$response_body = (object) json_decode(wp_remote_retrieve_body($login_response));
// Set access to for all requests
$this->api_access_token = $response_body->access_token;
// Set life time data
$this->api_login_lifetime = strtotime($response_body->expires_at);
return true;
}
/**
* Method to log out.
*/
private function logout()
{
// Build URL
$url = $this->build_url('auth/logout');
// Make sure to be logged in
$this->authenticate();
// Send POST request
$logout_response = wp_safe_remote_post($url, [
'blocking' => true,
'headers' => $this->get_headers(),
]
);
// Check if login went well
if (wp_remote_retrieve_response_code($logout_response) !== 200) {
return false;
}
// Reset login details
$this->reset_login();
return true;
}
/**
* Helper to setup authentication with API.
*
* @return bool|WP_Error
*/
private function authenticate()
{
// Check if lifetime is set and can't be restored
if (empty($this->api_login_lifetime) && ! $this->login()) {
return new WP_Error('auth_failed', __('Login fails or is missing', 'partnercenter-api'));
}
// Check if access token is still valid and can't be restored
if ($this->api_login_lifetime < time() && ! $this->login()) {
return new WP_Error('auth_failed', __('Login fails or is to old', 'partnercenter-api'));
}
// Check if access token is set
if (empty($this->api_access_token)) {
return new WP_Error('auth_failed', __('Auth token is missing', 'partnercenter-api'));
}
// Reset all header fields
$this->reset_request();
// Add access token to header
$this->headers['Authorization'] = 'Bearer '.$this->api_access_token;
return true;
}
/**
* Helper to reset login.
*/
private function reset_login()
{
unset($this->api_access_token);
unset($this->api_login_lifetime);
}
}

View file

@ -0,0 +1,122 @@
<?php
/*
* Hold all http request methods.
*/
trait PARTNERCENTER_API_Methods
{
/**
* Reset all things to be able to send requests.
*/
private function reset_request()
{
$this->headers = [
'Content-Type' => 'application/json',
'X-Requested-With' => 'XMLHttpRequest',
];
}
/**
* Build the URL.
*
* @param array $args
* @return string
*/
private function build_url(string $endpoint, $args = [])
{
return add_query_arg($args, trailingslashit($this->api_url).$endpoint);
}
/**
* Send a POST request.
*
*
* @return array|WP_Error
*/
private function create(string $endpoint, array $body = [])
{
// Make sure to be logged in
$this->authenticate();
// Build URL
$url = $this->build_url($endpoint);
// Return the POST request responds
return wp_safe_remote_post($url, [
'blocking' => true,
'headers' => $this->get_headers(),
'body' => json_encode($body),
]
);
}
/**
* Send a GET request.
*
*
* @return array|WP_Error
*/
private function read(string $endpoint)
{
// Make sure to be logged in
$this->authenticate();
// Build URL
$url = $this->build_url($endpoint);
// Return the GET request responds
return wp_safe_remote_get($url, [
'blocking' => true,
'headers' => $this->get_headers(),
]
);
}
/**
* Send PATCH request.
*
*
* @return array|WP_Error
*/
private function update(string $endpoint, array $body = [])
{
// Make sure to be logged in
$this->authenticate();
// Build URL
$url = $this->build_url($endpoint);
$request_args = [
'method' => 'PATCH',
'headers' => $this->get_headers(),
'body' => json_encode($body),
];
return wp_remote_request($url, $request_args);
}
/**
* Helper to check CRUD requests responses.
*
*
* @return bool
*/
private function handle_response($response)
{
// Check if an error returned
if (wp_remote_retrieve_response_code($response) !== 200) {
return false;
}
return true;
}
}

View file

@ -0,0 +1,424 @@
<?php
/*
* Hold all order related request.
*/
trait PARTNERCENTER_API_Order
{
/**
* Store order object.
*
* @since 1.0.0
*
* @var WC_Order Store WooCommerce order data
*/
private $order;
/**
* Store order ID.
*
* @since 1.0.0
*
* @var int Order ID
*/
private $order_id;
/**
* Helper to setup order object to work with.
*
*
* @since 1.0.0
*/
private function setup_order(int $order_id)
{
$this->order_id = absint($order_id);
// Fetch order object and make it accessibly for all methods
$this->order = new WC_Order($order_id);
}
/**
* Get the invoice url.
*
* @return string|bool
*/
private function invoice_data()
{
// Check if function exists
if (! function_exists('wc_gzdp_get_order_last_invoice')) {
return false;
}
// Get the latest invoice
$invoice = wc_gzdp_get_order_last_invoice($this->order);
// Check received data
if (empty($invoice) || gettype($invoice) !== 'object') {
return false;
}
// Try to get attachment ID
$attachment_id = get_post_meta($invoice->id, '_invoice_attachment', true);
// Check if a value was found
if (empty($attachment_id)) {
return false;
}
// Try to get file path
$file_relative_path = get_post_meta($attachment_id, '_wp_attached_file', true);
if (empty($GLOBALS['woocommerce_germanized_pro'])) {
return false;
}
// Get get detail vom Class
$upload_folder = $GLOBALS['woocommerce_germanized_pro']->get_upload_dir();
// Build and return the final url to the invoice file
return $upload_folder['baseurl'].'/'.$file_relative_path;
}
/**
* Helper to setup address data.
*
* @return array
*
* @since 1.0.0
*/
private function compose_address_body()
{
// Set up body args
$data = [
'billing_salutation' => intval($this->order->get_meta('_billing_title', true)),
'billing_company' => $this->order->get_billing_company(),
'billing_firstname' => $this->order->get_billing_first_name(),
'billing_lastname' => $this->order->get_billing_last_name(),
'billing_address' => $this->order->get_billing_address_1(),
'billing_address_2' => $this->order->get_billing_address_2(),
'billing_zipcode' => $this->order->get_billing_postcode(),
'billing_city' => $this->order->get_billing_city(),
'billing_country_code' => $this->order->get_billing_country(),
'billing_phone' => $this->order->get_billing_phone(),
'billing_email' => strtolower($this->order->get_billing_email()),
];
// Check if a shipping and billing address are the same
if ($this->order->get_formatted_billing_address() === $this->order->get_formatted_shipping_address()) {
// Set value to skip shipping address
$data['same_as_billing'] = true;
} else {
// Extent array with more details
$data = array_merge($data, [
'same_as_billing' => false,
'shipping_salutation' => intval($this->order->get_meta('_shipping_title', true)),
'shipping_company' => $this->order->get_shipping_company(),
'shipping_firstname' => $this->order->get_shipping_first_name(),
'shipping_lastname' => $this->order->get_shipping_last_name(),
'shipping_address' => $this->order->get_shipping_address_1(),
'shipping_address_2' => $this->order->get_shipping_address_2(),
'shipping_zipcode' => $this->order->get_shipping_postcode(),
'shipping_city' => $this->order->get_shipping_city(),
'shipping_country_code' => $this->order->get_shipping_country(),
'shipping_phone' => $this->order->get_billing_phone(),
]);
}
// Try to set order invoice
$invoice_url = $this->invoice_data($this->order->get_id());
if ($invoice_url !== false) {
$data['wp_invoice_path'] = $invoice_url;
}
return $data;
}
/**
* Helper to create cart data.
*
* @return array
*
* @since 1.0.0
*/
private function compose_cart_content()
{
// Start of empty cart
$cart = [];
// Loop all order items
foreach ($this->order->get_items() as $order_item) {
// Get product ID of order item
$product_id = $order_item->get_product_id();
// Get product object
$product = wc_get_product($product_id);
// Get sum of total and taxes
$line_total = $order_item->get_total() + $order_item->get_total_tax();
// Divide line total by quantity
$item_price = $line_total / $order_item->get_quantity();
// Round item price to usual format
$item_price_rounded = number_format($item_price, wc_get_price_decimals());
// Convert price to the way the API likes it
$item_price_converted = intval($item_price_rounded * pow(10, wc_get_price_decimals()));
// Build array item
$cart[] = [
'article' => $product->get_sku(),
'qty' => intval($order_item->get_quantity()),
'price' => $item_price_converted,
];
}
return $cart;
}
/**
* Create order in API.
*
* @since 1.0.0
*/
private function write_order()
{
// Start body by setting all address data
$request_body = $this->compose_address_body();
// Add dev mode
if (PARTNERCENTER_API_DEV) {
$request_body['mode'] = 'dev';
}
// Set some order details
$request_body['wp_order_number'] = $this->order->get_id();
$request_body['wp_order_date'] = $this->order->get_date_created()->date('Y-m-d H:i:s');
// Send to API
$response = $this->create('wp/store', $request_body);
// Handle response
return $this->handle_response($response);
}
/**
* Add address details into Order in API.
*
* @since 1.0.0
*/
private function write_order_changes()
{
// Start body by setting all address data
$request_body = $this->compose_address_body();
// Add dev mode
if (PARTNERCENTER_API_DEV) {
$request_body['mode'] = 'dev';
}
// Set some order details
$request_body['wp_order_number'] = $this->order->get_id();
// Send to API
$response = $this->create('wp/update', $request_body);
// Handle response
return $this->handle_response($response);
}
/**
* Add cart items to order in API.
*
* @since 1.0.0
*/
private function write_order_items()
{
/*
* Order details
*/
// Get all cart details
$cart = $this->compose_cart_content();
// Build up all body data
$request_body = [
'wp_order_number' => $this->order->get_id(),
'wp_order' => $cart,
];
/*
* Add invoice
*/
// Try to get order invoice
$invoice = wc_gzdp_get_order_last_invoice($this->order->get_id());
if (! is_null($invoice)) {
// generate random token
$download_token = bin2hex(random_bytes(20));
$download_token = substr($download_token, 0, 10);
// Save token to post meta
update_post_meta($this->order->get_id(), '_partnercenter_invoice_token', $download_token);
// Build the invoice URL
$invoice_path = sprintf('/partnercenter-document-download/%s/%s/%s/', $this->order->get_id(), $invoice->get_id(), $download_token);
$invoice_url = home_url($invoice_path);
if ($invoice_url !== false) {
$request_body['wp_invoice_path'] = $invoice_url;
}
}
/*
* Add advertising
*/
$flyer_ids_string = get_post_meta($this->order->get_id(), 'timopaul_woocommerce_customers_statistics_werbemittel', true);
if (! empty($flyer_ids_string)) {
// Break IDs into array
$flyer_ids_array = explode(',', $flyer_ids_string);
// Prepare empty array
$flyer_strings_array = [];
// Loop the flyers
foreach ($flyer_ids_array as $id) {
// Add all flyer titles to array
$flyer_strings_array[] = get_the_title($id);
}
// Add contacted string to request
$request_body['wp_advertising'] = implode(', ', $flyer_strings_array);
}
/*
* Add incentives
*/
$incentives_ids_string = get_post_meta(get_the_ID(), 'timopaul_woocommerce_customers_statistics_incentives', true);
if (! empty($incentives_ids_string)) {
// Break IDs into array
$incentives_ids_array = explode(',', $incentives_ids_string);
// Prepare empty array
$incentives_strings_array = [];
// Loop the flyers
foreach ($incentives_ids_array as $id) {
// Add all flyer titles to array
$incentives_strings_array[] = get_the_title($id);
}
// Add contacted string to request
$request_body['wp_incentives'] = implode(', ', $incentives_strings_array);
}
/*
* Make the request
*/
// Send to API
$response = $this->create('wp/order', $request_body);
// Handle response
return $this->handle_response($response);
}
/**
* Try to cancel order.
*
* @since 1.2.0
*
* @return bool
*/
private function cancel_order()
{
// Set some order details
$request_body['wp_order_number'] = $this->order->get_id();
// Send to API
$response = $this->create('wp/cancel', $request_body);
// Handle response
return $this->handle_response($response);
}
/**
* Method to get order status in API.
*
* @since 1.0.0
*/
private function read_order_status()
{
// Build body
$request_body = [
'wp_order_numbers' => [$this->order->get_id()],
];
// Send to API
$response = $this->create('wp/status', $request_body);
// Handle response
if ($this->handle_response($response)) {
// Get body data
$response_body = (object) json_decode(wp_remote_retrieve_body($response));
// Get first item from data
$first_item = (object) reset($response_body->data);
// Return the status string of the first item
return $first_item->status;
} else {
return 'error';
}
}
/**
* Method to get status of multiple orders.
*
*
* @return array
*
* @since 1.0.0
*/
private function read_orders_status(array $order_ids)
{
// Build body data
$request_body = [
'wp_order_numbers' => $order_ids,
];
// Send to API
$response = $this->create('wp/status', $request_body);
// Handle response
if ($this->handle_response($response)) {
// Get body data
$response_body = (object) json_decode(wp_remote_retrieve_body($response));
// Start empty array
$orders_status = [];
// Loop all received data
foreach ($response_body->data as $order) {
$orders_status[$order->wp_order_number] = sanitize_text_field($order->status);
}
// Return array of order id with status attached
return $orders_status;
} else {
// Return empty array to prevent errors upstream
return [];
}
}
}

View file

@ -0,0 +1,191 @@
<?php
/*
* PARTNERCENTER API
*/
if (! defined('ABSPATH')) {
exit;
}
/*
* Load traits
*/
require_once 'partnercenter-api-requests/methods.php';
require_once 'partnercenter-api-requests/auth.php';
require_once 'partnercenter-api-requests/order.php';
/**
* Class PARTNERCENTER_API_Requests
*/
class PARTNERCENTER_API_Requests
{
use PARTNERCENTER_API_Auth;
// Load requests for orders
use PARTNERCENTER_API_Methods;
use PARTNERCENTER_API_Order;
/**
* Array of http headers.
*
* @since 1.0.0
*
* @var array Request headers
*/
private $headers;
/**
* Hard codes url of API.
*
* @since 1.0.0
*
* @var string
*/
private $api_url;
/**
* PARTNERCENTER_API_Requests constructor.
*/
public function __construct()
{
$this->api_url = 'https://api.gruene-seele.bio/';
// Reset request basics
$this->reset_request();
}
/**
* Helper to get headers for requests.
*
* @return array
*
* @since 1.0.0
*/
private function get_headers()
{
return $this->headers;
}
/**
* Handle new orders.
*
*
* @return bool
*
* @since 1.0.0
*/
public function new_order(int $order_id)
{
// Setup the order object
$this->setup_order($order_id);
// Handle new order data
return $this->write_order();
}
/**
* Handle order updates.
*
*
* @return bool
*
* @since 1.0.0
*/
public function update_order(int $order_id)
{
// Setup the order object
$this->setup_order($order_id);
// Handle new order data
return $this->write_order_changes();
}
/**
* Handle order status questions.
*
*
* @return string
*
* @since 1.0.0
*/
public function get_order_status(int $order_id)
{
// Setup the order object
$this->setup_order($order_id);
// Get and return the status string
return $this->read_order_status();
}
/**
* Public method to check status for a list of orders.
*
*
* @return array
*
* @since 1.0.0
*/
public function get_orders_status(array $order_ids)
{
return $this->read_orders_status($order_ids);
}
/**
* Handle button click to send data to PARTNERCENTER.
*
*
* @return bool
*
* @since 1.0.0
*/
public function send_order_items(int $order_id)
{
// Setup the order object
$this->setup_order($order_id);
// Send data to API
if (! $this->write_order_items()) {
// Return error state
return false;
}
// Add timestamp to order meta to store success
update_post_meta($order_id, '_partnercenter_api_order_fulfillment_forwarded', time());
// Return a success flag
return true;
}
/**
* Handle retrieving of order from PARTNERCENTER.
*
* @since 1.2.0
*
* @return bool
*/
public function retrieve_order(int $order_id)
{
// Setup the order object
$this->setup_order($order_id);
// Send data to API
if (! $this->cancel_order()) {
// Return error state
return false;
}
// Add timestamp to order meta to store success
delete_post_meta($order_id, '_partnercenter_api_order_fulfillment_forwarded');
// Return a success flag
return true;
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* Add Shortcode
*
* @since 1.0.0
*/
function partnercenter_api_testing_shortcode()
{
// return '<h3>PARTNERCENTER API Test</h3>';
// $order_id = 82990;
// $order = new WC_Order( $order_id );
// return var_export( $order, true );
// $url = $invoice->get_pdf_url();
// return 'Test ' . $order_id . ': ' . $order->get_meta( '_billing_title', true ) . ' || ' . $order->get_b;
$partnercenter = apply_filters('PARTNERCENTER_API', false);
// error_log( var_export( '$partnercenter', true ) );
// error_log( var_export( $partnercenter, true ) );
// $order = new WC_Order( 82990 );
// error_log( var_export( '$order 82990', true ) );
// error_log( var_export( $order, true ) );
// $new_order = $partnercenter->new_order( 82990 );
// error_log( var_export( '$new_order', true ) );
// error_log( var_export( $new_order, true ) );
// $update_order = $partnercenter->update_order( 58 );
// error_log( var_export( '$update_order', true ) );
// error_log( var_export( $update_order, true ) );
// $order_status = $partnercenter->get_order_status( 58 );
// error_log( var_export( '$order_status', true ) );
// error_log( var_export( $order_status, true ) );
// $orders_status = $partnercenter->read_orders_status([67,]);
// error_log( var_export( '$orders_status', true ) );
// error_log( var_export( $orders_status, true ) );
// $order_items = $partnercenter->send_order_items( 58 );
// error_log( var_export( '$order_items', true ) );
// error_log( var_export( $order_items, true ) );
// Test login and logout
// $logout = $partnercenter->logout();
// error_log( var_export( '$logout', true ) );
// error_log( var_export( $logout, true ) );
}
add_shortcode('partnercenter_api', 'partnercenter_api_testing_shortcode');

View file

@ -0,0 +1,282 @@
<?php
/*
* All order status related features.
*/
if (! defined('ABSPATH')) {
exit;
}
class PARTNERCENTER_API_WooCommerce_Order_Status_Class
{
/**
* PARTNERCENTER_API_WooCommerce_Order_Status_Class constructor.
*/
public function __construct()
{
// Listen to new orders
add_action('woocommerce_new_order', [$this, 'woocommerce_new_order'], 94839877, 2);
// Listen to order updates
add_action('woocommerce_update_order', [$this, 'woocommerce_update_order'], 94839877, 2);
// Listen to new orders by admin
add_action('woocommerce_process_shop_order_meta', [$this, 'woocommerce_process_shop_order_meta'], 9876, 1);
// Listen to button click
add_action('partnercenter_api_send_order_items', [$this, 'partnercenter_api_send_order_items'], 20, 1);
// Listen to button click
add_action('partnercenter_api_retrieve_order', [$this, 'partnercenter_api_retrieve_order'], 20, 1);
// Listen for cron event
add_action('partnercenter_api_fetch_orders_status', [$this, 'partnercenter_api_fetch_orders_status'], 20);
}
/**
* Run API request on new order.
*
* @param WC_Order order
*
* @since 1.0.0
*/
public function woocommerce_new_order(int $order_id, $order)
{
// Build a hash over addresses
$address_string = $order->get_formatted_billing_address().$order->get_formatted_shipping_address();
$new_address_hash = md5($address_string);
// Store hash of addresses as meta data
add_post_meta($order_id, '_partnercenter_api_address_hash', $new_address_hash, true);
// Load API
$partnercenter = apply_filters('PARTNERCENTER_API', false);
if ($partnercenter === false) {
return;
}
// Notify PARTNERCENTER about new order
$added = $partnercenter->new_order($order_id);
if ($added) {
// Add flag about sent order
update_post_meta($order_id, '_partnercenter_api_order_added', time());
}
}
/**
* Handle new orders from admin screen.
*
* @param $order_id integer
*/
public function woocommerce_process_shop_order_meta(int $order_id)
{
// Check if order needs handling- if value isset the order has been send to API on "thank you" page
if (! empty(get_post_meta($order_id, '_partnercenter_api_order_added', true))) {
return;
}
// Get order object
$order = new WC_Order($order_id);
// Check if email was given
if (empty($order->get_billing_email())) {
return;
}
// Load API
$partnercenter = apply_filters('PARTNERCENTER_API', false);
if ($partnercenter === false) {
return;
}
// Notify PARTNERCENTER about new order
$added = $partnercenter->new_order($order_id);
if ($added) {
// Add flag about sent order
update_post_meta($order_id, '_partnercenter_api_order_added', time());
}
}
/**
* Run API request on order update.
*
* @param WC_Order $order
*
* @since 1.0.0
*/
public function woocommerce_update_order(int $order_id, $order)
{
// Build a hash over addresses
$address_string = $order->get_formatted_billing_address().$order->get_formatted_shipping_address();
$new_address_hash = md5($address_string);
// Get old address hash
$old_address_hash = get_post_meta($order_id, '_partnercenter_api_address_hash', true);
// Check if address data has changed
if ($old_address_hash === $new_address_hash) {
// Address had not been changed
return;
}
// Update hash of addresses as meta data
update_post_meta($order_id, '_partnercenter_api_address_hash', $new_address_hash);
// Load API
$partnercenter = apply_filters('PARTNERCENTER_API', false);
if ($partnercenter === false) {
return;
}
// Notify PARTNERCENTER API about updated addresses
$partnercenter->update_order($order_id);
}
/**
* Run API request on order forwarding form action.
*
*
* @since 1.0.0
*/
public function partnercenter_api_send_order_items(int $order_id)
{
// Load API
$partnercenter = apply_filters('PARTNERCENTER_API', false);
if ($partnercenter === false) {
return;
}
// Notify PARTNERCENTER about order content
$received = $partnercenter->send_order_items($order_id);
// Exit on error
if ($received === false) {
return;
}
// Add a value to be overwritten by cron job
add_post_meta($order_id, '_partnercenter_api_order_status', 'open', true);
/*
* Add order ID to list of orders to check regularly
*/
// Get list of orders to add to
$unclear_orders = get_option('_partnercenter_api_unclear_order_ids', []);
// Add current order ID to list
$unclear_orders[] = intval($order_id);
// Save new list of unclear order ids
update_option('_partnercenter_api_unclear_order_ids', $unclear_orders, false);
}
/**
* Run API request to retrieve order from shipment.
*
*
* @since 1.2.0
*/
public function partnercenter_api_retrieve_order(int $order_id)
{
// Load API
$partnercenter = apply_filters('PARTNERCENTER_API', false);
if ($partnercenter === false) {
return;
}
// Notify PARTNERCENTER about retrieved order
$received = $partnercenter->retrieve_order($order_id);
// Exit on error
if ($received === false) {
return;
}
// Remove value to make order free again
delete_post_meta($order_id, '_partnercenter_api_order_status');
// Mark order to be canceled in API
update_post_meta($order_id, '_partnercenter_api_order_canceled', time());
/*
* Add order ID to list of orders to check regularly
*/
// Get list of orders to add to
$unclear_orders = get_option('_partnercenter_api_unclear_order_ids', []);
$found_key = array_search($order_id, $unclear_orders);
if ($found_key === false) {
return;
}
// Remove order from list of orders to check
unset($unclear_orders[$found_key]);
// Save new list of unclear order ids
update_option('_partnercenter_api_unclear_order_ids', $unclear_orders, false);
}
/**
* Handle cron event call.
*
* @since 1.0.0
*/
public function partnercenter_api_fetch_orders_status()
{
// Get list of unclear orders
$unclear_orders = get_option('_partnercenter_api_unclear_order_ids', []);
if (empty($unclear_orders)) {
// No orders to check
return;
}
// Load API
$partnercenter = apply_filters('PARTNERCENTER_API', false);
if ($partnercenter === false) {
return;
}
// Ask PARTNERCENTER about current status
$new_statuses = $partnercenter->get_orders_status($unclear_orders);
if (empty($new_statuses)) {
// No orders to check or connection error
return;
}
// Loop all received order statues
foreach ($new_statuses as $order_key => $order_status) {
// Store new status
update_post_meta($order_key, '_partnercenter_api_order_status', sanitize_title($order_status));
if (! in_array($order_status, ['close', 'sent'])) {
continue;
}
// Search order ID in list of unclear orders
$key_in_array = array_search($order_key, $unclear_orders);
// Remove order after it shipped
unset($unclear_orders[$key_in_array]);
}
// Save new list of unclear order IDs
update_option('_partnercenter_api_unclear_order_ids', $unclear_orders, false);
}
}
new PARTNERCENTER_API_WooCommerce_Order_Status_Class;