# RevCent MCP Guide: `CreateSale`

AI/MCP-focused guide for the RevCent `CreateSale` operation.

This guide is intended for AI agents, MCP clients, developers, and automation tools that need a precise understanding of the `CreateSale` schema, payment-type requirements, metadata behavior, and ecommerce capabilities for creating paid Sales through direct API/AI/custom/internal integrations.

---

## Related Overview Reference

Before using `CreateSale`, AI/MCP clients should understand the broader Sale object model and lifecycle. Reference the Sales Overview document:

```text
https://revcent.com/documentation/markdown/mcp/operation/OverviewSale.md
```

The Sales Overview explains how Sales relate to Product Sales, shipments, tax, discounts, customers, subscriptions, trials, fulfillment, Email Templates, AI workflows, functions, DNS tracking metadata, refunds, and BigQuery reporting.

---

## Operation Summary

`CreateSale` creates a Sale with payment.

The MCP operation description is important:

```text
Create a sale with payment. This operation is for direct API/AI integration, either with a custom storefront or internal system. This operation does not apply to purchases coming from a WooCommerce store, as the RevCent Payments plugin for WordPress takes care of handling payments and creating sales.
```

Use `CreateSale` for:

- Direct API integrations
- Direct MCP workflows
- AI workflows that are explicitly allowed to create Sales
- Custom storefronts
- Internal order-entry systems
- Custom checkout systems outside the standard RevCent WooCommerce plugin flow

Do **not** use `CreateSale` for normal WooCommerce checkout purchases handled by the RevCent Payments plugin for WordPress. The plugin handles payment and Sale creation for those purchases.

---

## What a Sale Represents

A Sale is the central ecommerce purchase object in RevCent.

When a Sale is created, it can become the parent/spawning point for:

- Customer record creation or association
- Payment processing or payment association
- Product Sales, one per sold product line item
- Shipping records and fulfillment workflows
- Tax records
- Discount records
- Coupon-applied discounts
- Subscriptions, when sold products have subscription profiles
- Trials, when sold products have trial settings
- Email Template triggers
- AI Assistant workflows
- AI Voice Agent workflows
- Function triggers
- Webhook or integration events
- Notes and metadata
- DNS tracking / visitor attribution metadata
- BigQuery reporting across the Sale lifecycle

A Sale is not just a payment event. It is the parent lifecycle object that connects checkout, products, customer, payment, fulfillment, refunds, subscription/trial outcomes, attribution, and reporting.

---

## Critical AI/MCP Rules

1. **Use `CreateSale` only for direct API/AI/custom/internal integrations.**
2. **Do not use `CreateSale` for normal WooCommerce plugin checkout purchases.** The RevCent Payments plugin for WordPress handles those payments and creates Sales.
3. **Do not guess IDs.** Campaign IDs, Product IDs, Payment Profile IDs, Customer IDs, Sale IDs, and Integration IDs must come from RevCent records or verified user input.
4. **Do not invent payment information.** PayPal transaction IDs must come from PayPal/frontend checkout. Offline third-party transaction IDs must come from the third-party processor.
5. **Use `EstimateSale` before `CreateSale` if the user needs totals before payment.**
6. **Use pending Sale operations for multi-step checkout, abandoned checkout, upsells, or delayed payment.**
7. **Use `BigQueryRunQuery` for reporting, metrics, aggregation, and data mining.**
8. **Preserve metadata carefully.** Sale-level metadata passes down to the customer, product sales, shipping, and tax. Product/shipping/tax metadata passes to those specific eventual item records.
9. **Include DNS tracking metadata when applicable.** If the Sale occurred on a tracked website with RevCent tracking-domain DNS set up, include `revcent_track_id` and `revcent_entry_id` from visitor/session cookies.
10. **For offline payment third-party processors, include the required metadata entries** so RevCent can associate the Sale with the third-party processor transaction.


---

## Purpose for AI/MCP Clients

This file is not merely an API example. It is a decision and schema guide meant to help AI/MCP clients understand:

- When `CreateSale` is the correct operation.
- When `CreateSale` is not the correct operation.
- Which fields are required for each payment type.
- How Sale-level metadata flows into related records.
- How product, shipping, and tax metadata should be used for granular reporting.
- How DNS tracking metadata should be included for tracked website Sales.
- How offline payment third-party processor metadata must be formatted.
- What downstream ecommerce outcomes can occur after a Sale is created.
- How to avoid unsafe or incorrect payment, retry, and reporting behavior.

