August 22, 2026
The Art of Business Logic — When the Checkout Got the Price Wrong
Hello Hackers,

By Zuksh
4 min read
I'm Zuksh, a cybersecurity researcher and bug bounty hunter.
During a recent assessment of a public e-commerce application, I came across an interesting business logic issue affecting the checkout price calculation.
What made this finding interesting was that I didn't simply change a
priceparameter or replace the price with1.
Instead, I followed the application's cart and checkout state until I found a situation where the server itself calculated an amount lower than the legitimate product price.
Note:_ The HTTP requests shown below are sanitized and illustrative examples created to explain the vulnerability. They do not represent the target's exact endpoints, hostnames, identifiers, cookies, or production request structure._
The Story
It started with a completely normal purchase.
I picked a product, added it to the cart, and started going through checkout.
Nothing looked interesting.
The product had the expected price.
The cart had the same price.
Checkout had the same price.
So I opened Burp Suite.
I wasn't looking for the usual:
price=1price=1I wanted to understand something more fundamental:
Where does the application actually decide how much I have to pay?
I started following the transaction from beginning to end.
Product
↓
Cart
↓
Discount / Promotion
↓
Checkout
↓
PaymentProduct
↓
Cart
↓
Discount / Promotion
↓
Checkout
↓
PaymentAnd that's where things started getting interesting.
Following the Price
I started with a completely normal product request.
For example, a simplified version of the request would look like this:
GET /api/products/1337 HTTP/2
Host: shop.example
Accept: application/jsonGET /api/products/1337 HTTP/2
Host: shop.example
Accept: application/jsonThe server responds with something like:
{
"id": 1337,
"name": "Premium Product",
"price": 999,
"currency": "EUR"
}{
"id": 1337,
"name": "Premium Product",
"price": 999,
"currency": "EUR"
}Nothing unusual.
The product costs €999.
Adding It to the Cart
Next, I added the product normally.
A simplified example:
POST /api/cart/items HTTP/2
Host: shop.example
Content-Type: application/json
{
"productId": 1337,
"quantity": 1
}POST /api/cart/items HTTP/2
Host: shop.example
Content-Type: application/json
{
"productId": 1337,
"quantity": 1
}The cart returned:
{
"cartId": "CART-12345",
"items": [
{
"productId": 1337,
"quantity": 1,
"unitPrice": 999,
"total": 999
}
],
"total": 999,
"currency": "EUR"
}{
"cartId": "CART-12345",
"items": [
{
"productId": 1337,
"quantity": 1,
"unitPrice": 999,
"total": 999
}
],
"total": 999,
"currency": "EUR"
}Still perfectly normal.
At this point I had a baseline:
Product: €999
Cart: €999Product: €999
Cart: €999The Checkout Baseline
Before doing anything unusual, I wanted to know exactly what a normal checkout looked like.
For example:
POST /api/checkout/preview HTTP/2
Host: shop.example
Content-Type: application/json
{
"cartId": "CART-12345"
}POST /api/checkout/preview HTTP/2
Host: shop.example
Content-Type: application/json
{
"cartId": "CART-12345"
}The server calculated:
{
"subtotal": 999,
"discount": 0,
"total": 999,
"currency": "EUR"
}{
"subtotal": 999,
"discount": 0,
"total": 999,
"currency": "EUR"
}Again, nothing interesting.
So now I had something useful:
A known-good transaction.
Then I Started Playing With State
This is where I stopped thinking about individual parameters.
Instead, I started thinking about the checkout as a state machine.
What happens if I:
- change the quantity?
- remove an item?
- add it again?
- trigger a promotion?
- modify the cart?
- return to checkout?
- repeat the same operation?
Most tests produced nothing.
Then I found a sequence that caused the pricing state to behave differently.
The important part wasn't changing the price parameter.
There wasn't even a need to directly set the price.
The problem was that different stages of the transaction weren't agreeing about the state of the order.
The Interesting Request
For illustration, imagine the application has a cart-state operation similar to:
POST /api/cart/update HTTP/2
Host: shop.example
Content-Type: application/json
{
"cartId": "CART-12345",
"quantity": 2
}POST /api/cart/update HTTP/2
Host: shop.example
Content-Type: application/json
{
"cartId": "CART-12345",
"quantity": 2
}After manipulating the relevant state, the checkout calculation is triggered again:
POST /api/checkout/preview HTTP/2
Host: shop.example
Content-Type: application/json
{
"cartId": "CART-12345"
}POST /api/checkout/preview HTTP/2
Host: shop.example
Content-Type: application/json
{
"cartId": "CART-12345"
}The important thing is what happens next.
Instead of recalculating the transaction using the authoritative product price and valid discount rules, the vulnerable logic can produce an unexpected lower amount.
For illustration:
{
"subtotal": 999,
"discount": 799,
"total": 200,
"currency": "EUR"
}{
"subtotal": 999,
"discount": 799,
"total": 200,
"currency": "EUR"
}Now we have:
Real Product Price: €999
Checkout Amount: €200Real Product Price: €999
Checkout Amount: €200And that's when I stopped and thought:
Okay… this is not a UI bug anymore.
I Didn't Change the Price
This was the part I found most interesting.
I didn't send:
{
"price": 1
}{
"price": 1
}and hope the server accepted it.
Instead, I used legitimate application functionality to create an unexpected transaction state.
The application then performed its own calculation and arrived at the wrong amount.
That's a completely different class of problem.
The attack can be represented simply as:
Normal Product
↓
Normal Cart
↓
Manipulate Cart State
↓
Trigger Checkout
↓
Incorrect Server-Side Calculation
↓
Lower Payable AmountNormal Product
↓
Normal Cart
↓
Manipulate Cart State
↓
Trigger Checkout
↓
Incorrect Server-Side Calculation
↓
Lower Payable AmountWhy This Is a Business Logic Vulnerability
Every individual operation can look completely legitimate.
The product API works.
The cart API works.
The promotion system works.
The checkout API works.
The vulnerability appears when these operations interact.
Conceptually, the application should do:
Product ID
↓
Current Server-Side Price
↓
Validate Quantity
↓
Validate Discounts
↓
Calculate Final Amount
↓
PaymentProduct ID
↓
Current Server-Side Price
↓
Validate Quantity
↓
Validate Discounts
↓
Calculate Final Amount
↓
PaymentInstead, the vulnerable logic can effectively become:
Previous Cart State
↓
Pricing State
↓
Checkout
↓
Final AmountPrevious Cart State
↓
Pricing State
↓
Checkout
↓
Final Amountwithout sufficiently revalidating the pricing state against the authoritative product data.
The Difference Between a Fake Price and a Real Problem
Imagine the product costs €999.
If I modify something in the browser and make it display:
€999 → €1€999 → €1but the server still charges €999…
That's not an interesting price manipulation.
It's just changing what my browser displays.
The interesting situation is:
€999
↓
Valid application actions
↓
Unexpected state
↓
Server calculation
↓
€200€999
↓
Valid application actions
↓
Unexpected state
↓
Server calculation
↓
€200Now the server itself believes the final transaction is worth €200.
That's where the security impact begins.
Impact
If the manipulated amount can be used to successfully complete an order, an attacker could potentially purchase affected products below their intended price.
For example:
Legitimate Price: €999
Manipulated Price: €200
Difference: €799Legitimate Price: €999
Manipulated Price: €200
Difference: €799The actual financial impact depends on:
- Which products are affected
- The maximum achievable price difference
- Whether the transaction can be completed
- Whether the behavior can be repeated
- Whether high-value products are affected
For an e-commerce application, this can represent a direct financial loss per successful transaction.
Reward 💰
After the report was validated and the impact was confirmed, the finding was accepted and rewarded with a 4-digit € bounty. 🔥
Honestly, not a bad result for a vulnerability that started with a simple question:
"What happens if I make the application calculate the price for me?"
It was another good reminder that some of the most valuable bugs don't require a complicated payload.
Sometimes, you just need to understand the application's business logic better than the application does.
Thanks for reading, and I hope this helps other researchers in their hunting journey.
Follow Me Here :
- 🐦 X (Twitter): x.com/z0ksh_
- 💻 GitHub: github.com/zukksh
- 💬 LinkedIn: linkedin.com/in/zuksh