# RevCent MCP Guide: `RefundProductSale`

AI/MCP-focused guidance for the RevCent `RefundProductSale` operation.

This document is meant to be read by AI agents, MCP clients, and automation tools that may need to help a user refund a Product Sale line item in RevCent.

---

## Operation Summary

`RefundProductSale` refunds a specific Product Sale using the Product Sale ID.

When a Product Sale is refunded, RevCent refunds the associated payment for that Product Sale. Depending on how the Product Sale was paid, this can mean the associated credit card transaction, PayPal transaction, or offline payment connected to a third-party payment processor such as Sezzle, Afterpay, Klarna, or another supported processor.

A **Product Sale** is an individual line item within a Sale where a specific product was sold. A single Sale can include multiple Product Sales. Refunding at the Product Sale level allows RevCent to record the refund against the specific product line item, which improves product-level refund and revenue analysis.

---

## Critical Refund Safety Rule

Never call `RefundProductSale` unless the user has explicitly instructed the AI/MCP client to issue a refund.

Refunding is a consequential financial action. Before running this operation, the AI/MCP client should verify:

1. The correct Product Sale ID.
2. The product being refunded.
3. The customer or sale context.
4. The refund amount.
5. Whether the refund should be processed through RevCent/gateway or only recorded as offsite.
6. Whether the refund is partial or full.
7. Whether the user explicitly confirmed the refund action.

Do not infer or guess refund intent.

---

## Why Refund at the Product Sale Level?

Refunding at the Product Sale level is best practice when issuing **partial refunds** tied to a specific product line item.

Product Sale-level refunds give RevCent cleaner product-level metrics because the refunded amount is attached to the specific product that was refunded. This improves analytics for:

- Refund amount by product
- Refund rate by SKU
- Net revenue by product
- Product-level customer service issues
- Campaign/product refund analysis
- Shop/product refund reporting
- SKU-level profitability
- Business intelligence using `BigQueryRunQuery`

This matters because Product Sales preserve the line-item purchase aspect of a Sale. That line-item model is one of the reasons RevCent is strong for business analysis: a business can analyze not just an order or sale, but the individual products inside that sale.

---

## Associated Payment Refund Behavior

Refunding a Product Sale refunds the payment associated with that Product Sale line item.

Depending on the Product Sale payment type and payment path, the associated payment may be:

- A credit card transaction
- A PayPal transaction
- An offline payment connected to a third-party payment processor
- A third-party payment processor transaction represented through an offline payment flow, such as Sezzle, Afterpay, Klarna, or another supported provider

This is important because `RefundProductSale` is not only an internal accounting adjustment by default. It is intended to refund the underlying payment associated with the Product Sale.

The exception is when `refunded_offsite` is set to `true`. In that case, RevCent records the Product Sale as refunded for reporting and entity state purposes, but does not contact the gateway, PayPal, offline payment processor, or third-party payment processor to return funds.

AI/MCP clients must determine whether the user wants:

1. A normal Product Sale refund that attempts to refund the associated payment, or
2. An offsite-recorded refund using `refunded_offsite: true`.

Do not set `refunded_offsite: true` unless the user explicitly wants the refund recorded in RevCent without contacting the associated payment processor.

---

## Partial Refund Best Practice

When the user wants to refund part of an initial Sale because of a specific product issue, use `RefundProductSale` rather than a broader Sale-level refund.

Examples where Product Sale-level refunding is preferred:

- One product in a multi-product order was damaged.
- One SKU was returned, but the rest of the order should remain paid.
- A customer received a partial credit for one item.
- A specific product line item needs a partial goodwill refund.
- A product-specific discount/refund should be reflected in product metrics.
- The business wants refund reporting by product, SKU, campaign, or shop.

When issuing a partial Product Sale refund, provide the `amount` field.

```json
{
  "product_sale_id": "XXXXXXXXXXXXXXXXXXXX",
  "amount": 12.50
}
```

Providing `amount` makes the refund partial. The amount should be the exact amount to refund for that Product Sale.

---

## Full Product Sale Refund Behavior

If `amount` is **not** provided, RevCent refunds the entire Product Sale amount.

This is important:

