Discounts with Direct Order Submission
Direct Order Submission supports two powerful discount mechanisms to give you maximum flexibility in your pricing strategy:
Synced Discounts (Promo Codes) — merchant-managed codes validated against the merchant's e-commerce platform
Custom Discounts — channel-defined amounts/percentages that Violet applies without merchant validation
Whether you want to honor existing merchant promotions or create your own channel-specific deals, we've got you covered.
Quick Overview
One discount per merchant per request for both synced codes and custom discounts
Target different parts of the Order: Apply discounts at order level, shipping level, or SKU level
Apply amount or percentage-based Discounts: Pass in fixed amount discounts (in fractional currency unit, e.g. cents) or percentage-based discounts (e.g. 15% off)
Preview Discounts using Estimate Cart: Use Estimate Cart to evaluate discount impact before creating orders
Choosing Synced vs Custom
Who defines logic
Merchant platform
Channel
Validation source
Merchant platform
Violet (no merchant validation)
Targets
As platform rules allow
ORDER
, SKU
, SHIPPING
Typical use
Honor existing promos
Channel-led campaigns, subsidies
Failure Scenarios
INVALID
, EXPIRED
, NOT_SUPPORTED
discount codes
Failures due to discount amounts being greater than specified target; NOT_SUPPORTED
by platform
Synced Discounts (Promo Codes)
Synced discounts let you honor merchant-managed promo codes while applying them to your custom pricing. Violet validates these codes against the merchant's platform and applies the resulting discount according to their rules.
Key Benefits
Honor merchant promotions while using your own pricing
Automatic validation against the merchant's platform
Correct application at the right level (bag/SKU) based on merchant rules
Requirements
One code per merchant per request — multiple codes for the same merchant will result in a
400 Bad Request
merchant_id
is required for Estimate Cart requests to identify which merchant the code belongs to.Code must exist and be valid in the merchant's platform.
Platform Support
Supported Platforms
Shopify
WooCommerce
BigCommerce
Magento
Ecwid
Platforms Coming Soon
Wix
Estimate Cart with Promo Codes
Pass promo codes at the top level of your request:
{
"base_currency": "USD",
"skus": [
{
"quantity": 1,
"sku_id": 1,
"price": 1000
},
{
"quantity": 1,
"sku_id": 2,
"price": 2000
}
],
"discounts": [
{
"merchant_id": 11111,
"code": "PIEDPIPERCLUB"
}
],
"shipping_address": {
"city": "Seattle",
"state": "WA",
"postal_code": "98109",
"country": "US",
"address_1": "456 Terry Ave N"
}
}
Request Fields
merchant_id
Integer
Yes
Violet Merchant ID that the discount code belongs to. Must match a merchant ID from the SKUs in your request.
code
String
Yes
The promo code to validate against the merchant's platform.
Valid Promo Code Response
When a promo code is valid, you'll see it applied with full details:
{
"estimated_carts": [
{
"merchant_id": 11111,
"platform": "SHOPIFY",
"base_currency": "USD",
"sub_total": 20000,
"shipping_total": 0,
"discount_total": 2000,
"tax_total": 2000,
"total": 20000,
"skus": [...],
"discounts": [
{
"status": "VALID",
"type": "CODE",
"value_type": "PERCENTAGE",
"target_type": "ORDER",
"code": "PIEDPIPERCLUB",
"percentage": 15.0,
"amount_total": 2000,
"merchant_id": 11111
}
],
"available_shipping_methods": [...],
"has_shipping_methods": true
}
]
}
Invalid Promo Code Response
When a promo code doesn't work, you'll get clear feedback:
{
"estimated_carts": [
{
"merchant_id": 11111,
"platform": "SHOPIFY",
"base_currency": "USD",
"sub_total": 20000,
"shipping_total": 0,
"discount_total": 0,
"tax_total": 2000,
"total": 22000,
"skus": [...],
"discounts": [
{
"status": "INVALID",
"type": "CODE",
"code": "PIEDPIPERFAKEDISCOUNT"
}
],
"available_shipping_methods": [...],
"has_shipping_methods": true,
"external_error_messages": [
"Invalid discount code: PIEDPIPERFAKEDISCOUNT"
]
}
]
}
Response Fields
BagDiscount Object in Estimate Cart:
status
String
VALID
- Code is valid and discount applied
INVALID
- Code failed validation
ERROR
- System error occurred
type
String
Always CODE
for synced discounts
value_type
String
AMOUNT
or PERCENTAGE
- How the discount is calculated
target_type
String
ORDER
, SKU
, or SHIPPING
- What the discount applies to
code
String
The promo code that was validated
amount
Integer
Fixed discount amount in cents (when value_type
is AMOUNT
)
percentage
Double
Percentage discount value (when value_type
is PERCENTAGE
)
amount_total
Integer
Total discount applied in cents
merchant_id
Integer
Merchant ID this discount belongs to
Cart totals are automatically updated:
discount_total
- Total discount amount applied across all discountstax_total
- Recalculated after discount is appliedtotal
- Final cart total including discount
Create Order with Promo Codes
For Create Order, pass promo codes at the bag level within each bag's discounts
array:
{
"payment_method": {
"type": "SINGLE_USE_CARD_TOKEN",
"payment_provider": "STRIPE",
"token": "tok_amex"
},
"order": {
"app_order_id": "piedpiper-1881",
"customer": {
"first_name": "Richard",
"last_name": "Hendricks",
"email": "[email protected]"
},
"billing_address": {...},
"shipping_address": {...},
"bags": [
{
"skus": [
{ "sku_id": 12345, "quantity": 1, "price": 10000 }
],
"shipping_method": {
"carrier": "OTHER",
"label": "Economy",
"price": 5000,
"shipping_method_id": "DOLLARFIFTYSHIPPING"
},
"tax_total": 5000,
"discounts": [
{ "code": "PIEDPIPERCLUB" }
]
}
],
"currency": "USD"
}
}
Request Fields
code
String
Yes
The promo code to validate and apply.
Note: For Create Order with promo codes,
merchant_id
is inferred from the bag context; omit it from the discount object.
Response Fields
BagDiscount Object in Create Order:
id
Integer
Unique identifier for this discount
bag_id
Integer
ID of the bag this discount belongs to
status
String
APPLIED
- Discount successfully applied
INVALID
- Code failed validation
ERROR
- System error occurred
type
String
Always CODE
for synced discounts
value_type
String
AMOUNT
or PERCENTAGE
- How the discount is calculated
target_type
String
ORDER
, SKU
, or SHIPPING
- What the discount applies to
code
String
The promo code that was applied
amount
Integer
Fixed discount amount in cents (when value_type
is AMOUNT
)
percentage
Double
Percentage discount value (when value_type
is PERCENTAGE
)
amount_total
Integer
Total discount applied in cents
date_created
String
ISO timestamp when discount was created
date_last_modified
String
ISO timestamp when discount was last updated
Differences between Estimate Cart and Create Order for Synced Discounts
Purpose
Preview discount impact
Apply discount permanently
merchant_id
Required in discount object
Not required (inferred from bag)
Status Values
VALID
, INVALID
, ERROR
APPLIED
, INVALID
, ERROR
Persistence
Temporary evaluation only
Discount persisted with order
Additional Fields
None
id
, bag_id
, date_created
, date_last_modified
Error Handling
Shows as status in response
Creates error objects in errors
array
Platform behavior (synced codes): If the platform accepts the order but the code is inapplicable, the discount returns as
INVALID
and the bag may still beACCEPTED
(totals reflect no discount). Check thediscounts
array anderrors
for context.
Custom Discounts
Custom discounts give you complete control over your promotional strategy. Define your own discount amounts or percentages, and Violet applies them without needing to validate against merchant platforms. Merchants will then see these discounts applied in Orders on their side.
Key Benefits
Full control over discount logic and amounts
Flexible targeting — apply to orders, specific SKUs, or shipping
Perfect for marketplace-led promotions that don't exist in merchant stores
Discount Targets
Choose where your discount applies:
ORDER
— Apply to the entire bag/order subtotalSKU
— Apply to specific line itemsSHIPPING
— Apply to shipping charges only
Platform Support
Supported Platforms
Shopify
BigCommerce
Ecwid
Platforms Coming Soon
Magento
WooCommerce
Wix
Understanding the BagDiscount
object
BagDiscount
objectThe BagDiscount
object represents a discount applied to a bag. It contains all the necessary information about the discount, including its type, value, target, and status.
Common Fields (Both APIs)
sku_id
Integer
SKU this discount applies to (null for order/shipping discounts)
67890
type
String
Discount mechanism: CODE
or CUSTOM
CUSTOM
value_type
String
How discount is calculated: AMOUNT
or PERCENTAGE
PERCENTAGE
target_type
String
What the discount applies to: ORDER
, SKU
, or SHIPPING
ORDER
amount
Integer
Fixed discount in cents (when value_type
is AMOUNT
)
500
percentage
Double
Percentage discount (when value_type
is PERCENTAGE
)
20.0
amount_total
Integer
Final discount applied in cents
1580
Estimate Cart Only Fields
status
String
VALID
, INVALID
, ERROR
, NOT_SUPPORTED
merchant_id
Integer
Required for bag-level discounts in Estimate Cart
Create Order Only Fields
id
Integer
Unique discount identifier
bag_id
Integer
Bag this discount belongs to
status
String
APPLIED
, INVALID
, ERROR
, NOT_SUPPORTED
date_created
String
ISO timestamp when created
date_last_modified
String
ISO timestamp when updated
Using Custom Discounts
Estimate Cart
You can apply custom discounts at two levels:
Bag level — In the main
discounts
arraySKU level — Inside individual SKU objects
Order-Level Custom Discount
Apply a discount to the entire bag:
{
"base_currency": "USD",
"skus": [
{ "quantity": 1, "sku_id": 1, "price": 5000 },
{ "quantity": 1, "sku_id": 2, "price": 3000 }
],
"discounts": [
{
"merchant_id": 11111,
"type": "CUSTOM",
"target_type": "ORDER",
"amount": 800
}
],
"shipping_address": {
"city": "Seattle",
"state": "WA",
"postal_code": "98109",
"country": "US",
"address_1": "456 Terry Ave N"
}
}
Request Fields
Top-level discount (bag-level):
merchant_id
Integer
Yes
Violet Merchant ID that this discount applies to
type
String
Yes
Must be CUSTOM
for custom discounts
target_type
String
Yes
ORDER
, SKU
, or SHIPPING
- what the discount applies to
amount
Integer
No*
Fixed discount amount in cents
percentage
Double
No*
Percentage discount (e.g., 15.0
for 15%)
*Either amount
OR percentage
must be provided, not both.
Response:
{
"estimated_carts": [
{
"merchant_id": 11111,
"platform": "SHOPIFY",
"base_currency": "USD",
"sub_total": 8000,
"shipping_total": 0,
"discount_total": 800,
"tax_total": 720,
"total": 7920,
"skus": [...],
"discounts": [
{
"type": "CUSTOM",
"value_type": "AMOUNT",
"target_type": "ORDER",
"status": "VALID",
"amount": 800,
"amount_total": 800,
"merchant_id": 11111
}
],
"available_shipping_methods": [...],
"has_shipping_methods": true
}
]
}
SKU-Level Custom Discount
Apply a discount to a specific product:
{
"base_currency": "USD",
"skus": [
{
"quantity": 1,
"sku_id": 1,
"price": 5000,
"discount": {
"type": "CUSTOM",
"percentage": 15.0
}
},
{ "quantity": 1, "sku_id": 2, "price": 3000 }
],
"shipping_address": {
"city": "Seattle",
"state": "WA",
"postal_code": "98109",
"country": "US",
"address_1": "456 Terry Ave N"
}
}
Request Fields
SKU-level discount (inline):
type
String
Yes
Must be CUSTOM
for custom discounts
amount
Integer
No*
Fixed discount amount in cents
percentage
Double
No*
Percentage discount (e.g., 15.0
for 15%)
*Either amount
OR percentage
must be provided, not both. Note: target_type
is implied as SKU
when discount is inline with a SKU.
Response:
{
"estimated_carts": [
{
"merchant_id": 11111,
"platform": "SHOPIFY",
"base_currency": "USD",
"sub_total": 8000,
"shipping_total": 0,
"discount_total": 750,
"tax_total": 725,
"total": 7975,
"skus": [...],
"discounts": [
{
"type": "CUSTOM",
"value_type": "PERCENTAGE",
"target_type": "SKU",
"status": "VALID",
"percentage": 15.0,
"amount_total": 750,
"sku_id": 1
}
],
"available_shipping_methods": [...],
"has_shipping_methods": true
}
]
}
Shipping Discount
Apply a discount specifically to shipping costs:
{
"base_currency": "USD",
"skus": [
{ "quantity": 1, "sku_id": 1, "price": 5000 }
],
"discounts": [
{
"merchant_id": 11111,
"type": "CUSTOM",
"target_type": "SHIPPING",
"percentage": 50.0
}
],
"shipping_address": {
"city": "Seattle",
"state": "WA",
"postal_code": "98109",
"country": "US",
"address_1": "456 Terry Ave N"
}
}
Response Fields
BagDiscount Object for Custom Discounts (Estimate Cart):
status
String
VALID
- Discount is valid and applied
INVALID
- Discount failed validation
ERROR
- System error occurred
NOT_SUPPORTED
- Platform doesn't support this discount type
type
String
Always CUSTOM
for custom discounts
value_type
String
AMOUNT
or PERCENTAGE
- How the discount is calculated
target_type
String
ORDER
, SKU
, or SHIPPING
- What the discount applies to
amount
Integer
Fixed discount amount in cents (when value_type
is AMOUNT
)
percentage
Double
Percentage discount value (when value_type
is PERCENTAGE
)
amount_total
Integer
Total discount applied in cents
sku_id
Integer
Present for SKU-level discounts, null for order/shipping discounts
merchant_id
Integer
Merchant ID this discount belongs to (bag-level discounts only)
Cart totals are automatically updated:
discount_total
- Total discount amount applied across all discountstax_total
- Recalculated after discount is appliedtotal
- Final cart total including discount
Create Order
For Create Order, you can pass custom discounts at the bag level or inline with SKUs, just like in Estimate Cart.
Request Fields
Bag-level discount:
type
String
Yes
Must be CUSTOM
for custom discounts
target_type
String
Yes
ORDER
, SKU
, or SHIPPING
- what the discount applies to
amount
Integer
No*
Fixed discount amount in cents
percentage
Double
No*
Percentage discount (e.g., 15.0
for 15%)
SKU-level discount (inline with SKU):
type
String
Yes
Must be CUSTOM
for custom discounts
amount
Integer
No*
Fixed discount amount in cents
percentage
Double
No*
Percentage discount (e.g., 15.0
for 15%)
*Either amount
OR percentage
must be provided, not both. Note: target_type
is implied as SKU
for inline discounts, and merchant_id
is inferred from the bag context.
Response Fields
BagDiscount Object for Custom Discounts (Create Order):
id
Integer
Unique identifier for this discount
sku_id
Integer
Present for SKU-level discounts, null for order/shipping discounts
status
String
APPLIED
- Discount successfully applied
INVALID
- Discount failed validation
ERROR
- System error occurred
NOT_SUPPORTED
- Platform doesn't support this discount type
type
String
Always CUSTOM
for custom discounts
value_type
String
AMOUNT
or PERCENTAGE
- How the discount is calculated
target_type
String
ORDER
, SKU
, or SHIPPING
- What the discount applies to
amount
Integer
Fixed discount amount in cents (when value_type
is AMOUNT
)
percentage
Double
Percentage discount value (when value_type
is PERCENTAGE
)
amount_total
Integer
Total discount applied in cents
Bag-Level Custom Discount
{
"payment_method": {
"type": "SINGLE_USE_CARD_TOKEN",
"payment_provider": "STRIPE",
"token": "tok_visa"
},
"order": {
"app_order_id": "channel-order-123",
"customer": {
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]"
},
"bags": [
{
"skus": [
{ "sku_id": 12345, "quantity": 2, "price": 5000 }
],
"shipping_method": {
"carrier": "OTHER",
"label": "Standard",
"price": 1000
},
"tax_total": 1100,
"discounts": [
{
"type": "CUSTOM",
"target_type": "ORDER",
"percentage": 10.0
}
]
}
],
"shipping_address": {
"address_1": "123 Main St",
"city": "Seattle",
"state": "WA",
"country": "US",
"postal_code": "98101"
},
"currency": "USD"
}
}
Response:
{
"id": 145970,
"bags": [
{
"id": 176283,
"discounts": [
{
"id": 12784,
"status": "APPLIED",
"type": "CUSTOM",
"value_type": "PERCENTAGE",
"target_type": "ORDER",
"percentage": 10.0,
"amount_total": 1000
}
],
"sub_total": 10000,
"shipping_total": 1000,
"tax_total": 1100,
"discount_total": 1000,
"total": 11100
}
],
"total": 11100,
"status": "COMPLETED"
}
SKU-Level Custom Discount
{
"payment_method": {
"type": "SINGLE_USE_CARD_TOKEN",
"payment_provider": "STRIPE",
"token": "tok_visa"
},
"order": {
"app_order_id": "channel-order-124",
"customer": {
"first_name": "Jane",
"last_name": "Smith",
"email": "[email protected]"
},
"bags": [
{
"skus": [
{
"sku_id": 12345,
"quantity": 1,
"price": 8000,
"discount": {
"type": "CUSTOM",
"amount": 500
}
}
],
"shipping_method": {
"carrier": "OTHER",
"label": "Express",
"price": 1500
},
"tax_total": 750
}
],
"shipping_address": {
"address_1": "456 Oak Ave",
"city": "Portland",
"state": "OR",
"country": "US",
"postal_code": "97201"
},
"currency": "USD"
}
}
Response:
{
"id": 145971,
"bags": [
{
"id": 176284,
"skus": [...],
"discounts": [
{
"id": 12785,
"sku_id": 12345,
"status": "APPLIED",
"type": "CUSTOM",
"value_type": "AMOUNT",
"target_type": "SKU",
"amount": 500,
"amount_total": 500
}
],
"sub_total": 18000,
"shipping_total": 1500,
"tax_total": 750,
"discount_total": 1500,
"total": 18750
}
],
"total": 18750,
"status": "COMPLETED"
}
Understanding BagDiscount Fields
The BagDiscount
objects in responses contain all the information about applied discounts. Here's what each field means:
Core Fields (Both APIs)
sku_id
Integer
SKU this discount applies to (null for order/shipping discounts)
67890
type
String
Discount mechanism: CODE
or CUSTOM
CUSTOM
value_type
String
How discount is calculated: AMOUNT
or PERCENTAGE
PERCENTAGE
target_type
String
What the discount applies to: ORDER
, SKU
, or SHIPPING
ORDER
amount
Integer
Fixed discount in cents (when value_type
is AMOUNT
)
500
percentage
Double
Percentage discount (when value_type
is PERCENTAGE
)
20.0
amount_total
Integer
Actual discount applied in cents
1580
Estimate Cart Only
status
String
Whether discount can be applied
VALID
, INVALID
, ERROR
, NOT_SUPPORTED
Create Order Only
id
Integer
Unique discount identifier
12784
bag_id
Integer
Bag this discount belongs to
176283
status
String
Current discount state
APPLIED
, INVALID
, ERROR
, NOT_SUPPORTED
date_created
String
When discount was created
2025-08-15T17:16:34+0000
date_last_modified
String
When discount was last updated
2025-08-15T17:16:34+0000
Status Values Explained
PENDING
Discount is in processing state
Interim processing state (iterative checkout). In DOS, this is internal and generally not surfaced.
VALID
Discount is valid and ready to apply
Estimate Cart when discount passes validation
APPLIED
Discount has been successfully applied
Create Order when discount is active on the order
INVALID
Discount failed validation or rules
Bad promo code, over-amount discount, etc.
EXPIRED
Discount was not applied because it has expired
Merchant platform says the promo has expired (synced codes)
ERROR
System error during processing
Platform communication issues
NOT_SUPPORTED
Discount type not supported
Platform doesn't support this discount type
Validation & Error Handling
We validate discounts thoroughly to prevent issues and provide error messages in the errors
array .
Over-Amount Protection
Discounts cannot exceed their applicable base amount:
Order-level: Cannot exceed bag subtotal
SKU-level: Cannot exceed line price (price × quantity)
Shipping-level: Cannot exceed shipping method price
Single-Bag Order Error
If a discount exceeds limits in a single-bag order, the entire order fails with a bad-request exception:
{
"error": "bad_request",
"error_message": "Discount total (\"$300.00\") cannot exceed bag subtotal (\"$200.00\").",
"error_code": 1001
}
Multi-Bag Order Error
In multi-bag orders, only the offending bag fails while others may succeed:
{
"id": 145973,
"errors": [
{
"id": 26695,
"bag_id": 176286,
"type": "EXTERNAL_ADD_DISCOUNT_ERROR",
"message": "SKU-level discount (\"$120.00\") exceeds line price (\"$100.00\").",
"date_created": "2025-08-15T17:16:34+0000"
}
],
"bags": [
{
"id": 176286,
"bag_status": "REJECTED",
"discounts": [
{
"status": "INVALID",
"type": "CUSTOM",
"target_type": "SKU",
"sku_id": 12345
}
]
},
{
"id": 176285,
"bag_status": "ACCEPTED",
"discounts": [...]
}
]
}
Common Error Scenarios
Multiple discounts per merchant
400
More than one discount for the same merchant
"Multiple discounts cannot be passed in for the same merchant (merchant_id=10186)."
Negative discount
400
Discount amount is negative
"Discount total cannot be negative. Provided value: -$50.00"
Platform not supported
422
Platform doesn't support custom discounts
"Custom discounts are not supported by SFCC."
Best Practices
Always Include Shipping Address
A shipping address (at minimum the country
field) is required in Estimate Cart requests.
{
"shipping_address": {
"country": "US"
}
}
Pre-validate Discount Amounts
Before sending requests, ensure your discount amounts don't exceed their applicable base:
For order discounts: Check against subtotal
For SKU discounts: Check against line price (price × quantity)
For shipping discounts: Check against shipping method price
Use Estimate Cart First
Always use Estimate Cart to preview discount application before creating orders. This helps you catch issues early and provides a better user experience.
Platform Considerations
SKU-Level Discount Support
Some ecommerce platforms don't support SKU-level custom discounts. When this happens:
Violet automatically applies the discount at the Bag level instead
Merchants will see the discount applied in their ecommerce platform, but not tied to specific SKUs. Since this is a platform limitation, all the other discounts on their platform would appear the same way.
Violet data will still reflect the SKU-level details associated with the discount.
Only one discount is permitted per merchant per request, regardless of level. This means that multiple SKU-level discounts for the same merchant in a single request will result in a
400 Bad Request
.
Summary
With Direct Order Submission's discount support, you have the flexibility to:
Honor merchant promotions with synced promo codes
Create channel-specific deals with custom discounts
Apply targeted discounts at order, SKU, or shipping level
Ensure accuracy with comprehensive validation and clear error handling
This ensures you can confidently design discount strategies that work seamlessly across merchants and platforms and serve your marketplace needs.
Last updated
Was this helpful?