AI/MCP clients should use this document to construct valid `CreateSale` requests and to reason about the business impact of creating a Sale in RevCent.

---

## Schema Summary

```text
operation: CreateSale
title: Create A Sale
description: Create a sale with payment.
input type: object
additionalProperties: false
required:
  - campaign
  - product
  - payment_type
  - ip_address
```

The schema does not allow unknown top-level fields.

---

## Full Top-Level Input Schema

| Field | Type | Required | Description |
|---|---:|---:|---|
| `campaign` | string | Yes | 20-character Campaign ID. |
| `iso_currency` | string | No | Three-character ISO 4217 currency code. |
| `ip_address` | string | Yes | Customer IP address. |
| `payment_type` | string enum | Yes | Indicates the Sale payment type: `credit_card`, `paypal`, `offline_payment`, or `check_direct`. |
| `payment_profile` | string | Conditional | Required when `payment_type` is `credit_card`. 20-character Payment Profile ID used to route the credit card payment request. |
| `credit_card` | object | Conditional | Required when `payment_type` is `credit_card` and not providing an existing customer ID/default-card flow. |
| `paypal_transaction_id` | string | Conditional | Required when `payment_type` is `paypal`. ID issued by PayPal for the transaction. |
| `customer` | object | Conditional | Customer details. Receives first priority when creating a new customer. Not required if providing existing `customer_id`. |
| `bill_to` | object | No | Billing information. If absent, `customer` is used. Useful with separate credit-card billing information. |
| `ship_to` | object | No | Shipping destination. If absent, `customer` or `bill_to` is used in priority order. Not required if using existing customer and shipping address is the same. |
| `product` | array<object> | Yes | Products to include in the Sale request. |
| `shipping` | array<object> | No | Shipping entries to include in the Sale request. |
| `tax` | array<object> | No | Tax entries to charge in the Sale request. |
| `coupon` | array<object> | No | Coupon codes to automatically apply discounts to the Sale. |
| `discount` | array<object> | No | Static discount entries to apply to the Sale. |
| `sale_id` | string | No | Sale ID of a previously created Sale that failed payment and is in a pending state, when re-attempting a failed payment on an unchanged Sale. |
| `customer_id` | string | No | Existing 20-character Customer ID. Used when purchasing on behalf of an existing customer using the customer default credit card. |
| `internal_sale_id` | string | No | Optional internal Sale ID, such as a third-party order ID. |
| `internal_customer_id` | string | No | Optional internal Customer ID, such as a third-party customer ID. |
| `metadata` | array<object> | No | Sale-level metadata. Passed down to all items created as a result of the Sale, including customer, product sales, shipping, and tax. |

---

## Payment Types

Allowed `payment_type` values:

```json
[
  "credit_card",
  "paypal",
  "offline_payment",
  "check_direct"
]
```

| Payment Type | Use When | Required / Important Fields |
|---|---|---|
| `credit_card` | RevCent should process a credit card payment. | `payment_profile`; `credit_card` unless using existing customer/default card flow. |
| `paypal` | PayPal already issued a transaction ID from frontend/store checkout. | `paypal_transaction_id`. |
| `offline_payment` | Payment is handled by an offline or third-party processor flow, such as Sezzle, Afterpay, Klarna, Affirm, or Amazon Pay. | Required top-level fields plus required offline-payment metadata entries. |
| `check_direct` | Sale is paid through check/direct check payment path. | Required top-level fields plus useful metadata/internal IDs. |

---

## Payment Type: `credit_card`

Use `payment_type: "credit_card"` when RevCent should process the Sale through a credit card payment path.

The schema states that if `payment_type` is `credit_card`, both `credit_card` and `payment_profile` are required. It also states the `credit_card` object is required when `payment_type` is `credit_card` and an existing customer ID is not being provided.

### Required Credit Card Sale Fields

| Field | Required | Notes |
|---|---:|---|
| `campaign` | Yes | 20-character Campaign ID. |
| `ip_address` | Yes | Customer IP address. |
| `payment_type` | Yes | Must be `credit_card`. |
| `payment_profile` | Yes | 20-character Payment Profile ID for routing the credit card payment request. |
| `product` | Yes | At least one product object. |
| `credit_card` | Usually | Required for new-card payment. |
| `customer` or `customer_id` | Usually | Use `customer` for a new customer or `customer_id` for existing customer/default card. |

