Overview
↑ Back to topThe 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 topWooCommerce 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 topNYP settings are stored in WordPress post meta and accessed through the WooCommerce product object:
| Meta Key | Description | Type |
|---|---|---|
_nyp | Enables NYP for this product | 'yes' or 'no' |
_suggested_price | Suggested/default price shown to customers | Decimal (as string) |
_min_price | Minimum acceptable price | Decimal (as string) |
_maximum_price | Maximum acceptable price | Decimal (as string) |
_hide_nyp_minimum | Hide 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 topWhen a customer enters a custom price:
- Cart: The entered price is stored in
$cart_item['nyp']within the cart session - Orders: The NYP price becomes the line item’s price and is saved as part of the order item meta
- Persistence: The
nypvalue is preserved through the entire purchase flow
UsWooCommerce REST API (v3/v4)
↑ Back to topProducts Endpoint
↑ Back to topGet 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:
| Field | Type | Description |
|---|---|---|
nyp | boolean | Whether NYP is enabled for this product |
nyp_suggested_price | string | Suggested price (may be empty string if not set) |
nyp_minimum_price | string | Minimum acceptable price (may be empty string if not set) |
nyp_maximum_price | string | Maximum acceptable price (may be empty string if not set) |
nyp_hide_minimum | boolean | Whether 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:
- โ
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.”
- Error:
- โ
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.”
- Error:
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 topNYP 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 topNYP 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, andtotal(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 topThe Store API is designed for modern, customer-facing applications like WooCommerce Blocks and headless storefronts.
Products Endpoint
↑ Back to topGet 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:
- Prices are in minor units (cents for USD, pence for GBP, etc.)
"minimum_price": "1000"= $10.00 USD"suggested_price": "5000"= $50.00 USD
- Currency formatting included โ Use the provided currency data to format prices correctly for display
- Null values possible:
suggested_pricecan benullif not setmaximum_pricecan benullif not setminimum_pricedefaults to0if not set
Cart Endpoints
↑ Back to topAdd NYP Product to Cart
POST /wp-json/wc/store/v1/cart/add-item
Request Body:
{
"id": 123,
"quantity": 1,
"nyp": "7500"
}
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Product ID |
quantity | integer | Yes | Quantity to add |
nyp | string | Yes (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 topClient-Side Price Validation
↑ Back to topWhen 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 topThe 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_minimumsetting
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 topREST 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 topExample 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 topimport 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 top1. Always Validate on Both Client and Server
↑ Back to topWhile 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 topREST 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) / 100when receiving
3. Check NYP Status Before Displaying Input
↑ Back to topNot 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 topWhen 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 topWhen 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 topFor 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_periodparameter if using variable billing
7. Test Error Scenarios
↑ Back to topTest 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 topIssue: NYP fields not appearing in REST API response
↑ Back to topCause: 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 topCauses:
- Price is below minimum
- Price is above maximum
- Price is not numeric
- 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 topCause: 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 topCauses:
- Insufficient authentication/permissions
- Product type doesn’t support NYP
- 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 topCause: 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 topOfficial Documentation
↑ Back to topDeveloper Tools
↑ Back to top- WooCommerce REST API Client (JavaScript)
- WooCommerce REST API Postman Collection
- WordPress REST API Handbook
Code Examples
↑ Back to topQuestions & Support
↑ Back to topSomething Missing?
↑ Back to topDo 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 topHave 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 topAlready 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+