Name Your Price: REST & Store API Reference

Overview

↑ Back to top

The WooCommerce REST API lets you create, read, update, and delete data related to your Name Your Price (NYP) products. NYP extends the core WooCommerce REST API by adding custom fields to existing endpoints rather than creating new endpoints.

This guide covers both:

  • WooCommerce REST API (v3/v4) โ€” Traditional REST API for products, orders, and variations
  • WooCommerce Store API โ€” Modern API introduced in WooCommerce 7.0+ for blocks and headless commerce

Key Principle: NYP data is seamlessly integrated into standard WooCommerce endpoints, so you can manage Name Your Price functionality using familiar REST API patterns.


API Version Compatibility

↑ Back to top

WooCommerce REST API (v3/v4)

↑ Back to top
  • Endpoint Base: /wp-json/wc/v3/
  • Authentication: OAuth 1.0a or Application Passwords (WordPress 5.6+)
  • Use Cases: Admin interfaces, mobile apps, third-party integrations
  • NYP Support: Full read/write access to NYP product settings

WooCommerce Store API (v1)

↑ Back to top
  • Endpoint Base: /wp-json/wc/store/v1/
  • Authentication: Nonce-based (for logged-in users) or public access
  • Use Cases: WooCommerce Blocks, headless storefronts, modern cart/checkout
  • NYP Support: Read-only product data, full cart management with NYP prices

Recommendation: Use the Store API for customer-facing applications (storefronts, carts, checkout) and the traditional REST API for administrative tasks (product management, reporting).


How NYP Data is Stored

↑ Back to top

NYP settings are stored in WordPress post meta and accessed through the WooCommerce product object:

Meta KeyDescriptionType
_nypEnables NYP for this product'yes' or 'no'
_suggested_priceSuggested/default price shown to customersDecimal (as string)
_min_priceMinimum acceptable priceDecimal (as string)
_maximum_priceMaximum acceptable priceDecimal (as string)
_hide_nyp_minimumHide minimum price on frontend'yes' or 'no'

Important: While these are the underlying meta fields, the REST API exposes them as cleaner, top-level properties (see below).

Cart & Order Storage

↑ Back to top

When a customer enters a custom price:

  1. Cart: The entered price is stored in $cart_item['nyp'] within the cart session
  2. Orders: The NYP price becomes the line item’s price and is saved as part of the order item meta
  3. Persistence: The nyp value is preserved through the entire purchase flow

UsWooCommerce REST API (v3/v4)

↑ Back to top

Products Endpoint

↑ Back to top

Get a Product

GET /wp-json/wc/v3/products/{id}

Response includes NYP fields:

{
  "id": 123,
  "name": "Custom Donation",
  "type": "simple",
  "nyp": true,
  "nyp_suggested_price": "50.00",
  "nyp_minimum_price": "10.00",
  "nyp_maximum_price": "1000.00",
  "nyp_hide_minimum": false,
  "price": "10.00",
  "regular_price": "10.00",
  ...
}

NYP-Specific Fields:

FieldTypeDescription
nypbooleanWhether NYP is enabled for this product
nyp_suggested_pricestringSuggested price (may be empty string if not set)
nyp_minimum_pricestringMinimum acceptable price (may be empty string if not set)
nyp_maximum_pricestringMaximum acceptable price (may be empty string if not set)
nyp_hide_minimumbooleanWhether to hide the minimum price from customers

Note on price field: For NYP products, the price and regular_price are automatically set to the minimum price (or suggested price if the wc_nyp_sort_by_suggested_price filter is enabled). This allows WooCommerce to properly sort products by price.

Create/Update a Product

POST /wp-json/wc/v3/products
PUT /wp-json/wc/v3/products/{id}

Request Body:

{
  "name": "Support the Project",
  "type": "simple",
  "nyp": true,
  "nyp_suggested_price": "25",
  "nyp_minimum_price": "5",
  "nyp_maximum_price": "500",
  "nyp_hide_minimum": false
}

Validation Rules (Server-Side):