### Credit Card Vault / PCI DSS Level 1

When a credit card Sale is created, RevCent stores the customer's payment card information in RevCent's PCI DSS Level 1 environment.

RevCent functions as a credit card vault for ecommerce businesses, storing customer payment card information on behalf of users. This supports future purchases, customer card-on-file payments, subscription renewals, trial expiration charges, pending Sale processing, declined Sale retry/recovery workflows, AI Assistant recovery workflows, AI Voice Agent live recovery workflows, and customer support payment updates.

AI/MCP clients must treat card data as sensitive and use secure payment collection workflows.

---

## `credit_card` Object Schema

`credit_card` has `additionalProperties: false`.

Required fields:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `card_number` | string | Yes | Full credit card number. |
| `exp_month` | integer | Yes | Credit card expiration month as one or two digit integer, e.g. `1` or `12`. |
| `exp_year` | integer | Yes | Credit card expiration year as two digit integer, e.g. `29`. |

Optional fields:

| Field | Type | Description |
|---|---:|---|
| `card_code` | string | Credit card security code. Length can vary by card type. |
| `three_ds` | object | Optional 3DS values to pass to the processor. |

### Minimal Credit Card Example

```json
{
  "campaign": "XXXXXXXXXXXXXXXXXXXX",
  "ip_address": "203.0.113.10",
  "payment_type": "credit_card",
  "payment_profile": "XXXXXXXXXXXXXXXXXXXX",
  "customer": {
    "first_name": "Jane",
    "last_name": "Customer",
    "email": "jane@example.com"
  },
  "credit_card": {
    "card_number": "<CARD_NUMBER_COLLECTED_SECURELY>",
    "exp_month": 12,
    "exp_year": 29
  },
  "product": [
    {
      "id": "XXXXXXXXXXXXXXXXXXXX"
    }
  ]
}
```

---

## `credit_card.three_ds` Object Schema

`three_ds` is optional and is used when the checkout flow uses 3DS and sends RevCent the 3DS response values to pass to the processor.

`three_ds` has `additionalProperties: false`.

| Field | Type | Description |
|---|---:|---|
| `enabled` | boolean | Whether RevCent should parse 3DS variables to send to the processor. Must be `true` if using 3DS values. Default is false. |
| `version` | string | 3DS version, such as `2.1.0` or `2.2.0`. |
| `eci` | string | eCommerce indicator. |
| `cavv` | string | Cardholder Authentication Verification Value. |
| `xid` | string | Transaction identifier from authentication processing. Occasionally provided for some card brands. |
| `directory_server_id` | string | Transaction identifier assigned by the directory server. |
| `authentication_response` | string | Describes whether customer was successfully verified or attempted. |
| `acs_transaction_id` | string | Access Control Server transaction identifier. |
| `algorithm` | string | 3DS algorithm used. |
| `directory_response` | string | 3DS directory server response. |
| `enrollment_response` | string | Verify enrollment response/status. |
| `three_ds_server_transaction_id` | string | 3DS server transaction ID. |
| `gateway_id` | string | Gateway to use when 3DS is enabled and a specific gateway should process the request. |

Do not invent 3DS values. They must come from the real 3DS checkout/authentication flow.

---

## Payment Type: `paypal`

Use `payment_type: "paypal"` when the frontend/store has already completed PayPal checkout and PayPal has issued a transaction ID.

The schema states that if `payment_type` is `paypal`, `paypal_transaction_id` is required.

### Required PayPal Sale Fields

| Field | Required | Notes |
|---|---:|---|
| `campaign` | Yes | 20-character Campaign ID. |
| `ip_address` | Yes | Customer IP address. |
| `payment_type` | Yes | Must be `paypal`. |
| `paypal_transaction_id` | Yes | ID issued by PayPal for the transaction. |
| `product` | Yes | Products being purchased. |
| `customer` or `customer_id` | Usually | Customer context. |

### PayPal Frontend Flow

Typical direct API/custom storefront PayPal flow:

1. Customer checks out in frontend store.
2. Customer chooses PayPal.
3. PayPal completes the payment.
4. PayPal returns a PayPal transaction ID.
5. The custom storefront/internal system calls `CreateSale`.
6. Request includes `payment_type: "paypal"` and `paypal_transaction_id`.
7. RevCent creates the Sale with PayPal payment context.

