File "class-kp-order-data.php"
Full Path: /home/siazco/grocery.siazco.se/wp-content/plugins/klarna-payments-for-woocommerce/classes/requests/helpers/class-kp-order-data.php
File size: 11.29 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Helper class to generate a Klarna payments request body for a order/session request.
*
* @package WC_Klarna_Payments/Classes/Requests/Helpers
*/
defined( 'ABSPATH' ) || exit;
use KrokedilKlarnaPaymentsDeps\Krokedil\WooCommerce\Cart\Cart;
use KrokedilKlarnaPaymentsDeps\Krokedil\WooCommerce\Order\Order;
/**
* Helper class to generate a Klarna payments request body for a order/session request.
*/
class KP_Order_Data {
/**
* The WooCommerce order id is used to calculate the order data. If null the cart will be used instead.
*
* @var int|null
*/
private $order_id;
/**
* The WooCommerce order is used to calculate the order data. If null the cart will be used instead.
*
* @var WC_Order|null
*/
private $order;
/**
* The Klarna country to use for the request body.
*
* @var string
*/
private $klarna_country;
/**
* The Customer type to use for KP. Either B2B or B2C. Based on the setting in the plugin.
*
* @var string
*/
private $customer_type;
/**
* The generated order data.
*
* @var KrokedilKlarnaPaymentsDeps\Krokedil\WooCommerce\OrderData
*/
public $order_data;
/**
* If we should use separate sales tax or not for the requests.
*
* @var bool
*/
private $separate_sales_tax;
/**
* Class constructor.
*
* @param string $customer_type The Customer type to use for KP. Either B2B or B2C. Based on the setting in the plugin.
* @param int|null $order_id The WooCommerce order it used to calculate the order data. If null the cart will be used instead.
*/
public function __construct( $customer_type, $order_id = null ) {
$this->customer_type = $customer_type;
$this->order_id = $order_id;
$this->order = $this->order_id ? wc_get_order( $this->order_id ) : null;
$this->klarna_country = kp_get_klarna_country( $this->order );
$this->order_data = $this->get_order_data();
$this->separate_sales_tax = 'US' === $this->klarna_country;
}
/**
* Returns the request helper for the request based on if we have a order id passed or not.
*
* @return KrokedilKlarnaPaymentsDeps\Krokedil\WooCommerce\OrderData
*/
public function get_order_data() {
$config = array(
'slug' => 'kp',
'price_format' => 'minor',
);
if ( $this->order_id ?? false && ! empty( $this->order_id ) ) {
$order = wc_get_order( $this->order_id );
return new Order( $order, $config );
} else {
return new Cart( WC()->cart, $config );
}
}
/**
* Returns a formatted Klarna order object.
*
* @param KP_IFrame $iframe_options The options to use for the Klarna Payments iframes.
* @return array
*/
public function get_klarna_order_object( $iframe_options = null ) {
$customer = $this->get_klarna_customer_object();
return array(
'purchase_country' => $this->klarna_country,
'purchase_currency' => empty( $order ) ? get_woocommerce_currency() : $order->get_currency(),
'locale' => kp_get_locale(),
'order_amount' => $this->order_data->get_total(),
'order_tax_amount' => $this->order_data->get_total_tax(),
'order_lines' => $this->get_klarna_order_lines_array(),
'customer' => get_klarna_customer( $this->customer_type ),
'billing_address' => $customer['billing'],
'shipping_address' => $customer['shipping'],
'options' => $iframe_options ? $iframe_options->get_kp_color_options() : array(),
'merchant_urls' => array(
'authorization' => home_url( '/wc-api/KP_WC_AUTHORIZATION' ),
),
);
}
/**
* Returns an array of Klarna order line objects.
*
* @return array
*/
public function get_klarna_order_lines_array() {
$klarna_order_lines = array();
// Order items/products.
foreach ( $this->order_data->get_line_items() as $item ) {
$klarna_order_lines[] = $this->get_klarna_order_line_object( $item );
}
// Order Shipping.
foreach ( $this->order_data->get_line_shipping() as $item ) {
$klarna_order_lines[] = $this->get_klarna_order_line_object( $item );
}
// Order Fees.
foreach ( $this->order_data->get_line_fees() as $item ) {
$klarna_order_lines[] = $this->get_klarna_order_line_object( $item );
}
// Order compatibility, to support third party plugins that add orders lines that needs to be handled separately.
foreach ( $this->order_data->get_line_compatibility() as $item ) {
$klarna_order_lines[] = $this->get_klarna_order_line_object( $item );
}
// Order Coupons/Giftcards.
foreach ( KP_WC()->krokedil->compatibility()->giftcards() as $giftcards ) {
if ( false !== ( strpos( get_class( $giftcards ), 'WCGiftCards', true ) ) && ! function_exists( 'WC_GC' ) ) {
continue;
}
$retrieved_giftcards = ! empty( $this->order ) ? $giftcards->get_order_giftcards( $this->order ) : $giftcards->get_cart_giftcards();
foreach ( $retrieved_giftcards as $retrieved_giftcard ) {
$klarna_order_lines[] = $this->get_klarna_order_line_object( $retrieved_giftcard );
}
}
if ( $this->separate_sales_tax ) {
$klarna_order_lines[] = array(
'name' => __( 'Sales Tax', 'klarna-payments-for-woocommerce' ),
'quantity' => 1,
'reference' => __( 'Sales Tax', 'klarna-payments-for-woocommerce' ),
'tax_rate' => 0,
'total_amount' => $this->order_data->get_total_tax(),
'total_discount_amount' => 0,
'total_tax_amount' => 0,
'type' => 'sales_tax',
'unit_price' => $this->order_data->get_total_tax(),
);
}
return $klarna_order_lines;
}
/**
* Returns a formatted Klarna order line object.
*
* @param KrokedilKlarnaPaymentsDeps\Krokedil\WooCommerce\OrderLineData $order_line The order line data.
* @return array
*/
public function get_klarna_order_line_object( $order_line ) {
$type = 'physical';
switch ( $order_line->get_type() ) {
case 'shipping':
$type = 'shipping_fee';
break;
case 'fee':
$type = 'surcharge';
break;
case 'gift_card':
$type = 'gift_card';
break;
case 'discount':
$type = 'discount';
break;
}
$klarna_item = array(
'image_url' => $this->maybe_allow_order_line_url( $order_line->get_image_url() ),
'merchant_data' => apply_filters( $order_line->get_filter_name( 'merchant_data' ), array(), $order_line ),
'name' => $order_line->get_name(),
'product_identifiers' => apply_filters( $order_line->get_filter_name( 'product_identifiers' ), array(), $order_line ),
'product_url' => $order_line->get_product_url(),
'quantity' => $order_line->get_quantity(),
'quantity_unit' => apply_filters( $order_line->get_filter_name( 'quantity_unit' ), 'pcs', $order_line ),
'reference' => $order_line->get_sku(),
'tax_rate' => $this->separate_sales_tax ? 0 : $order_line->get_tax_rate(),
'total_amount' => $this->separate_sales_tax ? $order_line->get_total_amount() : $order_line->get_total_amount() + $order_line->get_total_tax_amount(),
'total_discount_amount' => $this->separate_sales_tax ? $order_line->get_total_discount_amount() : $order_line->get_total_discount_amount() + $order_line->get_total_discount_tax_amount(),
'total_tax_amount' => $this->separate_sales_tax ? 0 : $order_line->get_total_tax_amount(),
'type' => $type,
'unit_price' => $this->separate_sales_tax ? $order_line->get_subtotal_unit_price() : $order_line->get_subtotal_unit_price() + $order_line->get_subtotal_unit_tax_amount(),
'subscription' => apply_filters( $order_line->get_filter_name( 'subscription' ), array(), $order_line ),
);
if ( isset( $order_line->product ) ) {
$product = $order_line->product;
if ( class_exists( 'WC_Subscriptions_Product' ) && WC_Subscriptions_Product::is_subscription( $product ) ) {
$klarna_item['subscription'] = array(
'name' => $klarna_item['name'],
'interval' => strtoupper( WC_Subscriptions_Product::get_period( $product ) ),
'interval_count' => absint( WC_Subscriptions_Product::get_interval( $product ) ),
);
}
}
return array_filter( $klarna_item, 'KP_Order_Data::remove_null' );
}
/**
* Returns a formatted Klarna customer object.
*
* @param string|null $customer_type The customer type to use for generating the data. If empty it will use the class property instead.
* @return array
*/
public function get_klarna_customer_object( $customer_type = null ) {
if ( empty( $customer_type ) ) {
$customer_type = $this->customer_type;
}
$strip_postcode_spaces = apply_filters( 'wc_kp_remove_postcode_spaces', false );
$customer_data = $this->order_data->customer;
$billing = array(
'given_name' => $customer_data->get_billing_first_name(),
'family_name' => $customer_data->get_billing_last_name(),
'email' => $customer_data->get_billing_email(),
'phone' => $customer_data->get_billing_phone(),
'street_address' => $customer_data->get_billing_address_1(),
'street_address2' => $customer_data->get_billing_address_2(),
'postal_code' => $strip_postcode_spaces ? $customer_data->get_billing_postcode() : str_replace( ' ', '', $customer_data->get_billing_postcode() ),
'city' => $customer_data->get_billing_city(),
'region' => $customer_data->get_billing_state(),
'country' => empty( $customer_data->get_billing_country() ) ? kp_get_klarna_country() : $customer_data->get_billing_country(),
);
$shipping = array(
'given_name' => $customer_data->get_shipping_first_name(),
'family_name' => $customer_data->get_shipping_last_name(),
'email' => $customer_data->get_shipping_email(),
'phone' => $customer_data->get_shipping_phone(),
'street_address' => $customer_data->get_shipping_address_1(),
'street_address2' => $customer_data->get_shipping_address_2(),
'postal_code' => $strip_postcode_spaces ? $customer_data->get_shipping_postcode() : str_replace( ' ', '', $customer_data->get_shipping_postcode() ),
'city' => $customer_data->get_shipping_city(),
'region' => $customer_data->get_shipping_state(),
'country' => $customer_data->get_shipping_country(),
);
if ( 'b2b' === $customer_type ) {
$billing['organization_name'] = $customer_data->get_billing_company();
$shipping['organization_name'] = $customer_data->get_shipping_company();
}
foreach ( $shipping as $key => $value ) {
if ( ! empty( $value ) ) {
continue;
}
$shipping[ $key ] = $billing[ $key ];
}
$customer = array(
'billing' => $billing,
'shipping' => $shipping,
);
return $customer;
}
/**
* Filters array values to remove all null values.
*
* @param mixed $var The line value to filter.
* @return bool
*/
public static function remove_null( $var ) {
return is_array( $var ) ? ! empty( $var ) : null !== $var; // If empty array, or if value is null return true to remove value.
}
/**
* Maybe filters out product url for the order line before we send them to Klarna based on settings.
*
* @param string $url The URL to the product or product image.
* @return string|null
*/
public function maybe_allow_order_line_url( $url ) {
$settings = get_option( 'woocommerce_klarna_payments_settings', array() );
if ( 'yes' !== ( $settings['send_product_urls'] ?? 'no' ) ) {
$url = null;
}
return $url;
}
}