The REST API automatically validates NYP prices:

  1. โœ… Suggested โ‰ฅ Minimum: If both are set, suggested price must be greater than or equal to minimum
    • Error: woocommerce_rest_product_nyp_invalid_minimum_price
    • Message: “The suggested price must be higher than the minimum for Name Your Price products.”
  2. โœ… Maximum โ‰ฅ Minimum: If both are set, maximum price must be greater than or equal to minimum
    • Error: woocommerce_rest_product_nyp_invalid_maximum_price
    • Message: “The maximum price must be higher than the minimum for Name Your Price products.”

Example Error Response:

{
  "code": "woocommerce_rest_product_nyp_invalid_minimum_price",
  "message": "The suggested price must be higher than the minimum for Name Your Price products.",
  "data": {
    "status": 404
  }
}

Variations Endpoint

↑ Back to top

NYP fully supports variable products. Each variation can have its own NYP settings.

Get Product Variations

GET /wp-json/wc/v3/products/{product_id}/variations

Response:

[
  {
    "id": 456,
    "product_id": 123,
    "attributes": [
      {
        "id": 1,
        "name": "Size",
        "option": "Small"
      }
    ],
    "nyp": true,
    "nyp_suggested_price": "20.00",
    "nyp_minimum_price": "10.00",
    "nyp_maximum_price": "100.00",
    "nyp_hide_minimum": false,
    ...
  }
]

Update a Variation

PUT /wp-json/wc/v3/products/{product_id}/variations/{id}

Request Body:

{
  "nyp": true,
  "nyp_suggested_price": "15",
  "nyp_minimum_price": "5",
  "nyp_maximum_price": "50"
}

Orders Endpoint

↑ Back to top

NYP prices are stored as part of the line item data in orders.

Get an Order

GET /wp-json/wc/v3/orders/{id}

Response (excerpt):

{
  "id": 789,
  "line_items": [
    {
      "id": 1,
      "product_id": 123,
      "name": "Custom Donation",
      "quantity": 1,
      "subtotal": "75.00",
      "total": "75.00",
      "price": 75.00,
      "meta_data": []
    }
  ],
  ...
}

Key Points:

  • The customer’s entered price becomes the line item’s price, subtotal, and total (before taxes/fees)
  • The original NYP product settings are not stored in order meta โ€” only the final entered price
  • When using “Order Again”, NYP recalculates the price from the line item subtotal (accounting for taxes if needed)

WooCommerce Store API (v1)

↑ Back to top

The Store API is designed for modern, customer-facing applications like WooCommerce Blocks and headless storefronts.

Products Endpoint

↑ Back to top

Get Products

GET /wp-json/wc/store/v1/products
GET /wp-json/wc/store/v1/products/{id}

Response Format:

NYP data is returned in the extensions.name_your_price namespace:

{
  "id": 123,
  "name": "Custom Donation",
  "prices": {
    "price": "1000",
    "regular_price": "1000",
    "currency_code": "USD",
    "currency_symbol": "$",
    "currency_decimal_separator": ".",
    "currency_thousand_separator": ",",
    "currency_minor_unit": 2
  },
  "extensions": {
    "name_your_price": {
      "is_nyp": true,
      "hide_minimum": false,
      "prices": {
        "suggested_price": "5000",
        "minimum_price": "1000",
        "maximum_price": "100000",
        "currency_code": "USD",
        "currency_symbol": "$",
        "currency_decimal_separator": ".",
        "currency_thousand_separator": ",",
        "currency_minor_unit": 2
      }
    }
  }
}

Important Store API Pricing Notes:

  1. Prices are in minor units (cents for USD, pence for GBP, etc.)
    • "minimum_price": "1000" = $10.00 USD
    • "suggested_price": "5000" = $50.00 USD
  2. Currency formatting included โ€” Use the provided currency data to format prices correctly for display
  3. Null values possible:
    • suggested_price can be null if not set
    • maximum_price can be null if not set
    • minimum_price defaults to 0 if not set

Cart Endpoints

↑ Back to top

Add NYP Product to Cart

POST /wp-json/wc/store/v1/cart/add-item

Request Body:

{
  "id": 123,
  "quantity": 1,
  "nyp": "7500"
}

Parameters:

FieldTypeRequiredDescription
idintegerYesProduct ID
quantityintegerYesQuantity to add
nypstringYes (for NYP products)Customer’s price in minor units (e.g., “7500” = $75.00)

