Embed dynamic Travel Insured products and choose a Travel Insured purchase handoff or a partner-controlled hybrid flow.
Audience: Partner product teams, developers, solution architects, and QA teamsLast Updated: November 4, 2026
The Product Quote Card is a supported embedded integration strategy, not only a UI widget. The product-quote-card web component renders Travel Insured quote results inside your site so customers can compare products, review prices and coverage details, select supported optional add-ons, and choose a product without your team building the product-shopping UI.
After selection, choose one of two models:
Expedited Embedded: configure a Pay Now or Buy Now destination supplied by Travel Insured. The card navigates the customer into the Travel Insured purchase experience, which owns the remaining consumer journey.
Hybrid Embedded: receive the card's selection events, validate the selected state on your server, and continue through the approved Travel Insured API, purchase staging flow, or payment workflow for your account.
Hosted Partner Payment App (event-driven): keep the purchase experience inside the host application or partner-owned payment widget. The web component emits the staged purchase state so the host can create a payment session or continue the next step without redirecting the customer to the Travel Insured purchase app.
The component runtime and interactive test harness remain on the Product Web Component application.
Why Use It
The Product Quote Card can reduce the front-end work needed to present Travel Insured products while preserving a choice of downstream ownership. The verified component supports:
Area
Supported behavior
Product rendering
One or more dynamically rated products, plan names, prices, coverage details, carousel or grid layouts, and standard or comparison card variants
Coverage experience
Base coverage details, supported optional add-ons, updated price display, and coverageChanged events
Selection
Product selection, a versioned selectedPlan event, and configurable CTA text
Purchase handoff
Direct URL navigation, event-driven partner handoff, staged purchase payloads, and host-owned payment app integration
sequenceDiagram
participant Customer
participant UI as Partner website
participant API as Partner backend
participant Auth as TII embed auth
participant Quote as TII quote service
participant Card as Product Quote Card
participant Purchase as TII purchase experience
Customer->>UI: Enter trip and traveler information
UI->>API: Request quote experience
API->>Auth: POST embed-token with apiToken and accessKey
Auth-->>API: Short-lived embedToken
API->>Quote: Create quote with Bearer embedToken
Quote-->>API: Quote number and rated products
API-->>UI: Client-safe quote response
UI->>Card: Set quote-request-input
Card-->>Customer: Render products and coverages
Customer->>Card: Select product and optional coverages
Customer->>Card: Select Pay Now
Card->>Purchase: Navigate to configured TII destination
Purchase-->>Customer: Continue purchase experience
apiToken and accessKey stay on the partner backend. The recommended flow also uses embedToken server-side to pre-fetch the quote, then gives the browser only the quote response and client-safe component configuration.
Hybrid Embedded and Staged Purchase Flow
MERMAID
sequenceDiagram
participant Customer
participant UI as Partner website
participant API as Partner backend
participant Card as Product Quote Card
participant BFF as Product Web Card BFF
participant TII as Travel Insured APIs
Customer->>UI: Enter trip and traveler information
UI->>API: Request quote experience
API->>TII: Authenticate and create quote
TII-->>API: Quote number and rated products
API-->>UI: Client-safe quote response
UI->>Card: Set quote-request-input
Card-->>Customer: Render products and coverage options
Customer->>Card: Select product or optional coverage
Card-->>UI: coverageChanged and selectedPlan
UI->>API: Submit selection and staged payload
API->>BFF: Stage selected policy and purchase state
BFF->>TII: Validate and persist staged purchase state
TII-->>BFF: Final staged purchase result
BFF-->>UI: Purchase-ready payload or error
UI-->>Customer: Redirect, continue in payment app, or remain in page based on host configuration
Browser event data is untrusted input. Retrieve or validate the quote, product, price, eligibility, expiry, and applicable coverage state on the server before a sensitive downstream operation. The purchase staging API is the system of record for final purchase readiness and total price validation.
Hosted Payment App (event-only)
The host app may own the payment experience and create a payment session from the payload emitted by the web component rather than by redirecting the browser to a Travel Insured purchase URL.
MERMAID
sequenceDiagram
participant Customer
participant Host as Partner app or payment app
participant Card as Product Quote Card
participant BFF as Product Web Card BFF
participant TII as Travel Insured APIs
Customer->>Card: Select product and optional coverages
Card-->>Host: selectedPlan and purchaseStageRequest
Host->>BFF: Validate and stage selected purchase state
BFF->>TII: Stage policy and finalize total
TII-->>BFF: Valid staged result
Host->>Host: Create hosted payment session / continue approved flow
Host-->>Customer: Payment flow without redirect to product-card app
This pattern is intended for host-owned payment integrations and should not be treated as a direct redirect back to the card application. The browser should receive only the final purchase-ready state and whatever host-side action is required for the approved payment or subsequent workflow.
Authentication and Embed Token
Travel Insured supplies these partner credentials through an approved onboarding channel:
Credential
Used by
Purpose
apiToken
Partner backend only
Partner API credential used to request an embed token
accessKey
Partner backend only
Partner access credential used with apiToken
embedToken
Partner backend; browser only when client-side quote fetching is required
Short-lived JWT scoped to quote operations and an allowed origin
Never expose apiToken or accessKey in HTML, JavaScript bundles, component attributes, query strings, browser storage, logs, analytics, screenshots, or version control.
Request an embed token
Your backend calls:
HTTP
POST https://productwebc-sbtii.azurewebsites.net/api/auth/embed-token
Content-Type: application/json
The documented token lifetime is 3,600 seconds. Cache it server-side by allowed origin and scopes, refresh it before expiry, and request a new token after a 401. The allowedOrigin must be registered with Travel Insured and must match the browser origin for browser-originated quote requests. For staged purchase handoff the embed JWT is validated at the Product Web Card BFF boundary; the JWT is not forwarded upstream to the GraphQL service. The BFF decrypts the partner credentials from the validated JWT and then uses those upstream credentials to call Travel Insured's underlying APIs.
Sandbox URLs are shown here to document the contract. Production service and component URLs are provided by Travel Insured during onboarding.
Create a Quote
All sandbox quote endpoints use Authorization: Bearer <embedToken>.
Endpoint
Purpose
Required scope
POST /api/quotes
Create and rate a new quote
quote:create
POST /api/quotes accepts the trip, residency, destination, and traveler request below. Dates use YYYY-MM-DD; at least one destination and traveler are required; exactly one traveler is primary; and tripCost is a positive per-traveler amount in the requested currency.
HTTP
POST https://productwebc-sbtii.azurewebsites.net/api/quotes
Authorization: Bearer <embed-token>
Content-Type: application/json
Required account identifier assigned by Travel Insured
agentId, groupNumber
Optional or account-specific attribution values; omit or send null when not assigned
quoteNumber
null for a new quote; use the saved quote identifier only for the approved re-rate flow
residencyCountryIsoCode
Required ISO country code
residencyStateIsoCode
Required when the residency country or enabled product requires a state
language, currency, tripType
Required request context using values enabled for the account
trip.departureDate, trip.returnDate
Required ISO dates with return after departure
trip.depositDate, trip.finalPaymentDate
Optional lifecycle dates; send null when not applicable
trip.destinations
At least one destination with countryIsoCode; stateIsoCode is conditional
trip.travelers
At least one traveler with a stable request id, exactly one primaryTraveler, date of birth, name, and positive tripCost; email is included for the primary traveler in the supported browser contract
Representative response:
JSON
{"quoteNumber":"Q-EXAMPLE-001","products":[{"productId":2001,"productCode":"PARTNER_STANDARD","productName":"Partner Standard","productDescription":"Flexible protection for the covered journey","upsellProduct":null,"imageUrl":"https://cdn.example.test/products/partner-standard.png","availablePaymentMethod":[],"coverages":[{"available":true,"customDates":false,"productCoverageId":101,"productCoverageType":"Trip Cancellation","productCoverageTypeCode":"TC","productCoverageExplanation":"Covers eligible trip cancellation","coverageClassification":"Base","selected":false,"coverageLimits":[{"maxPerPlanLimitAmount":6000,"maxPerPersonLimitAmount":6000,"productCoverageLimitId":1001,"additionalText":"Coverage up to the eligible trip cost","totalPrice":124.5,"travelerBreakdown":[{"id":1,"price":124.5}]}],"benefits":[{"categoryName":"Trip Protection","description":"Trip cancellation or interruption","limit":"100%","limitDescription":"Up to the eligible trip cost","toolTip":"Covered reasons apply"}]}]}]}
Retain quoteNumber, productId, productCode, and the response-derived coverage and coverage-limit identifiers on the trusted server. The card needs the complete client-safe response to render. selectedPlan identifies the chosen quote and product for a Hybrid handoff; coverageChanged is a browser selection signal that still requires server validation. purchaseStageRequest is the pre-flight purchase payload emitted before the BFF staging call so the host can preview and validate the exact staging request values before the call is made. Expedited Pay Now uses the documented URL placeholders, subject to the optional-coverage owner-confirmation gap below.
Keep partner credentials and the authoritative quote request on the server. Pass only the short-lived embedToken when browser-side fetching is required, or preferably pass the client-safe quote response. Treat every identifier, price, event, and changed coverage returned by the browser as untrusted and revalidate it before purchase, payment, or issuance.
The component supports two input models:
Pre-fetched response, recommended: the partner backend calls POST /api/quotes, then passes the complete response to quote-request-input. The component renders without another API request.
Client-side request: pass quote request parameters to quote-request-input, set api-base-url, and set the short-lived embed-token. The component calls the quote service from the browser.
The pre-fetched model minimizes browser authorization and is recommended for both Expedited and Hybrid integrations.
Render Dynamic Products
Load the module once, wait for custom-element registration when your framework requires it, and set the quote response as a JSON string.
quoteResponse is the complete response returned by your backend. Do not put apiToken or accessKey in this code or on the element.
Product and Coverage Features
Rated products can include productId, productCode, productName, coverage collections, product details, and pricing. The card can present one or multiple products, product details, base coverages, and optional add-ons returned for the partner's enabled catalog.
The display and event contract does not make browser state authoritative. In Hybrid integrations, retain identifiers from the current quote response and validate them server-side before purchase staging, payment, or policy issuance.
Pay Now and Travel Insured Purchase Handoff
For Expedited Embedded, Travel Insured provides the environment- and partner-specific purchase destination during onboarding. Configure the CTA in URL mode:
URL template that replaces {quoteNumber}, {productCode}, and {productId} at click time
buy-now-url
Navigates to the configured URL without documented placeholder expansion
enable-internal-navigation
Must be true to enable component navigation; defaults to false
button-text
CTA label; defaults to Buy Now
When button-url or buy-now-url is configured, the component navigates instead of emitting selectedPlan. Use the exact Travel Insured destination supplied for your account; the example hostname above is documentation-only.
Hybrid Partner-Controlled Handoff
Omit button-url and buy-now-url so the CTA emits selectedPlan. Listen for both supported events and send the required selection to your backend over an authenticated partner session. Your backend then retrieves or validates authoritative state and continues through the approved API or Hosted Payment flow.
Do not use URL navigation and a selectedPlan listener as competing handoff mechanisms.
Staging and event-only / payment-app flows
The staged purchase flow is a supported integration pattern for partner-controlled handoff. When the user selects a plan, the component emits:
selectedPlan for the final selected product and purchase metadata
purchaseStageRequest for the exact payload that will be sent to the Product Web Card BFF purchase-stage endpoint before a redirect or payment action occurs
The host app can choose one of the following patterns:
Redirect flow: after the stage request succeeds, navigate to the configured purchase destination.
Event-only flow: consume the event payload and continue with the partner's own application flow.
Host-owned payment app flow: create the payment session from the staged payload without redirecting the customer to the product card host app.
Failure-blocking flow: when the stage request fails, the host application must stop navigation and display the returned error state instead of continuing the purchase journey.
The payload preview must be visible before the request is sent so QA can validate the values used by the stage call and compare them to the response returned by the API.
Component API
The custom element name is product-quote-card. Attribute values are strings; pass quote-request-input with JSON.stringify(...).
Core and CTA attributes
Attribute
Required
Default
Allowed values or behavior
quote-request-input
Yes
None
Full BFF quote response or quote request parameters as JSON
The legacy api-token and access-key attributes are deprecated. Do not use them; exposing those credentials in the browser violates the security boundary.
Product detail and presentation attributes
Attribute
Default
Purpose
logo-src / logo-alt
None / Product logo
Product header image and accessible alternative text
Select a Travel Insured-managed partner stylesheet when configured
Comparison-shell, market-variant, and single-offer presentation controls are available only when enabled for the account. Confirm their configured product rules and copy with Travel Insured during onboarding rather than inferring market behavior.
Event Reference
Both events are bubbling and composed CustomEvent instances and cross the component's Shadow DOM boundary.
selectedPlan
Fires when the user selects the CTA in event-driven mode. It does not fire when button-url or buy-now-url controls navigation.
Use contractVersion for compatibility checks. Submit the identifiers to your backend, then validate the quote and product before downstream operations. The event is a user-selection signal, not authoritative purchase state. It represents the staged final state after user selection and should be treated as the canonical payload for host-driven purchase or payment flows when a redirect is not used.
purchaseStageRequest
Fires immediately before the component issues the purchase-stage request to the Product Web Card BFF. This payload is the exact staging contract sent to the purchase-stage endpoint and is intended for QA preview, validation, and host-side pre-flight inspection.
Use this event to confirm the exact payload values before the stage call runs. The host app should compare the preview with the returned staged purchase result and block navigation or payment-session creation when the stage call fails.
coverageChanged
Fires when a customer toggles a supported optional add-on on a card or in the plan-detail modal.
source is card or modal. Use the event to update partner-controlled display state and send the selection to your backend in a Hybrid integration. Do not treat totalPrice or coverage selection as authoritative without server validation. Its relationship to URL-mode Pay Now remains the owner-confirmation gap documented above.
Styling and Branding
The component uses Shadow DOM, so ordinary page selectors do not style its internals. Prefer CSS custom properties on the element or an ancestor:
External stylesheets must use HTTPS outside local development. Same-origin stylesheets are allowed; other origins must appear in custom-stylesheet-allowed-origins. Travel Insured's supported customization limits and partner branding approval still apply.
Framework Examples
React and Next.js
Load the module in an effect, wait for registration, set JSON through the DOM element, and attach native custom-event listeners.
For Next.js, keep this in a Client Component. Acquire the quote or embed token through a server-only route; never read apiToken or accessKey from a NEXT_PUBLIC_ variable. Render the custom element only in the browser to avoid server-side custom-element and hydration failures.
Vue and Nuxt
Tell the Vue compiler that the tag is a custom element:
In Vue 3, use an element ref, wait for customElements.whenDefined('product-quote-card'), call setAttribute('quote-request-input', JSON.stringify(quoteResponse)), and attach selectedPlan, purchaseStageRequest, and coverageChanged with addEventListener. Vue 2 can add product-quote-card to Vue.config.ignoredElements.
Accessibility and Responsive Behavior
The card is responsive and offers carousel, grid, comparison, and account-configured market layouts. The host page remains responsible for the complete experience around it:
Give the quote region an accessible name and preserve logical heading and focus order.
Announce loading, errors, and completed host actions without relying on color alone.
Preserve the component's visible focus indicators and accessible logo text.
Test keyboard operation, plan-detail modal focus, screen readers, 200% zoom, 320 CSS-pixel reflow, contrast, and reduced motion.
Test every enabled product, optional coverage, language, currency, and supported viewport.
Automated checks cannot establish WCAG 2.2 Level AA conformance. Complete manual keyboard and assistive-technology review before launch. The current public contract does not list a browser support matrix; confirm supported browser versions during onboarding.
Testing and Test Harness
The Product Quote Card Integration Harness is a sandbox/testing tool. It can request an embed token, create or load a quote, inspect BFF JSON, render the component, change supported layout and theme controls, test URL or event handoffs, validate the staged purchase payload, and inspect selectedPlan, purchaseStageRequest, and coverageChanged payloads.
Use only assigned sandbox credentials and synthetic data. The harness stores entered partner credentials in page memory for the active test; do not use production credentials or shared screenshots. The harness and component runtime are supporting tools, not a second canonical documentation source.
Required validation scenarios for staged purchase and payment-app integration
The harness should be used to verify all supported handoff patterns, not a single redirect-only path:
Successful redirect flow: validate that a selected plan stages successfully and only then redirects the browser to the configured purchase page.
Successful event-only flow: validate that the host app receives the full purchase-ready payload and can continue on the partner page, open a payment session, or remain on the page without forcing a direct redirect.
Host-owned payment app flow: validate that the harness or host app can create a payment session or continue a partner-owned payment flow using the emitted payload without redirecting the user to the Travel Insured site for payment.
Pre-stage data path: validate that a complete purchase request can be constructed before the component loads or before the user selects a plan.
Post-selection data path: validate that the staged payload reflects the final selected product and add-on benefit state after user interaction and not stale default values.
Failure / no redirect path: when the stage API returns an error, confirm that no navigation occurs, no payment session is created, and the error is surfaced clearly in the host app.
Preview validation: confirm the harness exposes the payload before the stage call and the returned staged state after the call so QA can compare request and response values in real time.
Agency / agent validation: confirm the staged request uses the correct agency and agent identifiers and is rejected clearly when required values are absent or mismatched.
Retry / stale-state validation: after a failed or changed selection, confirm the next purchase attempt uses the most recent staged values and not stale request data from the earlier attempt.
Mode parity validation: confirm the same final staged purchase state is available in redirect mode and event-only mode, with only host behavior differing by integration pattern selected in the harness.
Troubleshooting
Symptom
Likely cause
Action
Embed-token request returns 401
Invalid, expired, revoked, or wrong-environment credentials
Confirm the server-side apiToken and accessKey with Travel Insured
Embed-token request returns 403
Account lacks embed permission
Request embed enablement through onboarding support
Quote returns INVALID_ORIGIN
Browser origin differs from token allowedOrigin
Use the exact registered origin, including scheme and port
Quote returns AGENCY_MISMATCH
Request agency differs from credential mapping
Use the agency assigned to the same credentials
No products are returned
No enabled product matches input or account configuration
Verify input, market, currency, catalog, and response correlation ID
Component remains loading
Invalid JSON, unreachable api-base-url, or script registration failure
Inspect Network and Console; pass JSON.stringify(quoteResponse) and await registration
selectedPlan does not fire
URL mode is configured
Remove button-url and buy-now-url for event-driven Hybrid mode
purchaseStageRequest preview is missing
The component did not emit the staged request before the stage call
Confirm the component emitted the event before the BFF fetch and inspect the harness preview panel
Pay Now does not navigate
Internal navigation is disabled or destination is invalid
Set enable-internal-navigation="true" and use the assigned destination
Coverage price differs downstream
Browser state is stale or coverage transfer is not defined
Revalidate server-side; do not assume URL mode propagates changed coverages
Vue cannot resolve the element
Missing custom-element compiler configuration
Add isCustomElement or the Vue 2 ignored-element setting
React or Next.js hydration fails
Component loaded during server rendering
Load it in a Client Component effect after mount
Include the safe correlationId, environment, component version, and contract version in a support request. Never include credentials, tokens, or unnecessary traveler data.
Production Readiness
Confirm production BFF, component, and Travel Insured purchase destination URLs.