Mediquo documentation home

mq-chat-consultation-checkout

Chat-consultation checkout. Creates a payment session for a chat consultation with a professional, then delegates the full payment UX to mq-checkout.

<mq-chat-consultation-checkout> is the chat counterpart of <mq-checkout>. You give it a professional-hash; it creates the payment session via the Mediquo API and hands the rest of the flow — embedding the portal, polling, retries — to <mq-checkout> internally.

Use this component when the patient chooses a professional to chat with and must pay before the conversation opens. No agenda slot is reserved and no price is sent: the backend prices the consultation from the professional's specialty. When the payment is confirmed, the component emits payment-success with the chat room id so you can open the conversation.

A patient who is already entitled to consult that professional without paying is never charged. In that case no payment portal is rendered: the consultation is opened and the component emits consultation-granted instead, so the host can navigate straight to the conversation.

You can also open the same flow through the hosted checkout shell at /chat-consultation — see Hosted checkout.

This flow uses Addon Payments only. Discount codes, slots, services and pre-consultation documents do not apply — if you need those, use <mq-appointment-checkout>. To drive the payment from a session created by your own backend, use <mq-checkout> directly.

Dependencies

Must be rendered inside an <mq-theme-provider> ancestor. No other providers are required.

Installation

npm install @mediquo/web-components
import "@mediquo/web-components/mq-chat-consultation-checkout";
import "@mediquo/web-components/mq-theme-provider";

Usage

HTML

<mq-theme-provider theme="mediquo">
  <mq-chat-consultation-checkout
    env="production"
    api-key="<your-api-key>"
    token="<your-token>"
    professional-hash="<professional-hash>"
    locale="es_ES"
  ></mq-chat-consultation-checkout>
</mq-theme-provider>

React / Next.js

"use client";
import { useEffect, useRef } from "react";

export function ChatConsultationCheckout({ apiKey, token, professionalHash }) {
  const ref = useRef<HTMLElement>(null);

  useEffect(() => {
    import("@mediquo/web-components/mq-chat-consultation-checkout");
    import("@mediquo/web-components/mq-theme-provider");
  }, []);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;

    const onSuccess = (e: Event) =>
      console.log("chat room", (e as CustomEvent).detail.consultationId);
    const onGranted = () => console.log("no payment needed");

    el.addEventListener("payment-success", onSuccess);
    el.addEventListener("consultation-granted", onGranted);

    return () => {
      el.removeEventListener("payment-success", onSuccess);
      el.removeEventListener("consultation-granted", onGranted);
    };
  }, []);

  return (
    <div style={{ height: "700px" }}>
      {/* @ts-expect-error — custom element */}
      <mq-theme-provider theme="mediquo">
        {/* @ts-expect-error — custom element */}
        <mq-chat-consultation-checkout
          ref={ref}
          env="production"
          api-key={apiKey}
          token={token}
          professional-hash={professionalHash}
          locale="es_ES"
        />
      </mq-theme-provider>
    </div>
  );
}

Attributes & properties

NameKindTypeRequiredDescription
envattributestringNoBackend environment: "development" or "production". Applied once at mount.
api-keyattributestringYesAPI key for the Mediquo platform.
tokenattributestringYesMediquo user token.
professional-hashattributestringYesHash of the professional the patient wants to consult.
localeattributestringYesLocale code: es_ES, en_US, pt_PT, de_DE, ca_ES.

Events

All events bubble and cross shadow boundaries (composed: true).

EventDetailDescription
payment-success{ consultationId: string }Payment confirmed. consultationId is the chat room to open.
consultation-granted{ professionalHash: string }No payment was needed — the patient could already consult this professional. The conversation has been opened; navigate to it.
payment-denied{ sessionId: string }Payment was rejected. Forwarded from <mq-checkout>.
payment-error{ reason: "auth" | "session" | "timeout" | "unavailable" | "unsupported" }Authentication failed, the session could not be created, polling timed out, the professional is not available (unavailable), or the organization cannot charge for chat consultations (unsupported). Forwarded from <mq-checkout>.
const checkout = document.querySelector("mq-chat-consultation-checkout");

checkout.addEventListener("payment-success", (e) => {
  console.log("chat consultation paid", e.detail.consultationId);
});

checkout.addEventListener("consultation-granted", (e) => {
  console.log("free consultation", e.detail.professionalHash);
});

Every failure renders its own message inside the component, so handling payment-error is only needed when the host wants to react (navigate away, report it). Backend detail is never surfaced to the patient: an unknown professional and one outside your organization are reported identically on purpose, and a missing chat price is reported as a checkout problem rather than with the backend's wording.

Environment, CSP & theming

These behave identically to <mq-checkout>: select the backend with the env attribute (set once at mount), allowlist the payment-portal origin under your CSP frame-src, and theme via <mq-theme-provider>.