Important: The nyp parameter must be a string representing the price in the currency’s minor units (cents, pence, etc.). The Store API will validate this price against the product’s min/max constraints.

Success Response:

{
  "key": "abc123",
  "id": 123,
  "quantity": 1,
  "prices": {
    "price": "7500",
    "line_price": "7500",
    ...
  },
  "extensions": {
    "name_your_price": {
      "nyp": "7500",
      "currency_code": "USD",
      ...
    }
  },
  ...
}

Get Cart

GET /wp-json/wc/store/v1/cart

Response (excerpt):

{
  "items": [
    {
      "key": "abc123",
      "id": 123,
      "name": "Custom Donation",
      "quantity": 1,
      "prices": {
        "price": "7500",
        "line_price": "7500",
        ...
      },
      "short_description": "<p class=\"wc-block-cart-item__edit\"><a class=\"components-button wc-block-components-button wp-element-button outlined wc-block-cart-item__edit-link contained\" href=\"...\">Edit price</a></p>",
      "extensions": {
        "name_your_price": {
          "nyp": "7500",
          "currency_code": "USD",
          "currency_symbol": "$",
          "currency_decimal_separator": ".",
          "currency_thousand_separator": ",",
          "currency_minor_unit": 2
        }
      }
    }
  ],
  ...
}

Cart Editing: If the NYP setting “Allow editing in cart” is enabled, an “Edit price” button will be automatically added to the short_description field, allowing customers to modify their entered price.


Validation & Error Handling

↑ Back to top

Client-Side Price Validation

↑ Back to top

When adding an NYP product to cart (via either API), you should validate the entered price on the client side first for better UX:

// Example: Validate NYP price before submission
function validateNYPPrice(enteredPrice, minPrice, maxPrice) {
  const price = parseFloat(enteredPrice);
  
  // Check for valid positive number
  if (isNaN(price) || price < 0 || !isFinite(price)) {
    return {
      valid: false,
      message: 'Please enter a valid, positive number.'
    };
  }
  
  // Check minimum
  if (minPrice && price < parseFloat(minPrice)) {
    return {
      valid: false,
      message: `Please enter at least ${formatPrice(minPrice)}.`
    };
  }
  
  // Check maximum
  if (maxPrice && price > parseFloat(maxPrice)) {
    return {
      valid: false,
      message: `Please enter less than or equal to ${formatPrice(maxPrice)}.`
    };
  }
  
  return { valid: true };
}

Server-Side Validation Rules

↑ Back to top

The server performs comprehensive validation when adding NYP products to cart:

1. Numeric & Positive Check

  • Price must be a valid number
  • Price must be positive (โ‰ฅ 0)
  • Price must not be infinite

Error Message: “Please enter a valid, positive number.”

2. Minimum Price Validation

  • If a minimum is set, entered price must be โ‰ฅ minimum
  • Error message varies based on hide_minimum setting

Error Messages:

  • If minimum is hidden: “Please enter a higher amount.”
  • If minimum is visible: “Please enter at least {minimum price}.”

3. Maximum Price Validation

  • If a maximum is set, entered price must be โ‰ค maximum

Error Message: “Please enter less than or equal to {maximum price}.”

4. Variable Billing Period Validation (Subscriptions)

  • For subscription products with variable billing periods, NYP validates the annualized price
  • This ensures a customer can’t circumvent minimum pricing by choosing a longer billing period

Error Response Formats

↑ Back to top

REST API (v3/v4) Errors

When validation fails during product update:

{
  "code": "woocommerce_rest_product_nyp_invalid_minimum_price",
  "message": "The suggested price must be higher than the minimum for Name Your Price products.",
  "data": {
    "status": 404
  }
}

Store API Errors

When validation fails during add-to-cart:

{
  "code": "woocommerce_store_api_invalid_product_price",
  "message": "Please enter at least $10.00.",
  "data": {
    "status": 500
  }
}

When validation fails during cart validation (checkout):

{
  "code": "woocommerce_cart_error",
  "message": "\"Custom Donation\" cannot be purchased. Please enter at least $10.00.",
  "data": {
    "status": 409
  }
}

Code Examples

↑ Back to top

Example 1: Get All NYP Products

↑ Back to top
// Using WooCommerce REST API v3
const WooCommerceRestApi = require("@woocommerce/woocommerce-rest-api").default;