AI/MCP clients must not invent the PayPal transaction ID. It must come from PayPal or the frontend checkout result.

### PayPal Example

```json
{
  "campaign": "XXXXXXXXXXXXXXXXXXXX",
  "iso_currency": "USD",
  "ip_address": "203.0.113.10",
  "payment_type": "paypal",
  "paypal_transaction_id": "PAYPAL_TRANSACTION_ID_FROM_FRONTEND",
  "customer": {
    "first_name": "Jane",
    "last_name": "Customer",
    "email": "jane@example.com"
  },
  "product": [
    {
      "id": "XXXXXXXXXXXXXXXXXXXX",
      "quantity": 1
    }
  ],
  "internal_sale_id": "CUSTOM_ORDER_12345"
}
```

---

## Payment Type: `offline_payment`

Use `payment_type: "offline_payment"` when the Sale is paid through an offline or third-party payment processor flow.

The `CreateSale` schema contains a specific metadata requirement for offline payment Sales involving a third-party payment processor.

For offline payment Sales involving a third-party payment processor, the Sale-level `metadata` array must include these three entries:

```json
[
  {
    "name": "offline_payment_third_party",
    "value": "sezzle | afterpay | klarna | affirm | amazon_pay"
  },
  {
    "name": "offline_payment_third_party_transaction_id",
    "value": "[the transaction ID from the third party]"
  },
  {
    "name": "offline_payment_third_party_integration_id",
    "value": "[the RevCent ID of the third party integration within your account for the third party processor]"
  }
]
```

Supported values shown by the schema:

```text
sezzle
afterpay
klarna
affirm
amazon_pay
```

These metadata entries ensure proper association of the Sale within RevCent to the third-party processor transaction.

### Offline Payment Example: Klarna

```json
{
  "campaign": "XXXXXXXXXXXXXXXXXXXX",
  "iso_currency": "USD",
  "ip_address": "203.0.113.10",
  "payment_type": "offline_payment",
  "customer": {
    "first_name": "Jane",
    "last_name": "Customer",
    "email": "jane@example.com"
  },
  "product": [
    {
      "id": "XXXXXXXXXXXXXXXXXXXX",
      "quantity": 1
    }
  ],
  "internal_sale_id": "KLARNA_ORDER_12345",
  "metadata": [
    {
      "name": "offline_payment_third_party",
      "value": "klarna"
    },
    {
      "name": "offline_payment_third_party_transaction_id",
      "value": "klarna-transaction-12345"
    },
    {
      "name": "offline_payment_third_party_integration_id",
      "value": "XXXXXXXXXXXXXXXXXXXX"
    }
  ]
}
```

---

## Payment Type: `check_direct`

Use `payment_type: "check_direct"` when the Sale is paid through a check/direct check payment path.

The `CreateSale` schema does not expose a nested check object. Use the standard required Sale fields and useful metadata/internal IDs for reconciliation.

### Check Direct Example

```json
{
  "campaign": "XXXXXXXXXXXXXXXXXXXX",
  "iso_currency": "USD",
  "ip_address": "203.0.113.10",
  "payment_type": "check_direct",
  "customer": {
    "first_name": "Jane",
    "last_name": "Customer",
    "email": "jane@example.com"
  },
  "product": [
    {
      "id": "XXXXXXXXXXXXXXXXXXXX",
      "quantity": 1
    }
  ],
  "metadata": [
    {
      "name": "check_reference",
      "value": "CHECK-10001"
    }
  ]
}
```

---

## Customer Fields

### `customer`

The `customer` object receives first priority as details when creating a new customer. It is not required if providing an existing `customer_id`.

`customer` has `additionalProperties: false`.

Required when object is provided:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `first_name` | string | Yes | Customer first name. |
| `last_name` | string | Yes | Customer last name. |
| `email` | string/email | Yes | Customer email. |

Optional:

| Field | Type | Description |
|---|---:|---|
| `address_line_1` | string | Customer first address line. |
| `address_line_2` | string | Customer second address line. |
| `city` | string | Customer city. |
| `state` | string | Customer state. |
| `zip` | string | Customer ZIP/postal code. |
| `country` | string | Customer country in three-letter ISO 3166-1 alpha-3 format. |
| `company` | string | Customer company. |
| `phone` | string | Customer phone. |

### `customer_id`

Use `customer_id` when the customer already exists.

The schema states that if a customer already exists and you wish to make a purchase on their behalf using their default credit card, provide the customer's 20-character Customer ID.