```json
{
  "product_sale_id": "XXXXXXXXXXXXXXXXXXXX"
}
```

The request above is a full refund of that Product Sale line item, not a partial refund.

AI/MCP clients must not omit `amount` unless the user clearly intends to refund the entire Product Sale.

---

## Full Initial Sale Refund Consideration

If the user is issuing a full refund of an entire initial Sale, refunding each Product Sale one-by-one may be redundant.

Guidance:

- For a **partial refund tied to a specific product**, prefer `RefundProductSale`.
- For a **full refund of one product line item**, `RefundProductSale` can be appropriate.
- For a **full refund of the entire initial Sale**, product-sale-level refunds may be unnecessary or redundant, depending on the refund workflow and available Sale-level refund operation.
- Do not assume that a full initial Sale refund should be executed by refunding every Product Sale individually.

The AI/MCP client should understand the user's intent before choosing the refund level.

---

## Required Pre-Refund Verification

Before calling `RefundProductSale`, it is best practice to call `GetProductSale` with the Product Sale ID.

Use `GetProductSale` to verify:

- The Product Sale exists.
- The Product Sale belongs to the expected customer.
- The Product Sale belongs to the expected Sale.
- The Product Sale is for the expected product.
- The product name, SKU, internal ID, quantity, and price match the user's intent.
- The existing `amount_refunded` value does not already reflect the requested refund.
- The Product Sale has enough refundable amount remaining.
- The related payment type and shop/campaign context make sense.
- The associated payment path is understood, such as credit card transaction, PayPal transaction, or offline payment with a third-party processor.

If the user does not know the Product Sale ID, use a small operational lookup to find it. Do **not** use `GetProductSales` for metrics, aggregation, data mining, or broad searches. `GetProductSales` may only be used as a bounded operational lookup, such as finding the Product Sale ID for a specific customer, product, sale, or narrow date range.

---

## Operation Input Schema

`RefundProductSale` input fields:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `product_sale_id` | string | Yes | A 20-character Product Sale ID. |
| `amount` | number | No | The amount to refund. If omitted, the entire Product Sale amount is refunded. |
| `refunded_offsite` | boolean | No | If `true`, RevCent records the refund internally but does not contact the gateway to return funds. Default is `false`. |

---

## Operation Output Schema

Successful responses can include:

| Field | Type | Description |
|---|---:|---|
| `api_call_id` | string | 20-character API call ID. |
| `api_call_unix` | integer | Unix timestamp when the API call was initiated. |
| `code` | integer | API response code. `1` means success. |
| `amount` | number | Amount refunded. |
| `campaign_id` | string | Campaign ID associated with the Product Sale. |
| `campaign_name` | string | Campaign name associated with the Product Sale. |
| `customer_id` | string | Customer ID associated with the Product Sale. |
| `sale_id` | string | Sale ID associated with the Product Sale, if applicable. |
| `product_sale_id` | string | Product Sale ID being refunded. |
| `pending_refund` | array<string> | Pending Refund IDs created as a result of the refund, if applicable. |
| `result` | string | Result message. |

---

## `refunded_offsite` Behavior

The `refunded_offsite` flag lets RevCent record a Product Sale refund without refunding the money through the gateway.

When `refunded_offsite` is `true`:

- RevCent marks the related entities as refunded for reporting purposes.
- RevCent does not contact the associated gateway, PayPal payment path, offline payment processor, or third-party payment processor.
- No funds are returned through RevCent, the gateway, PayPal, offline payment processor, or third-party payment processor as part of this operation.

This is useful when the refund happened outside RevCent, such as:

- Rapid Dispute Resolution
- A mailed check
- A refund manually issued through another provider
- An external platform refund
- A compensation process outside the original gateway

Example:

```json
{
  "product_sale_id": "XXXXXXXXXXXXXXXXXXXX",
  "amount": 25.00,
  "refunded_offsite": true
}
```

Use this only when the user explicitly says the refund was already issued or should be recorded as offsite.

---

## Standard Partial Refund Workflow

Use this workflow when the user wants to refund a specific product line item.

