phpwordpresswoocommercewoocommerce-rest-api

How to Show Order Totals with Decimals in WooCommerce REST API Response


I'm working on a WooCommerce store with a multi-currency setup. My store's default currency is Japanese Yen, and I have the price decimal setting in the WooCommerce dashboard set to 0 to avoid showing decimals for JPY prices. However, I also sell in other currencies (e.g., USD), and I need the WooCommerce REST API to return order totals with 2 decimal places for those currencies.

The issue is that when I retrieve order data via the WooCommerce REST API (e.g., /wp-json/wc/v3/order/{id}), the total fields are rounded up to integers for all currencies, even for currencies like USD, where decimals are important.

What I’m Trying to Achieve:
Keep the WooCommerce dashboard and storefront displaying prices without decimals for JPY. Ensure the WooCommerce REST API returns order totals with 2 decimal places for currencies that require it (e.g., USD).

What I’ve Tried:
I attempted to use the woocommerce_rest_prepare_shop_order_object filter to modify the total field in the API response. Here’s the code I’ve used:

add_filter( 'woocommerce_rest_prepare_shop_order_object', 'modify_order_total_in_api', 10, 3 );

function modify_order_total_in_api( $response, $order, $request ) {

    // Check if the total exists
    if ( isset( $response->data['total'] ) ) {
        // Format the total with 2 decimals
        $response->data['total'] = number_format( $order->get_total(), 2, '.', '' );
    }

    return $response;
}

What Happens:

Additional Context:

Questions:

Any help would be greatly appreciated!


Solution

  • The issue might arises when a product's price is rounded and stored in an order, making it challenging to replicate the same rounding method in an external system.

    Instead you can do the following:

    1. Go to your store settings and set decimals to 2.
    2. Use the filter woocommerce_price_trim_zeros

    You can use below code in your functions.php file to trim your decimals on the price in your store, while maintaining the 2 decimals for your API:

    /* Hide trailing zeros on prices */
    add_filter( 'woocommerce_price_trim_zeros', '__return_true' );
    

    You can read more about the woocommerce_price_trim_zeros filter in the woocommerce documentation

    This way you ensure the API respects the currency’s decimal settings, while keeping the dashboard and storefront settings at 0 decimals.

    If you need to apply this to only 1 currency like the JPY, you can use conditional check within the filter. Example:

    add_filter( 'woocommerce_price_trim_zeros', 'trim_zeros_for_jpy' );
    
    function trim_zeros_for_jpy( $trim ) {
        $currency = get_woocommerce_currency();
        if ( $currency === 'JPY' ) {
            return true;
        }
        return false;
    }