Do not charge an existing customer without authorization.

---

## Billing and Shipping Destination Fields

### `bill_to`

Use `bill_to` when billing information differs from the customer information. If `bill_to` is not present, the `customer` object is used.

`bill_to` has `additionalProperties: false`.

Required when object is provided:

```text
first_name
last_name
email
```

Optional fields mirror the customer address/contact fields: `address_line_1`, `address_line_2`, `city`, `state`, `zip`, `country`, `company`, `phone`.

### `ship_to`

Use `ship_to` when the shipping destination differs from customer/billing information. If `ship_to` is not present, the `customer` object or `bill_to` object is used if either is present in the respective order.

`ship_to` has `additionalProperties: false`.

Required when object is provided:

```text
first_name
last_name
email
```

Optional fields mirror the customer address/contact fields: `address_line_1`, `address_line_2`, `city`, `state`, `zip`, `country`, `company`, `phone`.

---

## Metadata Object Schema

Metadata objects appear in multiple places:

- Sale-level `metadata`
- Product-level `product[].metadata`
- Shipping-level `shipping[].metadata`
- Tax-level `tax[].metadata`

Each metadata object has `additionalProperties: false`.

Required fields:

| Field | Type | Required | Limit |
|---|---:|---:|---|
| `name` | string | Yes | 1 to 100 characters. |
| `value` | string | Yes | 1 to 255 characters. |

Example:

```json
{
  "name": "utm_source",
  "value": "google"
}
```

---

## Sale-Level `metadata`

Sale-level metadata is optional but extremely important.

The `CreateSale` schema states that Sale-level metadata is passed down to all items created as a result of the Sale:

- Customer
- Product Sales
- Shipping
- Tax

Use Sale-level metadata for broad attribution and lifecycle dimensions that apply to the full Sale.

Examples:

```json
{
  "metadata": [
    {
      "name": "utm_source",
      "value": "google"
    },
    {
      "name": "utm_campaign",
      "value": "spring_sale"
    },
    {
      "name": "affiliate_id",
      "value": "aff_001"
    }
  ]
}
```

---

## Visitor Tracking Metadata Requirement

If the Sale took place on a website and tracking-domain DNS is set up in RevCent for the website, the request must include the following metadata from the visitor/session cookie:

```json
[
  {
    "name": "revcent_track_id",
    "value": "[the value of visitor/session cookie.revcent_track_id]"
  },
  {
    "name": "revcent_entry_id",
    "value": "[the value of visitor cookie.revcent_entry_id]"
  }
]
```

These values connect the Sale to RevCent DNS tracking and conversion tracking.

This enables:

- Sale origination tracking
- Visitor-to-Sale association
- URL-parameter metadata attribution
- Full lifecycle reporting
- Granular BigQuery analysis by traffic source, campaign, affiliate, click ID, landing page, and related dimensions

AI/MCP clients creating Sales from a tracked website must preserve and include these metadata values.

---

## `product` Array Schema

`product` is required.

Each product entry has `additionalProperties: false`.

Required:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `id` | string | Yes | 20-character Product ID. |

Optional:

| Field | Type | Description |
|---|---:|---|
| `quantity` | integer | Quantity being purchased. Default is 1. |
| `price` | number | Price to charge if different from product default price in RevCent. |
| `metadata` | array<object> | Metadata for this individual product; passed to the eventual Product Sale. |

### Product-Level Metadata

The `CreateSale` schema includes product-level metadata.

Product metadata is passed to the eventual Product Sale for that product. This is extremely useful for business metrics because it supports line-item-specific reporting.

Example: marking an individual product as an upsell.

```json
{
  "id": "XXXXXXXXXXXXXXXXXXXX",
  "quantity": 1,
  "metadata": [
    {
      "name": "is_upsell",
      "value": "true"
    },
    {
      "name": "upsell_step",
      "value": "post_purchase_1"
    }
  ]
}
```

This enables product-level reports on all upsells by filtering Product Sales for metadata such as `is_upsell = true`.

### Product Sales Created From Products

When a Sale is created, RevCent creates Product Sale line items from the products sold.

Product Sales support:

- Product-level revenue
- SKU-level analysis
- Product-level refunds
- Product-level metrics
- Upsell/downsell reporting through product metadata
- Subscription and trial origination
- Fulfillment logic
- BigQuery analysis