const api = new WooCommerceRestApi({
  url: "https://example.com",
  consumerKey: "ck_xxxxxxxxxxxx",
  consumerSecret: "cs_xxxxxxxxxxxx",
  version: "wc/v3"
});

// Fetch all products
const response = await api.get("products", {
  per_page: 100
});

// Filter for NYP products
const nypProducts = response.data.filter(product => product.nyp === true);

console.log('Found', nypProducts.length, 'NYP products');

Example 2: Create an NYP Product

↑ Back to top
// Create a new NYP product
const productData = {
  name: "Tip the Developer",
  type: "simple",
  status: "publish",
  nyp: true,
  nyp_suggested_price: "10",
  nyp_minimum_price: "1",
  nyp_maximum_price: "100",
  nyp_hide_minimum: false,
  description: "Show your appreciation with a custom tip!",
  short_description: "Pay what you feel it's worth"
};

api.post("products", productData)
  .then(response => {
    console.log('Created NYP product:', response.data.id);
  })
  .catch(error => {
    console.error('Error:', error.response.data);
  });

Example 3: Update NYP Settings for Existing Product

↑ Back to top
// Update an existing product to enable NYP
const productId = 123;

const updates = {
  nyp: true,
  nyp_suggested_price: "50",
  nyp_minimum_price: "25"
};

api.put(`products/${productId}`, updates)
  .then(response => {
    console.log('Updated product:', response.data.name);
    console.log('NYP enabled:', response.data.nyp);
    console.log('Suggested price:', response.data.nyp_suggested_price);
  })
  .catch(error => {
    console.error('Error:', error.response.data);
  });

Example 4: Add NYP Product to Cart (Store API)

↑ Back to top
// Add an NYP product to cart with custom price
// Note: Store API uses nonces for authentication in WordPress context

async function addNYPToCart(productId, customPrice) {
  // Convert price to minor units (cents)
  const priceInCents = Math.round(customPrice * 100).toString();
  
  const response = await fetch('/wp-json/wc/store/v1/cart/add-item', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Nonce': wpApiSettings.nonce // WordPress nonce
    },
    body: JSON.stringify({
      id: productId,
      quantity: 1,
      nyp: priceInCents
    })
  });
  
  const data = await response.json();
  
  if (!response.ok) {
    throw new Error(data.message || 'Failed to add to cart');
  }
  
  return data;
}

// Usage
try {
  const result = await addNYPToCart(123, 75.50); // $75.50
  console.log('Added to cart:', result.key);
} catch (error) {
  console.error('Validation error:', error.message);
  // Display error to user: "Please enter at least $10.00"
}

Example 5: Fetch NYP Product Data (Store API)

↑ Back to top
// Fetch product with NYP data using Store API
async function getNYPProductData(productId) {
  const response = await fetch(`/wp-json/wc/store/v1/products/${productId}`);
  const product = await response.json();
  
  if (product.extensions?.name_your_price?.is_nyp) {
    const nypData = product.extensions.name_your_price;
    const prices = nypData.prices;
    
    // Convert from minor units to major units (cents to dollars)
    const minorUnit = prices.currency_minor_unit; // e.g., 2 for USD
    const divisor = Math.pow(10, minorUnit);
    
    return {
      isNYP: true,
      suggested: prices.suggested_price ? parseInt(prices.suggested_price) / divisor : null,
      minimum: prices.minimum_price ? parseInt(prices.minimum_price) / divisor : 0,
      maximum: prices.maximum_price ? parseInt(prices.maximum_price) / divisor : null,
      hideMinimum: nypData.hide_minimum,
      currencySymbol: prices.currency_symbol,
      currencyCode: prices.currency_code
    };
  }
  
  return { isNYP: false };
}

// Usage
const nypInfo = await getNYPProductData(123);
console.log('Minimum:', nypInfo.currencySymbol + nypInfo.minimum);
console.log('Suggested:', nypInfo.suggested ? nypInfo.currencySymbol + nypInfo.suggested : 'None');

Example 6: Bulk Update NYP Products

