39341-vm/wp-content/plugins/stripe-payments/includes/class-asp-product-item.php
2026-03-26 12:55:30 +00:00

817 lines
28 KiB
PHP

<?php
class ASP_Product_Item {
public $currency;
public $name;
public $quantity;
public $description;
public $tax_amount;
protected $post_id = false;
protected $post;
protected $last_error = '';
protected $cust_quantity = false;
protected $tax;
protected $shipping;
protected $zero_cent = false;
protected $price;
protected $asp_main;
protected $coupon = false;
protected $price_with_discount;
protected $button_key = false;
protected $items = array();
protected $sess;
protected $overriden_data = false;
public function __construct( $post_id = false ) {
$this->asp_main = AcceptStripePayments::get_instance();
if ( false !== $post_id ) {
//let's try to load item from product
$this->post_id = $post_id;
$this->load_from_product();
$btn_uniq_id = isset( $_GET['btn_uniq_id'] ) ? sanitize_text_field( stripslashes ( $_GET['btn_uniq_id'] ) ) : '';
if ( ! empty( $btn_uniq_id ) ) {
ASP_Debug_Logger::log( 'Using the btn_uniq_id parameter. Value of btn_uniq_id: ' . $btn_uniq_id, true );
$this->sess = ASP_Session::get_instance();
$this->overriden_data = $this->sess->get_transient_data( 'overriden_data_' . $btn_uniq_id );
}
}
}
private function in_cents( $amount ) {
if ( ! $this->zero_cent ) {
$amount = round( $amount * 100, 2 );
} else {
$amount = round( $amount, 0 );
}
return $amount;
}
private function from_cents( $amount ) {
if ( ! $this->zero_cent ) {
$amount = round( $amount / 100, 2 );
} else {
$amount = round( $amount, 0 );
}
return $amount;
}
public function get_last_error() {
return $this->last_error;
}
public function get_product_id() {
return $this->post_id;
}
public function get_button_text() {
$button_text = get_post_meta( $this->post_id, 'asp_product_button_text', true );
if ( empty( $button_text ) ) {
$button_text = $this->asp_main->get_setting( 'button_text' );
}
return $button_text;
}
public function get_button_class() {
$button_class = get_post_meta( $this->post_id, 'asp_product_button_class', true );
return $button_class;
}
public function get_stock_items() {
$stock_items = get_post_meta( $this->post_id, 'asp_product_stock_items', true );
return $stock_items;
}
public function stock_control_enabled() {
$stock_control_enabled = get_post_meta( $this->post_id, 'asp_product_enable_stock', true );
return $stock_control_enabled;
}
public function get_tax() {
if ( false !== $this->overriden_data && isset( $this->overriden_data['tax'] ) ) {
return $this->overriden_data['tax'];
}
if ( ! empty( $this->tax ) ) {
return $this->tax;
}
$this->tax = get_post_meta( $this->post_id, 'asp_product_tax', true );
if ( empty( $this->tax ) ) {
$this->tax = 0;
}
return $this->tax;
}
public function set_tax( $tax ) {
$this->tax = $tax;
}
public function get_shipping( $in_cents = false ) {
if ( ! isset( $this->shipping ) ) {
$this->shipping = get_post_meta( $this->post_id, 'asp_product_shipping', true );
}
if ( empty( $this->shipping ) ) {
$this->shipping = 0;
}
if ( $in_cents ) {
return $this->in_cents( $this->shipping );
}
return $this->shipping;
}
public function set_shipping( $shipping, $in_cents = false ) {
$this->shipping = $in_cents ? $this->from_cents( $shipping ) : $shipping;
}
public function get_items_total( $in_cents = false, $with_discount = false ) {
$items_total = 0;
if ( ! empty( $this->items ) ) {
foreach ( $this->items as $item ) {
$items_total += $item['price'];
}
} else {
return 0;
}
if ( $with_discount && $this->coupon && 'perc' === $this->coupon['discount_type'] ) {
$items_total = $this->apply_discount_to_amount( $items_total, false );
}
return $in_cents ? $this->in_cents( $items_total ) : $items_total;
}
public function get_items() {
return $this->items;
}
public function add_item( $name, $price ) {
$this->items[] = array(
'name' => $name,
'price' => floatval( $price ),
);
}
public function get_thumb() {
$this->thumb = get_post_meta( $this->post_id, 'asp_product_thumbnail', true );
return $this->thumb;
}
public function get_name() {
$this->name = $this->post->post_title;
return $this->name;
}
public function get_description() {
$this->description = get_post_meta( $this->post_id, 'asp_product_description', true );
return $this->description;
}
public function get_quantity() {
$this->quantity = get_post_meta( $this->post_id, 'asp_product_quantity', true );
if ( ! is_numeric( $this->quantity ) ) {
$this->quantity = absint( $this->quantity );
}
if ( empty( $this->quantity ) ) {
$this->quantity = 1;
}
if ( $this->cust_quantity ) {
$this->quantity = $this->cust_quantity;
}
return $this->quantity;
}
public function get_coupon_discount_amount() {
$price = $this->get_price();
$items_total = $this->get_items_total();
$discount_amount = $this->get_discount_amount( $price + $items_total );
return $discount_amount;
}
public function get_price( $in_cents = false, $price_with_discount = false ) {
if ( is_null( $this->price ) ) {
$this->price = get_post_meta( $this->post_id, 'asp_product_price', true );
$this->price = empty( $this->price ) ? 0 : round( $this->price * 100 ) / 100;
}
if ( $price_with_discount && $this->coupon ) {
$discount_amount = $this->get_discount_amount( $this->price, $in_cents );
$this->price_with_discount = $this->price - $discount_amount;
}
if ( $in_cents ) {
if ( $price_with_discount && $this->coupon ) {
return $this->in_cents( $this->price_with_discount );
}
return $this->in_cents( $this->price );
}
if ( $price_with_discount && $this->coupon ) {
return $this->price_with_discount;
}
return $this->price;
}
public function get_surcharge()
{
$surcharge_amount = get_post_meta( $this->post_id, 'asp_surcharge_amount', true );
return !empty($surcharge_amount) && is_numeric($surcharge_amount) ? $surcharge_amount : 0;
}
public function get_surcharge_label()
{
$surcharge_label = get_post_meta( $this->post_id, 'asp_surcharge_label', true );
return !empty($surcharge_label) ? $surcharge_label : __("Surcharge", 'stripe-payments');
}
public function get_surcharge_type()
{
$surcharge_type = get_post_meta( $this->post_id, 'asp_surcharge_type', true );
return empty($surcharge_type) ? 'flat' : $surcharge_type;
}
/**
* Calculate the total surcharge amount based on the surcharge type and amount.
*
* @param bool $in_cents Whether to return the result in cents.
*
* @return float|int
*/
public function calculate_total_surcharge(bool $in_cents = false)
{
$surcharge_amount = $this->get_surcharge();
$surcharge_type = $this->get_surcharge_type();
if ( $surcharge_type == 'perc' ){
$calculate_from_amount = $this->get_total();
$surcharge_percentage = floatval($surcharge_amount);
$amount = ( $calculate_from_amount / 100 ) * $surcharge_percentage;
} else {
$amount = floatval($surcharge_amount);
}
return $in_cents ? $this->in_cents( $amount ) : $amount;
}
/**
* Returns min amount for donation product
*
* @param bool $in_cents Return amount in cents if set to `true`
*
* @return integer|float
*/
public function get_min_amount( $in_cents = false ) {
$min_amount = get_post_meta( $this->post_id, 'asp_product_min_amount', true );
$min_amount = empty( $min_amount ) ? 0 : $min_amount;
return $in_cents ? $this->in_cents( $min_amount ) : $min_amount;
}
/**
* Returns product type
*
* @return string
*/
public function get_type() {
$type = get_post_meta( $this->post_id, 'asp_product_type', true );
return $type;
}
public function apply_discount_to_amount( $amount, $in_cents = false ) {
if ( $this->coupon ) {
if ( 'perc' === $this->coupon['discount_type'] ) {
$perc = AcceptStripePayments::is_zero_cents( $this->get_currency() ) ? 0 : 2;
$discount_amount = round( $amount * ( $this->coupon['discount'] / 100 ), $perc );
} else {
$discount_amount = $this->coupon['discount'];
if ( $in_cents && ! AcceptStripePayments::is_zero_cents( $this->get_currency() ) ) {
$discount_amount = $discount_amount * 100;
}
}
if ( $in_cents ) {
$discount_amount = round( $discount_amount, 0 );
}
$amount = $amount - $discount_amount;
}
return $amount;
}
public function get_discount_amount( $total, $in_cents = false ) {
$discount_amount = 0;
if ( $this->coupon ) {
if ( 'perc' === $this->coupon['discount_type'] ) {
$perc = AcceptStripePayments::is_zero_cents( $this->get_currency() ) ? 0 : 2;
$discount_amount = round( $total * ( $this->coupon['discount'] / 100 ), $perc );
} else {
$discount_amount = $this->coupon['discount'];
if ( ! $this->coupon['per_order'] ) {
$discount_amount = $discount_amount * $this->get_quantity();
}
if ( $in_cents && ! AcceptStripePayments::is_zero_cents( $this->get_currency() ) ) {
$discount_amount = $discount_amount * 100;
}
}
if ( $in_cents ) {
$discount_amount = round( $discount_amount, 0 );
}
$this->coupon['discountAmount'] = $discount_amount;
}
return $discount_amount;
}
/*
* Returns the total amount for the product (including tax, shipping, item quantity, and discount if any)
*
* @param bool $in_cents Return amount in cents if set to `true`
*/
public function get_total( $in_cents = false ) {
$total = $this->get_price( $in_cents );
$items_total = $this->get_items_total( $in_cents );
$total += $items_total;
$total = $total * $this->get_quantity();
$total = $total - $this->get_discount_amount( $total, $in_cents );
if ( $this->get_tax() ) {
$total = $total + $this->get_tax_amount( $in_cents, true );
}
$shipping = $this->get_shipping( $in_cents );
if ( ! empty( $shipping ) ) {
$total = $total + $this->get_shipping( $in_cents );
}
if ( $total < 0 ) {
$total = 0;
}
return $total;
}
public function set_price( $price, $in_cents = false ) {
//workaround for zero-cents currencies for Sub addon 2.0.10 or less
$this->zero_cent = AcceptStripePayments::is_zero_cents( $this->get_currency() );
if ( $this->zero_cent && class_exists( 'ASPSUB_main' ) && isset( $this->plan ) && version_compare( ASPSUB_main::ADDON_VER, '2.0.10' ) <= 0 ) {
$price = $price * 100;
}
//end workaround
if ( $in_cents ) {
$price = $this->from_cents( $price );
}
$this->price = $price;
}
public function set_quantity( $quantity ) {
$this->cust_quantity = $quantity;
}
public function get_tax_amount( $in_cents = false, $price_with_discount = false ) {
$total = $this->get_price( false );
$items_total = $this->get_items_total( false );
$total += $items_total;
$total = $total * $this->get_quantity();
$total = $total - $this->get_discount_amount( $total, false );
$this->tax_amount = AcceptStripePayments::get_tax_amount( $total, $this->get_tax(), $this->zero_cent );
if ( $in_cents ) {
return $this->in_cents( $this->tax_amount );
}
return $this->tax_amount;
}
public function get_currency() {
if ( empty( $this->currency ) ) {
$this->currency = get_post_meta( $this->post_id, 'asp_product_currency', true );
$this->currency = empty( $this->currency ) ? $this->asp_main->get_setting( 'currency_code' ) : $this->currency;
}
$this->zero_cent = AcceptStripePayments::is_zero_cents( $this->currency );
return $this->currency;
}
public function set_currency( $curr ) {
$this->currency = $curr;
$this->zero_cent = AcceptStripePayments::is_zero_cents( $curr );
}
public function is_variable() {
return $this->get_price() === 0;
}
public function is_currency_variable() {
if ( $this->get_type() !== 'donation' ) {
return false;
}
$currency_variable = get_post_meta( $this->post_id, 'asp_product_currency_variable', true );
return $currency_variable;
}
public function get_redir_url() {
$url = get_post_meta( $this->post_id, 'asp_product_thankyou_page', true );
if ( empty( $url ) ) {
$url = $this->asp_main->get_setting( 'checkout_url' );
}
return $url;
}
public function collect_billing_addr() {
return get_post_meta( $this->post_id, 'asp_product_collect_billing_addr', true );
}
public function gen_item_data() {
$ret = array();
$item_info = array(
'name' => $this->get_name(),
'amount' => $this->get_price( true ),
'currency' => $this->get_currency(),
'quantity' => $this->get_quantity(),
);
$thumb = $this->get_thumb();
if ( ! empty( $thumb ) ) {
$item_info['images'] = array( $this->get_thumb() );
}
$descr = $this->get_description();
if ( ! empty( $descr ) ) {
$item_info['description'] = $this->get_description();
}
$ret[] = $item_info;
$tax = $this->get_tax();
if ( ! empty( $tax ) ) {
$tax_str = apply_filters( 'asp_customize_text_msg', __( 'Tax', 'stripe-payments' ), 'tax_str' );
$tax_info = array(
'name' => sprintf( '%s (%s%%)', $tax_str, $this->get_tax() ),
'amount' => $this->get_tax_amount( true ),
'currency' => $this->get_currency(),
'quantity' => $this->get_quantity(),
);
$ret[] = $tax_info;
}
$ship = $this->get_shipping();
if ( ! empty( $ship ) ) {
$ship_str = apply_filters( 'asp_customize_text_msg', __( 'Shipping', 'stripe-payments' ), 'shipping_str' );
$tax_info = array(
'name' => sprintf( '%s', $ship_str ),
'amount' => $this->get_shipping( true ),
'currency' => $this->get_currency(),
'quantity' => $this->get_quantity(),
);
$ret[] = $tax_info;
}
return $ret;
}
public function get_coupon() {
return $this->coupon;
}
private function load_coupon( $coupon_code ) {
//let's find coupon
$coupon = get_posts(
array(
'meta_key' => 'asp_coupon_code',
'meta_value' => $coupon_code,
'posts_per_page' => 1,
'offset' => 0,
'post_type' => 'asp_coupons',
)
);
wp_reset_postdata();
if ( empty( $coupon ) ) {
//coupon not found
$this->last_error = __( 'Coupon not found.', 'stripe-payments' );
return false;
}
$coupon = $coupon[0];
//check if coupon is active
if ( ! get_post_meta( $coupon->ID, 'asp_coupon_active', true ) ) {
$this->last_error = __( 'Coupon is not active.', 'stripe-payments' );
return false;
}
//check if coupon start date has come
$start_date = get_post_meta( $coupon->ID, 'asp_coupon_start_date', true );
if ( empty( $start_date ) || strtotime( $start_date ) > time() ) {
$this->last_error = __( 'Coupon is not available yet.', 'stripe-payments' );
return false;
}
//check if coupon has expired
$exp_date = get_post_meta( $coupon->ID, 'asp_coupon_exp_date', true );
if ( ! empty( $exp_date ) && strtotime( $exp_date ) < time() ) {
$this->last_error = __( 'Coupon has expired.', 'stripe-payments' );
return false;
}
//check if redemption limit is reached
$red_limit = get_post_meta( $coupon->ID, 'asp_coupon_red_limit', true );
$red_count = get_post_meta( $coupon->ID, 'asp_coupon_red_count', true );
if ( ! empty( $red_limit ) && intval( $red_count ) >= intval( $red_limit ) ) {
$this->last_error = __( 'Coupon redemption limit is reached.', 'stripe-payments' );
return false;
}
$per_order = get_post_meta( $coupon->ID, 'asp_coupon_per_order', true );
$this->coupon = array(
'code' => $coupon_code,
'id' => $coupon->ID,
'discount' => get_post_meta( $coupon->ID, 'asp_coupon_discount', true ),
'discount_type' => get_post_meta( $coupon->ID, 'asp_coupon_discount_type', true ),
'per_order' => empty( $per_order ) ? 0 : 1,
);
return true;
}
public function check_coupon( $coupon_code = false ) {
if ( ! $coupon_code ) {
$this->last_error = 'No coupon code provided';
return false;
}
$coupon_code = trim( $coupon_code );
$this->load_coupon( $coupon_code );
if ( ! $this->coupon ) {
return false;
}
//check if coupon is allowed for the product
$only_for_allowed_products = get_post_meta( $this->coupon['id'], 'asp_coupon_only_for_allowed_products', true );
if ( $only_for_allowed_products ) {
$allowed_products = get_post_meta( $this->coupon['id'], 'asp_coupon_allowed_products', true );
if ( is_array( $allowed_products ) && ! in_array( strval( $this->post_id ), $allowed_products, true ) ) {
$this->last_error = __( 'Coupon is not allowed for this product.', 'stripe-payments' );
$this->coupon = false;
return false;
}
}
return true;
}
public function get_download_url() {
$post_url = isset( $_POST['asp_item_url'] ) ? sanitize_text_field( stripslashes ( $_POST['asp_item_url'] ) ) : '';
if ( $post_url ) {
$item_url = $post_url;
} else {
$item_url = get_post_meta( $this->post_id, 'asp_product_upload', true );
$item_url = $item_url ? $item_url : '';
if ( ! $item_url ) {
return '';
}
$item_url = base64_encode( $item_url );
}
$item_url = apply_filters(
'asp_item_url_process',
$item_url,
array(
'button_key' => $this->get_button_key(),
'product_id' => $this->post_id,
)
);
$item_url = base64_decode( $item_url );
return $item_url;
}
public function get_button_key() {
if ( ! $this->button_key ) {
// ASP_Debug_Logger::log("Get Button Key - Name:". $this->get_name() . ", Price:", $this->get_price(true));
$this->button_key = md5( htmlspecialchars_decode( $this->get_name() ) . $this->get_price( true ) );
}
return $this->button_key;
}
public function is_physical_product() {
if(!empty($this->get_meta('asp_is_physical_product'))) {
return true;
} else if (!empty($this->get_meta('asp_product_shipping'))) {
return true;
} else if (!empty($this->get_meta('asp_product_shipping_variations'))) {
return true;
}
return false;
}
public function load_from_product( $post_id = false ) {
if ( false === $post_id ) {
$post_id = $this->post_id;
}
if ( false === $post_id ) {
$this->last_error = __( 'No product ID provided.', 'stripe-payments' );
return false;
}
$post_id = intval( $post_id );
$this->post = get_post( $post_id );
if ( ! $this->post || ( get_post_type( $post_id ) !== ASPMain::$products_slug && get_post_type( $post_id ) !== ASPMain::$temp_prod_slug ) ) {
// translators: %d is product id
$this->last_error = sprintf( __( "Can't find product with ID %d", 'stripe-payments' ), $post_id );
ASP_Debug_Logger::log( "Can't find product with ID: " . $post_id, false );
return false;
}
$this->zero_cent = AcceptStripePayments::is_zero_cents( $this->get_currency() );
return true;
}
public function get_meta( $meta, $single = true ) {
return get_post_meta( $this->post_id, $meta, $single );
}
/**
* Calculate regional shipping amount by the provided region.
*
* @param $shipping_region array
* @param $in_cents bool
*
* @return float|int
*/
public function calculate_regional_shipping_amount($shipping_region, $in_cents = false) {
$regional_shipping_amount = 0;
$configured_variations = $this->get_meta('asp_product_shipping_variations');
// Evaluate variable shipping if enabled.
if (is_array($configured_variations) && count($configured_variations)) {
// Iterate through the available shipping variation option to find if there is amy matching.
foreach ($configured_variations as $variation) {
$variation['amount'] = (float) $variation['amount'];
$location = strtolower($variation['loc']);
switch ($variation['type']) {
case '0':
if (!empty($shipping_region['country']) && $location == strtolower($shipping_region['country']) )
// Matched by country, get shipping amount for this location.
$regional_shipping_amount += $variation['amount'];
break;
case '1':
if (!empty($shipping_region['state']) && $location == strtolower($shipping_region['state']) )
// Matched by state, get shipping amount for this location.
$regional_shipping_amount += $variation['amount'];
break;
case '2':
if (!empty($shipping_region['city']) && $location == strtolower($shipping_region['city']) )
// Matched by city, get shipping amount for this location.
$regional_shipping_amount += $variation['amount'];
break;
default:
break;
}
}
}
return $in_cents ? $this->in_cents($regional_shipping_amount) : $regional_shipping_amount;
}
/**
* Validates the total checkout amount for a product against amounts from ajax.
*
* @param int $amount The price to validate.
* @param int $quantity Product quantity.
* @param array $custom_inputs Custom input from customer such as applied coupon code, billing/shipping details, price variation etc.
*
* @return bool TRUE if validation is successful, FALSE otherwise.
*/
public function validate_total_amount( $amount, $quantity, $custom_inputs) {
//ASP_Debug_Logger::log("Amount submitted by customer (in cents): ". $amount, true);
$product_price = (float) $this->get_meta('asp_product_price');
$quantity = (int) $quantity;
$product_price_in_cents = $this->in_cents($product_price);
//ASP_Debug_Logger::log("Raw product price: ". $product_price_in_cents , true);
$this->set_price($product_price_in_cents, true);
$this->set_quantity( $quantity );
$price_variation = $custom_inputs['price_variation'];
if ( isset($price_variation) && !empty( $price_variation ) ) {
$variations_groups = $this->get_meta('asp_variations_groups');
$variations_names = $this->get_meta('asp_variations_names');
$variations_prices = $this->get_meta('asp_variations_prices');
$construct_final_price = ! empty( $this->get_meta('asp_product_hide_amount_input') );
$pvars = explode(',', $price_variation ); // Hold data like this: ['<group_name>-<applied_option>', ....]
$variation_price = 0;
foreach ($pvars as $pvar_str) {
$separator = '_';
// Use the last index of the separator to explode the $pvar_str. This is to avoid collision if $pvar_str contains (from the group name) more than one $separator.
$last_separator_index = strrpos($pvar_str, $separator);
$option_group = substr($pvar_str, 0, $last_separator_index); // Group name;
$applied_option = (int) substr($pvar_str, $last_separator_index + strlen($separator));// Applied option
$group_index = array_search($option_group, $variations_groups);
$applied_price = (float) $variations_prices[$group_index][$applied_option];
$applied_price = $this->in_cents( $applied_price );
$variation_price += $applied_price;
// ASP_Debug_Logger::log("Applied variation price for ". $variations_names[$group_index][$applied_option]. ' : ' .$applied_price, true);
}
// ASP_Debug_Logger::log("Applied total variation price : ". $variation_price, true);
$price_with_applied_variation = 0;
if ($construct_final_price) {
$price_with_applied_variation = $variation_price;
}else{
$price_with_applied_variation = $variation_price + $product_price_in_cents;
}
$this->set_price($price_with_applied_variation, true);
// ASP_Debug_Logger::log("Applied total variation price with base price : ". $price_with_applied_variation, true);
}
// ASP_Debug_Logger::log("Amount current total (after price variation): ". $this->get_total(true), true);
$tax_variations_type = $this->get_meta('asp_product_tax_variations_type');
$tax_variations_arr = $this->get_meta('asp_product_tax_variations');
$collect_billing_addr_enabled = $this->get_meta('asp_product_collect_billing_addr');
$collect_shipping_addr_enabled = $this->get_meta('asp_product_collect_shipping_addr');
// ASP_Debug_Logger::log("Applied tax amount (before tax variation apply): ". $this->get_tax_amount(true), true);
// Evaluate variable tax if enabled.
if (is_array($tax_variations_arr) && count($tax_variations_arr) && $collect_billing_addr_enabled === '1') {
$applied_tax_percentage = 0;
$tax_region = ($tax_variations_type === 's' && $collect_shipping_addr_enabled === '1') ? $custom_inputs['shipping_details']['address'] : $custom_inputs['billing_details']['address'];
// Iterate through the available tax variation option to find if there is amy matching.
foreach ($tax_variations_arr as $tax_variation) {
$tax_variation['amount'] = (float) $tax_variation['amount'];
switch ($tax_variation['loc']) {
case $tax_region['city']:
// Matched by city, get tax amount for this location.
$applied_tax_percentage += $tax_variation['amount'];
break;
case $tax_region['state']:
// Matched by state, get tax amount for this location.
$applied_tax_percentage += $tax_variation['amount'];
break;
case $tax_region['country']:
// Matched by country, get tax amount for this location.
$applied_tax_percentage += $tax_variation['amount'];
break;
}
}
if ($applied_tax_percentage > 0) {
$this->set_tax($applied_tax_percentage);
}
}
//ASP_Debug_Logger::log("Applied tax amount (after tax variation): ". $this->get_tax_amount(true), true);
//ASP_Debug_Logger::log("Amount current total (after tax variation): ". $this->get_total(true), true);
$base_shipping_amount = get_post_meta( $this->post_id, 'asp_product_shipping', true );
if (empty($base_shipping_amount)){
$base_shipping_amount = 0;
} else {
$base_shipping_amount = $this->in_cents(floatval($base_shipping_amount));
}
$shipping_amount = $base_shipping_amount;
$collect_shipping_addr_enabled = $this->get_meta('asp_product_collect_shipping_addr');
if ( $collect_shipping_addr_enabled == '1'){
$regional_shipping_amount = $this->calculate_regional_shipping_amount($custom_inputs['shipping_details']['address'], true);
$shipping_amount += $regional_shipping_amount;
}
$this->set_shipping( $shipping_amount, true );
//ASP_Debug_Logger::log("Amount current total (after base shipping): ". $this->get_total(true), true);
$coupon_code = $custom_inputs['coupon_code'];
if ( !empty( $coupon_code ) ) {
// Get the coupon and evaluate it (if submitted).
if ( !$this->load_coupon( $coupon_code ) ) {
// Invalid coupon. The 'load_coupon' method will handle appending appropriate error message.
return false;
};
}
// Calculate the expected total amount.
$expected_total_amount = $this->get_total(true);
// Check if surcharge feature is enabled.
if ( !empty($this->get_surcharge()) ){
// Surcharge is enabled. Calculate the surcharge amount then adjust the expected total.
$surcharge_amount = round($this->calculate_total_surcharge(true));//This is in cents so round it to 0 decimal place.
ASP_Debug_Logger::log("The surcharge feature is enabled. Applied surcharge amount (in cents): ". $surcharge_amount, true);
$expected_total_amount += $surcharge_amount;
}
// Trigger a filter so addons can override it.
$expected_total_amount = apply_filters('asp_pre_api_submission_expected_amount', $expected_total_amount, $amount, $this->post_id);
// Check if the expected total amount matches the given amount.
if ( $amount != $expected_total_amount ){
ASP_Debug_Logger::log("Pre-API Submission validation amount mismatch. Expected amount (in cents): ". $expected_total_amount . ", Submitted amount (in cents): " . $amount, false);
// Set the last error message that will be displayed to the user.
$mismatch_err_msg = __( "Price validation failed. The submitted amount does not match the product's configured price. ", 'stripe-payments' );
$mismatch_err_msg .= "Expected: " . $this->from_cents($expected_total_amount) . ", Submitted: " . $this->from_cents($amount);
$this->last_error = $mismatch_err_msg;
return false;
}
ASP_Debug_Logger::log("Pre-API Submission validation successful. Expected: " . $this->from_cents($expected_total_amount) . ", Submitted: " . $this->from_cents($amount), true);
return true;
}
}