If a sold product has an associated subscription profile, RevCent can automatically create a subscription. If a sold product has trial settings, RevCent can automatically create a trial. If a sold product is shippable, RevCent can create shipment/fulfillment outcomes.

---

## `shipping` Array Schema

`shipping` is optional.

Each shipping entry has `additionalProperties: false`.

Required:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `amount` | number | Yes | Amount to charge for the shipping entry. Can be 0. |

Optional:

| Field | Type | Description |
|---|---:|---|
| `provider` | string | Shipping provider. Included when creating shipment at a fulfillment center. |
| `provider_method` | string | Shipping provider method corresponding to provider. |
| `name` | string | Optional shipping entry name. |
| `description` | string | Optional shipping entry description. |
| `metadata` | array<object> | Metadata for this individual shipping entry; passed to the eventual shipping item. |

### Shipping-Level Metadata

Shipping metadata is passed to the eventual shipping item for the Sale.

Example:

```json
{
  "shipping": [
    {
      "amount": 6.95,
      "provider": "usps",
      "provider_method": "priority",
      "name": "USPS Priority",
      "metadata": [
        {
          "name": "fulfillment_priority",
          "value": "standard"
        }
      ]
    }
  ]
}
```

Use shipping metadata for shipping-specific reporting and fulfillment context.

---

## `tax` Array Schema

`tax` is optional.

Each tax entry has `additionalProperties: false`.

Required:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `amount` | number | Yes | Amount to charge for the tax entry. |

Optional:

| Field | Type | Description |
|---|---:|---|
| `name` | string | Optional tax entry name. |
| `description` | string | Optional tax entry description. |
| `metadata` | array<object> | Metadata for this individual tax entry; passed to the eventual tax item. |

### Tax-Level Metadata

Tax metadata is passed to the eventual tax item for the Sale.

Example:

```json
{
  "tax": [
    {
      "amount": 3.25,
      "name": "Sales Tax",
      "description": "NY sales tax",
      "metadata": [
        {
          "name": "tax_region",
          "value": "NY"
        }
      ]
    }
  ]
}
```

---

## `coupon` Array Schema

`coupon` is optional.

Each coupon entry has `additionalProperties: false`.

Required:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `coupon_code` | string | Yes | Coupon code that exists in RevCent. |

Example:

```json
{
  "coupon": [
    {
      "coupon_code": "SPRING20"
    }
  ]
}
```

Use `EstimateSale` first if the user needs to preview coupon validity or savings before charging.

---

## `discount` Array Schema

`discount` is optional.

Each discount entry has `additionalProperties: false`.

Required:

| Field | Type | Required | Description |
|---|---:|---:|---|
| `discount_value` | number | Yes | Discount value relative to `discount_type`. |
| `discount_type` | string enum | Yes | Either `percent` or `amount`. |

Optional:

| Field | Type | Description |
|---|---:|---|
| `name` | string | Optional discount name. |
| `description` | string | Optional discount description. |
| `apply_to_product` | boolean | Whether discount applies to products purchased. Default is true. |
| `apply_to_shipping` | boolean | Whether discount applies to shipping. Default is true. |

Allowed `discount_type` values:

```json
[
  "percent",
  "amount"
]
```

Example:

```json
{
  "discount": [
    {
      "discount_value": 10.00,
      "discount_type": "amount",
      "name": "Customer Service Credit",
      "description": "$10 courtesy discount",
      "apply_to_product": true,
      "apply_to_shipping": false
    }
  ]
}
```

---

## `sale_id` for Re-Attempting Failed/Pending Sales

`CreateSale` includes optional `sale_id`.

The schema describes it as the RevCent Sale ID of a previously created Sale that failed payment and is in a pending state, when re-attempting a failed payment on a Sale that has not changed. It is similar to the `ProcessPendingSale` operation.

Use `sale_id` only when:

- A previous Sale failed payment
- The Sale is in pending state
- The Sale contents have not changed
- The user/system wants to re-attempt payment

If the Sale needs to be modified before payment, use:

```text
UpdatePendingSale → ProcessPendingSale
```

---

## Internal IDs

### `internal_sale_id`

Use `internal_sale_id` for an external order ID or internal system order ID.

Examples:

- Custom storefront order ID
- Internal CRM order ID
- Marketplace order ID
- Custom checkout order ID
- Non-WooCommerce system ID

### `internal_customer_id`

Use `internal_customer_id` for an external customer ID.

Examples:

