Complete an approved AR or token purchase in one mutation
planNumber, transactionId, document links
2B
stagePolicyPurchase
Create the pending policy used by deferred payment
planGuid
3B
Embedded payment app
Securely capture card data, process payment, and automatically bind the staged policy
paymentSessionId; reconciled planNumber and policy result
planGuid is temporary workflow state. planNumber is the issued policy identifier used for later search and servicing.
Flow
MERMAID
sequenceDiagram
autonumber
actor Traveler
participant App as Partner app
participant Backend as Partner backend
participant API as Travel Insured GraphQL API
participant Payment as Approved payment flow
Traveler->>App: Enter trip and traveler details
App->>Backend: Request eligible products
Backend->>API: quote
API-->>Backend: quoteNumber and products
Backend-->>App: Display products, coverages, and prices
Traveler->>App: Select product and purchase
alt Streamlined AR or provider-token purchase
Backend->>API: purchasePolicy
API-->>Backend: success, planNumber, transactionId, documents
else Deferred hosted-payment purchase
Backend->>API: stagePolicyPurchase
API-->>Backend: planGuid
Backend->>Payment: Create payment session for planGuid
Payment-->>Backend: paymentSessionId, embedToken, expiresAt
Backend-->>App: Short-lived widget configuration
App->>Payment: Mount widget and submit card in hosted PCI form
Payment->>Payment: Process payment and bind policy
Payment-->>App: Payment or policy UX event
Backend->>Backend: Reconcile authoritative policy status
end
Backend-->>App: Return issued policy confirmation
App-->>Traveler: Display policy number and document links
Step 1: Request a Quote
quote is a mutation because it creates resumable quote context. It returns a quoteNumber and the products currently available for the submitted agency, residency, dates, destinations, travelers, and trip costs.
{"policyPurchaseInput":{"agencyNumber":"<assigned-agency-number>","quoteNumber":"<quote-number>","deliveryMethods":[{"deliveryType":"Email"}],"product":{"effectiveDate":"2027-06-10","productCode":"<selected-product-code>","optionalCoverages":[]},"trip":{"departureDate":"2027-06-10","returnDate":"2027-06-22","depositDate":"2027-02-15","destinations":[{"countryIsoCode":"FR"}],"primaryTraveler":{"firstName":"<traveler-first-name>","lastName":"<traveler-last-name>","dateOfBirth":"1985-06-15","tripCost":2500.00,"email":"traveler@example.com","phoneNumbers":["+1-555-010-0200"],"address":{"addressLine1":"123 Example Street","city":"Hartford","stateIsoCode":"CT","zipCode":"06103","countryIsoCode":"US"}},"additionalTravelers":[]},"payment":{"amount":184.50,"paymentMethod":"AR","idempotencyKey":"<unique-key-for-this-intended-purchase>"}}}
The payment amount must match the current authoritative quoted total. 184.50 is illustrative only; replace it with the total for the selected product and coverages from the current quote state.
The purchase input includes:
Input
Source
quoteNumber
Quote response
agencyNumber and optional agentId
Partner configuration
product.productCode
Traveler's selected quote product
product.optionalCoverages[]
Selected type and limit IDs from the quote
trip
Confirmed dates, destinations, costs, and purchaser details
deliveryMethods[]
Requested document delivery methods
payment.amount
Current quoted total
payment branch
AR or approved provider-token details
Optional Coverage Selection
Use an empty array when the customer selects no optional coverage:
JSON
"optionalCoverages":[]
When the customer selects an optional coverage, carry both identifiers from the selected quote response limit:
productCoverageTypeCode identifies the coverage and productCoverageLimitId identifies its selected limit. The SDL permits multiple entries and optional startDate and endDate values. Include dates only when the selected coverage contract requires them. Re-run quote after a coverage selection changes, then carry the refreshed selection and authoritative total into either purchase path.
{"policyPurchaseStage":{"agencyNumber":"<assigned-agency-number>","quoteNumber":"<quote-number>","deliveryTypes":[{"deliveryType":"Email"}],"product":{"effectiveDate":"2027-06-10","productCode":"<selected-product-code>","optionalCoverages":[]},"trip":{"departureDate":"2027-06-10","returnDate":"2027-06-22","depositDate":"2027-02-15","destinations":[{"countryIsoCode":"FR"}],"primaryTraveler":{"firstName":"<traveler-first-name>","lastName":"<traveler-last-name>","dateOfBirth":"1985-06-15","tripCost":2500.00,"email":"traveler@example.com","phoneNumbers":["+1-555-010-0200"],"address":{"addressLine1":"123 Example Street","city":"Hartford","stateIsoCode":"CT","zipCode":"06103","countryIsoCode":"US"}},"additionalTravelers":[]}}}
Repeat the confirmed purchase data. Use quoteNumber, productCode, and optional coverage identifiers from the same quote response. The primary traveler must include the contact and address fields required by PrimaryTravelerInput.
The response contains only planGuid. It does not return the quote number, amount due, transaction ID, or bind status. Keep those values in server-side checkout state.
Step 3: Complete Payment
From your backend, create an embedded payment session with the staged planGuid, current approved amount, billing contact, and billing address. The session response supplies a short-lived paymentSessionId, embedToken, and expiry for the widget. Do not call processPayment; session creation replaces that partner-orchestrated mutation.
Mount the approved tii-payment-widget in the browser. Card number, expiration, and security code must be entered only in the Travel Insured-hosted PCI form loaded by the widget. Keep partner API credentials on the backend and never include them in widget configuration.
After successful card capture, the embedded payment app processes payment and automatically binds the policy on the backend. Widget events such as tii.payment.verified or tii.policy.bound can update the checkout UI but are not authoritative proof of issuance. Poll the session status from the partner backend and require both status and bindStatus to be Bound before confirming success or releasing documents.
Do not call processPayment or policyBindRequest. The embedded payment app owns both operations behind the scenes so the partner does not orchestrate another API call. See the Payment Integration Guide for the session request, widget values, event handling, and security boundary.
Confirmation and Persistence
After successful issuance:
Persist planNumber as the policy identifier.
Associate it with the authenticated customer using server-side authorization checks.
Present document links only to an authorized user and account for their time-limited nature.
Retain reconciliation identifiers according to your approved retention policy.
Remove temporary plan GUID, token, and hosted-payment state when no longer required.
Failure and Retry Rules
Failure point
Recommended action
Quote validation fails
Correct the invalid input and request a new quote
Quote inputs change
Re-run quote; replace the earlier quote and selection
Streamlined result is uncertain
Check existing state, then retry with the same idempotency key
Staging fails
Correct the request; do not start payment without planGuid
Payment or binding is pending or unknown
Poll the payment-session status with bounded backoff; do not call payment or bind mutations
Final policy result is uncertain
Reconcile the existing session before retrying session creation
Never log raw payment tokens, card data, API credentials, or full traveler records. Treat quote numbers, plan GUIDs, plan numbers, and browser payment events as untrusted until authorized and verified on the backend.