↑ Back to top
// Batch update multiple products to set minimum prices
async function bulkUpdateMinimumPrices(productIds, newMinimum) {
  const batch = {
    update: productIds.map(id => ({
      id: id,
      nyp_minimum_price: newMinimum.toString()
    }))
  };
  
  const response = await api.post('products/batch', batch);
  
  console.log('Updated:', response.data.update.length, 'products');
  
  // Check for errors
  response.data.update.forEach(product => {
    if (product.error) {
      console.error(`Product ${product.id} error:`, product.error.message);
    }
  });
  
  return response.data;
}

// Update products 101, 102, 103 to have $5 minimum
await bulkUpdateMinimumPrices([101, 102, 103], "5");

Example 7: React Component for NYP Input

↑ Back to top
import React, { useState } from 'react';

function NYPPriceInput({ product }) {
  const [price, setPrice] = useState(product.nyp_suggested_price || '');
  const [error, setError] = useState('');
  
  const handlePriceChange = (e) => {
    const value = e.target.value;
    setPrice(value);
    setError('');
  };
  
  const validatePrice = () => {
    const numPrice = parseFloat(price);
    const min = parseFloat(product.nyp_minimum_price);
    const max = parseFloat(product.nyp_maximum_price);
    
    if (isNaN(numPrice) || numPrice < 0) {
      setError('Please enter a valid, positive number.');
      return false;
    }
    
    if (min && numPrice < min) {
      setError(`Please enter at least $${min.toFixed(2)}.`);
      return false;
    }
    
    if (max && numPrice > max) {
      setError(`Please enter less than or equal to $${max.toFixed(2)}.`);
      return false;
    }
    
    return true;
  };
  
  const handleSubmit = async (e) => {
    e.preventDefault();
    
    if (!validatePrice()) {
      return;
    }
    
    // Add to cart via Store API
    try {
      const priceInCents = Math.round(parseFloat(price) * 100).toString();
      
      const response = await fetch('/wp-json/wc/store/v1/cart/add-item', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Nonce': wpApiSettings.nonce
        },
        body: JSON.stringify({
          id: product.id,
          quantity: 1,
          nyp: priceInCents
        })
      });
      
      if (!response.ok) {
        const data = await response.json();
        setError(data.message);
        return;
      }
      
      // Success! Redirect to cart or show confirmation
      window.location.href = '/cart';
      
    } catch (err) {
      setError('An error occurred. Please try again.');
    }
  };
  
  return (
    <form onSubmit={handleSubmit} className="nyp-form">
      <div className="nyp-price-input">
        <label htmlFor="nyp-price">Name Your Price</label>
        
        {product.nyp_minimum_price && !product.nyp_hide_minimum && (
          <p className="nyp-minimum">
            Minimum: ${parseFloat(product.nyp_minimum_price).toFixed(2)}
          </p>
        )}
        
        {product.nyp_suggested_price && (
          <p className="nyp-suggested">
            Suggested: ${parseFloat(product.nyp_suggested_price).toFixed(2)}
          </p>
        )}
        
        <div className="price-input-wrapper">
          <span className="currency-symbol">$</span>
          <input
            id="nyp-price"
            type="number"
            step="0.01"
            min="0"
            value={price}
            onChange={handlePriceChange}
            placeholder="Enter amount"
            required
          />
        </div>
        
        {error && <p className="error">{error}</p>}
      </div>
      
      <button type="submit" className="add-to-cart-button">
        Add to Cart
      </button>
    </form>
  );
}

export default NYPPriceInput;

Best Practices

↑ Back to top

1. Always Validate on Both Client and Server

↑ Back to top

While NYP performs server-side validation, implement client-side validation for better UX:

  • Provide immediate feedback to customers
  • Reduce unnecessary API calls
  • Display helpful error messages before submission

2. Handle Price Formatting Correctly

↑ Back to top

REST API (v3/v4):

  • Prices are decimal strings: "50.00"
  • Use parseFloat() for calculations
  • Format for display using toFixed(2)

Store API:

  • Prices are in minor units (integers as strings): "5000" = $50.00
  • Always convert: Math.round(price * 100) when sending
  • Always convert back: parseInt(price) / 100 when receiving

3. Check NYP Status Before Displaying Input

↑ Back to top

Not all products are NYP products:

if (product.nyp === true) {
  // Show NYP price input
} else {
  // Show standard add-to-cart button
}