- Custom storefront customer ID
- CRM customer ID
- Marketplace customer ID
- Internal system customer ID

Internal IDs are helpful for reconciliation, support, reporting, and syncing with external systems.

---

## Complete Credit Card Example With Tracking and Product Metadata

```json
{
  "campaign": "XXXXXXXXXXXXXXXXXXXX",
  "iso_currency": "USD",
  "ip_address": "203.0.113.10",
  "payment_type": "credit_card",
  "payment_profile": "XXXXXXXXXXXXXXXXXXXX",
  "customer": {
    "first_name": "Jane",
    "last_name": "Customer",
    "email": "jane@example.com",
    "phone": "555-555-5555",
    "address_line_1": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zip": "10001",
    "country": "USA"
  },
  "credit_card": {
    "card_number": "<CARD_NUMBER_COLLECTED_SECURELY>",
    "exp_month": 12,
    "exp_year": 29,
    "card_code": "<CARD_CODE_COLLECTED_SECURELY>"
  },
  "product": [
    {
      "id": "XXXXXXXXXXXXXXXXXXXX",
      "quantity": 1,
      "metadata": [
        {
          "name": "is_upsell",
          "value": "false"
        }
      ]
    },
    {
      "id": "YYYYYYYYYYYYYYYYYYYY",
      "quantity": 1,
      "price": 19.95,
      "metadata": [
        {
          "name": "is_upsell",
          "value": "true"
        },
        {
          "name": "upsell_step",
          "value": "post_purchase_1"
        }
      ]
    }
  ],
  "shipping": [
    {
      "amount": 6.95,
      "provider": "usps",
      "provider_method": "priority",
      "name": "USPS Priority",
      "metadata": [
        {
          "name": "fulfillment_priority",
          "value": "standard"
        }
      ]
    }
  ],
  "tax": [
    {
      "amount": 3.25,
      "name": "Sales Tax",
      "metadata": [
        {
          "name": "tax_region",
          "value": "NY"
        }
      ]
    }
  ],
  "coupon": [
    {
      "coupon_code": "SPRING20"
    }
  ],
  "discount": [
    {
      "discount_value": 5.00,
      "discount_type": "amount",
      "name": "Courtesy Discount",
      "apply_to_product": true,
      "apply_to_shipping": false
    }
  ],
  "internal_sale_id": "CUSTOM_ORDER_12345",
  "internal_customer_id": "EXT_CUSTOMER_98765",
  "metadata": [
    {
      "name": "revcent_track_id",
      "value": "visitor-session-track-id"
    },
    {
      "name": "revcent_entry_id",
      "value": "visitor-entry-id"
    },
    {
      "name": "utm_source",
      "value": "google"
    },
    {
      "name": "utm_campaign",
      "value": "spring_sale"
    },
    {
      "name": "affiliate_id",
      "value": "aff_001"
    }
  ]
}
```

---

## Output Schema

The MCP output schema is:

```json
{
  "type": "object",
  "additionalProperties": false,
  "properties": {},
  "required": []
}
```

AI/MCP clients should not assume undocumented output fields.

If details of the created Sale are needed afterward, use follow-up lookup/search/detail workflows based on known identifiers and integration context.

---

## Downstream Outcomes

`CreateSale` can create or trigger downstream outcomes depending on product settings, account configuration, payment type, integrations, and event configuration.

```text
CreateSale
├─ Customer created or linked
├─ Payment processed or linked
│  ├─ Credit card transaction
│  ├─ PayPal transaction
│  ├─ Offline payment
│  └─ Check direct
├─ Credit card payment information stored in RevCent PCI DSS Level 1 vault
├─ Product Sales created
│  ├─ Product-level metadata passed to Product Sale
│  ├─ Product-level metrics enabled
│  └─ Product-level refund path via RefundProductSale
├─ Shipping records can be created
│  ├─ Shipping metadata passed to shipping item
│  └─ Fulfillment workflow can begin
├─ Tax records can be created
│  └─ Tax metadata passed to tax item
├─ Discounts can be created
├─ Coupons can apply discounts
├─ Subscription can be created if sold product has subscription profile
├─ Trial can be created if sold product has trial settings
├─ Sale-level metadata passes to customer, product sales, shipping, and tax
├─ DNS tracking metadata can attach visitor/session attribution
├─ Email Templates can send configured messages
├─ Events can trigger AI Assistants, AI Voice Agents, Functions, webhooks, notes, and metadata workflows
└─ BigQuery reporting becomes possible across the Sale lifecycle
```

