Skip to main content

Send Won Quotes to Your Distributor Order System

Connect a distributor webhook that turns a connected contractor’s won quote into a secure, order-ready payload.

Written by Hayden Lewis

When a connected contractor wins a quote, SetSale can send the selected quote directly to your distributor order system. The webhook includes the contractor reference, chosen option, equipment models, AHRI number, quantities, warranties, discounts, rebates, and selected work.

This guide shows a distributor administrator how to register a secure order-intake endpoint and test the complete won-quote flow.

How It Works

  1. A connected contractor completes checkout and the quote becomes Won.

  2. SetSale sends a signed contractor.quote.won request to your HTTPS endpoint.

  3. Your receiver verifies the signature and ignores duplicate event IDs.

  4. Your integration maps the chosen option into an order in your ERP or fulfillment system.

  5. Your endpoint returns a successful response within 10 seconds.

Before You Begin

  • Distributor administrator access to Settings → API & Webhooks.

  • A public HTTPS POST endpoint owned by your organization.

  • A server-side secret manager for the signing secret.

  • At least one connected sandbox contractor for testing.

  • A durable database or queue for duplicate protection and order processing.

⚠️ Heads Up: You do not need an API key just to receive this webhook. Never place an API key, signing secret, or private webhook URL in browser code, screenshots, tickets, or shared documentation.

Step-by-Step Instructions

1. Select the Distributor Event

Open the SetSale API documentation and select [Distributor] contractor.quote.won under Webhooks.

This is the distributor event. The similarly named contractor event belongs to the contractor's own account and has a different payload.

2. Add Your Order-Intake Endpoint

  1. In the distributor account, go to Settings → API & Webhooks.

  2. Under Webhook endpoints, select Add endpoint.

  3. Enter the public HTTPS URL for your order system.

  4. Add a clear description, such as Production order intake.

  5. Select only Contractor quote won — contractor.quote.won.

  6. Select Create endpoint.

Use a dedicated route such as https://orders.example.com/webhooks/setsale. Do not use a personal inbox URL, a URL containing credentials, or a client-side page.

3. Save the Signing Secret

  1. Copy the signing secret immediately. SetSale displays it only once.

  2. Store it in your server's secret manager as SETSALE_WEBHOOK_SECRET.

  3. Do not commit it to source control or paste it into frontend code, documentation, or support messages.

  4. Select Done after it is safely stored.

⚠️ Heads Up: If the secret is exposed, rotate it and update your server before accepting more orders.

4. Build the Receiver

Your receiver should perform these checks before creating an order:

  • Read the raw request body before parsing JSON.

  • Verify setsale-signature with HMAC-SHA256 and your signing secret.

  • Reject timestamps more than five minutes from your server clock.

  • Compare signatures in constant time.

  • Deduplicate deliveries using setsale-event-id.

  • Treat only contractor.quote.won as an order. The Send test button sends a ping event.

  • Queue order creation and return a successful response within 10 seconds.

Copy-and-paste receiver resource

Use the setsale-distributor-order-receiver.txt file attached at the bottom of this page as a starting point. It includes signature verification, replay protection, chosen-option extraction, equipment grouping, quantities, and queue placeholders.

Note: The attachment uses a .txt extension so Intercom keeps it downloadable. You will need to rename it to .js in your project in order for it to execute.

5. Map the Won Quote to an Order

Find the selected option by matching the option ID to quote.chosenOptionId. Do not create orders from every option in the payload.

Recommended field mapping

  • setsale-event-id → idempotency key and duplicate protection.

  • data.contractor.externalId → contractor account number in your system.

  • data.contractor.name → contractor display name.

  • data.quote.id → source quote reference.

  • data.quote.url → link back to SetSale.

  • Chosen option totalPrice → quoted total.

  • systems[].ahriNumber → AHRI reference.

  • systems[].equipment[] → manufacturer, model number, and equipment type.

  • addons[], services[], and additionalWorkItems[] → extra order lines with quantity preserved.

  • thermostats[] and additionalEquipment[] → additional equipment lines.

  • warranties[] → warranty coverage.

  • discounts[] and rebates[] → pricing adjustments and reconciliation data.

  • data.wonAt → won timestamp.

Each equipment entry represents one unit. If the same model appears more than once, group identical models and count them. Preserve the supplied quantity on priced line items. Route any line with a missing quantity to review instead of silently guessing.

The distributor payload intentionally excludes customer contact information. Treat this webhook as an order-ready quote snapshot, not a customer-contact feed.

6. Test the Complete Flow

  1. On the endpoint page, select Send test. Confirm your receiver accepts the ping event and returns a successful response.

  2. In a connected sandbox contractor account, create a quote with safe test data, choose an option, and complete checkout so the quote becomes Won.

Include an AHRI matchup, equipment, and at least one quantity-bearing line item so the test exercises your order mapping.

Confirm the delivery

  • The endpoint is Enabled.

  • It is listening to Contractor quote won.

  • Failed remains 0.

  • The contractor.quote.won delivery shows Succeeded with a successful response.

In the tested preview flow, SetSale delivered contractor.quote.won successfully. The signed payload contained the chosen option, one system, three equipment models, an AHRI number, and quantities on every selected priced line. The signature was independently verified against the raw body.

Production Checklist

  • Keep SETSALE_WEBHOOK_SECRET server-side only.

  • Verify the raw body before parsing JSON.

  • Enforce the five-minute timestamp tolerance.

  • Store setsale-event-id with a unique database constraint.

  • Queue order creation and acknowledge within 10 seconds.

  • Alert on failed responses and growing delivery latency.

  • Preserve equipment and line-item quantities.

  • Map contractor.externalId before enabling automated fulfillment.

  • Test secret rotation and replay handling before launch.

Troubleshooting

The Send test works, but no order is created

The test sends ping, not contractor.quote.won. Complete checkout on a quote from a contractor connected to this distributor.

The quote is won, but no distributor event appears

Confirm the contractor is connected to this distributor, the endpoint is enabled, and Contractor quote won is selected.

Signature verification fails

Verify against the exact raw body bytes. Parsing and re-stringifying JSON changes the signed value.

The same order appears twice

Webhook delivery is at least once. Use setsale-event-id as an idempotency key backed by an atomic unique constraint.

The endpoint was disabled

Fix timeouts or failed responses, then re-enable the endpoint. SetSale automatically disables an endpoint after 20 consecutive failed delivery attempts.

Need Help?

Share the event timestamp, event type, and response status with your SetSale contact. Never send your signing secret, API keys, authorization headers, full webhook URL, or unredacted payloads.

Copy-and-paste receiver example 👇

Did this answer your question?