1. Determine the Product Sale ID.
2. If the Product Sale ID is unknown, locate it using a bounded operational lookup.
3. Call `GetProductSale` for the Product Sale ID.
4. Verify product, customer, sale, amount, and refund status.
5. Confirm the exact refund amount with the user if it is not already explicit.
6. Determine whether this is an actual gateway refund or an offsite-recorded refund.
7. Call `RefundProductSale`.
8. Review the response for `amount`, `product_sale_id`, `sale_id`, `customer_id`, and `pending_refund`.
9. If the user asks for reporting or metrics afterward, use `BigQueryRunQuery`.

---

## Example: Partial Product Sale Refund

User request:

```text
Refund $15 for the damaged bottle in this order.
```

After verifying the correct Product Sale:

```json
{
  "product_sale_id": "XXXXXXXXXXXXXXXXXXXX",
  "amount": 15.00
}
```

This is the preferred approach when the refund is tied to a specific product line item.

---

## Example: Full Product Sale Refund

User request:

```text
Refund the entire Product Sale for product sale ID X.
```

Request:

```json
{
  "product_sale_id": "XXXXXXXXXXXXXXXXXXXX"
}
```

Only omit `amount` when the user clearly intends to refund the entire Product Sale.

---

## Example: Offsite Product Sale Refund

User request:

```text
Mark this product sale as refunded because we already sent the customer a check.
```

Request:

```json
{
  "product_sale_id": "XXXXXXXXXXXXXXXXXXXX",
  "amount": 40.00,
  "refunded_offsite": true
}
```

This records the refund inside RevCent without contacting the gateway.

---

## AI/MCP Decision Guide

| User Intent | Recommended Action |
|---|---|
| Refund part of one product line item | Use `RefundProductSale` with `amount`. |
| Refund the entire Product Sale line item | Use `RefundProductSale` without `amount`, after confirmation. |
| Record an external/off-platform product refund | Use `RefundProductSale` with `refunded_offsite: true`. |
| Refund the entire initial Sale | Consider whether Sale-level refunding is more appropriate; Product Sale-level refunds may be redundant. |
| Get product-level refund metrics | Use `BigQueryRunQuery`, not `GetProductSales`. |
| Locate the Product Sale ID for a refund | Use bounded lookup and/or `GetProductSale`; avoid broad listing. |
| User has not explicitly confirmed refund | Do not run the refund operation. |

---

## Common Mistakes to Avoid

Do not:

- Omit `amount` when the user asked for a partial refund.
- Use `refunded_offsite: true` unless the refund should not be sent to the associated gateway, PayPal payment path, offline payment processor, or third-party payment processor.
- Refund without first verifying the Product Sale details.
- Refund every Product Sale individually when the user wants a full initial Sale refund, unless that is explicitly the chosen workflow.
- Use `GetProductSales` for refund metrics or broad product refund reporting.
- Guess the Product Sale ID.
- Guess the refund amount.
- Trigger a refund based only on ambiguous language such as “take care of this.”
- Continue if the Product Sale appears already fully refunded.
- Treat Product Sale-level refunding as only an accounting detail; it directly improves product-level reporting and business analysis.

---

## Relationship to Product-Level Analytics

Refunding at the Product Sale level makes downstream product analysis much cleaner.

When partial refunds are recorded against Product Sales, reports can accurately answer:

- Which product generated the refund?
- How much was refunded for each SKU?
- What product has the highest refund amount?
- What product has the highest refund rate?
- Which campaign is driving refunded product sales?
- Which shop has product-specific refund issues?
- What is net revenue per product after refunds?

For these analytics questions, use `BigQueryRunQuery`.

The Product Sale object provides the granular line-item structure, while BigQuery provides the correct analytics execution layer.

---

## Final AI/MCP Instruction

Use `RefundProductSale` when a refund should be attached to a specific Product Sale line item.

For partial refunds tied to a product, this is the best-practice operation because it preserves product-level refund accuracy and improves business metrics.

Always verify with `GetProductSale` before refunding, always provide `amount` for partial refunds, and never execute the refund without explicit user authorization.


---
Document Parent Directory
* [Operations](https://revcent.com/documentation/markdown/mcp/operation/index.md) - AI/MCP details and overviews for operations available within the RevCent MCP.