---

## Refund Implications

Refund routing after `CreateSale` depends on what needs to be refunded.

| Refund Intent | Correct Operation |
|---|---|
| Refund one product line item | `RefundProductSale` |
| Refund part of one product line item | `RefundProductSale` with `amount` |
| Refund shipping | `RefundShipment` |
| Refund part of shipping | `RefundShipment` with `amount` |
| Refund tax | `RefundTax` |
| Refund part of tax | `RefundTax` with `amount` |
| Refund the entire Sale | `VoidSale` |

Do not manually refund every component if the user wants a full Sale refund. Use `VoidSale`.

Do not omit `amount` in a component-level refund unless the user intends to refund the entire component.

---

## Reporting and Metrics

Do not use `GetSales` for reporting on Sales created by `CreateSale`.

Use `BigQueryRunQuery` for:

- Sales reporting
- Revenue reporting
- Product Sale reporting
- Product-level metadata analysis
- Upsell/downsell reporting
- Refund metrics
- Shipping metrics
- Tax reporting
- Coupon/discount performance
- Payment type analysis
- Offline third-party processor reporting
- DNS tracking attribution
- Customer lifetime value
- Trial/subscription creation analysis
- AI recovery performance
- Voice recovery performance
- Campaign/shop/source reporting

Use `GetBigQueryTables` before querying if exact table names or fields are unknown.

---

## Validation Checklist Before Calling `CreateSale`

Before calling `CreateSale`, verify:

- `CreateSale` is the correct operation and the flow is not a normal WooCommerce plugin checkout purchase.
- Campaign ID is valid.
- Product IDs are valid.
- Product quantities and override prices are intentional.
- Product-level metadata is included when line-item reporting is needed.
- Payment type is correct.
- Credit card Sales include `payment_profile`.
- New-card credit card Sales include `credit_card`.
- PayPal Sales include a real `paypal_transaction_id` from PayPal/frontend checkout.
- Offline third-party payment Sales include the three required metadata entries.
- Customer or Customer ID is correct.
- Billing and shipping objects are correct when provided.
- Shipping entries are correct and include metadata if needed.
- Tax entries are correct and include metadata if needed.
- Coupon codes and discounts are intentional.
- Sale-level metadata includes DNS tracking values when the Sale happened on a tracked website.
- `revcent_track_id` and `revcent_entry_id` are included when tracking-domain DNS is configured.
- Internal Sale ID and internal Customer ID are included for external/custom systems.
- The customer/user authorized the payment.
- `EstimateSale` was used first if totals need to be previewed.

---

## Common Mistakes to Avoid

Do not:

- Use `CreateSale` for normal WooCommerce checkout handled by the RevCent Payments plugin.
- Use `CreateSale` when the user only wants an estimate.
- Use `CreateSale` for a multi-step checkout that should remain pending.
- Guess Campaign, Product, Payment Profile, Customer, Sale, PayPal transaction, or Integration IDs.
- Omit `payment_profile` for credit card Sales.
- Omit `paypal_transaction_id` for PayPal Sales.
- Omit offline payment third-party metadata for Sezzle, Afterpay, Klarna, Affirm, or Amazon Pay Sales.
- Omit `revcent_track_id` or `revcent_entry_id` for tracked website Sales.
- Put upsell metadata only at the Sale level when the reporting need is product-line-item-specific.
- Forget that product metadata passes to the Product Sale.
- Forget that shipping metadata passes to the shipping item.
- Forget that tax metadata passes to the tax item.
- Use non-descriptive metadata names.
- Create a Sale without payment authorization.
- Use `GetSales` for reporting or aggregation.
- Forget that products with subscription profiles can automatically create subscriptions.
- Forget that products with trial settings can automatically create trials.
- Forget that shippable products can trigger shipment/fulfillment workflows.

---

## Final AI/MCP Instruction

Use `CreateSale` for direct API/AI/custom/internal paid Sale creation.

Do not use `CreateSale` for normal WooCommerce plugin purchases because the RevCent Payments plugin for WordPress handles those payments and creates the Sales.

Build the request strictly according to the schema, include all required payment-specific fields, preserve tracking and third-party metadata, use product/shipping/tax metadata for item-level reporting, and use `BigQueryRunQuery` for all reporting and metrics after Sales are created.


---
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.