4. Respect the hide_minimum Setting

↑ Back to top

When nyp_hide_minimum is true, don’t display the minimum price to customers. This is typically used for donations where the merchant wants to encourage higher contributions.

5. Use Batch Endpoints for Multiple Updates

↑ Back to top

When updating multiple products, use the batch endpoint to improve performance:

// Good: Batch update
api.post('products/batch', { update: [/* array of products */] });

// Avoid: Individual updates in a loop
products.forEach(p => api.put(`products/${p.id}`, updates));

6. Handle Subscription-Specific Validation

↑ Back to top

For WooCommerce Subscriptions integration, remember that NYP validates annualized prices for variable billing periods. Your frontend should:

  • Display the selected billing period
  • Validate accordingly
  • Pass the nyp_period parameter if using variable billing

7. Test Error Scenarios

↑ Back to top

Test your integration with edge cases:

  • โŒ Negative prices
  • โŒ Non-numeric input
  • โŒ Prices below minimum
  • โŒ Prices above maximum
  • โŒ Empty/null prices
  • โœ… Prices exactly at minimum/maximum boundaries

Troubleshooting Common Issues

↑ Back to top

Issue: NYP fields not appearing in REST API response

↑ Back to top

Cause: Product type might not support NYP.

Supported Types:

  • Simple
  • Subscription
  • Bundle
  • Composite
  • Mix and Match
  • Variation
  • Subscription Variation
  • Deposit

Solution: Check product.type and ensure it’s in the supported list.


Issue: “Invalid product price” error when adding to cart

↑ Back to top

Causes:

  1. Price is below minimum
  2. Price is above maximum
  3. Price is not numeric
  4. Price format is incorrect (Store API requires minor units)

Solution: Validate price on client side first, ensure correct format for the API you’re using.


Issue: Store API prices seem wrong (off by 100x)

↑ Back to top

Cause: Store API uses minor units (cents, not dollars).

Solution:

// Convert TO Store API format (dollars โ†’ cents)
const priceInCents = Math.round(dollarAmount * 100).toString();

// Convert FROM Store API format (cents โ†’ dollars)
const dollarAmount = parseInt(priceInCents) / 100;

Issue: Can’t update NYP settings via REST API

↑ Back to top

Causes:

  1. Insufficient authentication/permissions
  2. Product type doesn’t support NYP
  3. Validation failing (suggested < minimum, maximum < minimum)

Solution: Check error response code and message. Ensure your prices satisfy validation rules.


Issue: Cart shows wrong price for NYP product

↑ Back to top

Cause: The nyp parameter wasn’t included when adding to cart, or contained invalid data.

Solution: Always include the nyp parameter when adding NYP products to cart:

// Correct
{ id: 123, quantity: 1, nyp: "5000" }

// Wrong - will fail validation
{ id: 123, quantity: 1 }

Things to Keep in Mind

↑ Back to top
  • Validation: The extension performs server-side validation of entered prices. Always validate input when adding items via a custom integration.
  • Custom Front-End: If youโ€™re building a custom front-end that uses the REST API, ensure the price field is included and validated before sending to the cart/order.
  • Compatibility: Some third-party plugins may affect how custom prices are handled via the API.

Resources

↑ Back to top

Official Documentation

↑ Back to top

Developer Tools

↑ Back to top

Code Examples

↑ Back to top

Questions & Support

↑ Back to top

Something Missing?

↑ Back to top

Do you still have questions and need assistance? If you run into issues working with Name Your Price and the REST API, please reach out to support with:

  • The REST API endpoint and method you’re using
  • The complete request body (with sensitive data redacted)
  • The full error response
  • The NYP product settings (screenshots helpful)
  • WordPress/WooCommerce/NYP version numbers

Pre-Sales Questions

↑ Back to top

Have a question before you buy this extension? Please fill out this pre-sales form and include “Name Your Price” in your query.

Technical Support

↑ Back to top

Already purchased and need assistance? Get in touch with the developer via the WooCommerce.com Support page and choose “Name Your Price” from the “I need help with” dropdown. Please include a clear description of the issue and any relevant code snippets.


Document Version: 1.0
Last Updated: February 2026
NYP Version Covered: 3.7.2+