Skip to main content

Packages, pricing and checkout

Everything here works through the API — your patients never have to go to the VitaRelay portal to buy.

Patient ids

You don’t need to store VitaRelay’s patient id. Create the patient with your own external_patient_id (POST /patients) and then use that id anywhere a patient is needed: external_patient_id on POST /orders and POST /intakes, and in the path of /patients/{id}/payment-methods and /patients/{id}/partner. The VitaRelay patient id (UUID) works everywhere too. A patient who isn’t in VitaRelay yet is created first with POST /patients, which returns both ids.

Who pays decides the price

With patient_checkout, what the patient sees in your storefront is what they pay:
  • A listed product is charged at its shop price.
  • A package is charged at the package price you set. The price is spread exactly over the package’s products, so the lines always add up to it, to the cent.
  • The shop’s doctor consult fee (503A orders) and a shipping line are added the same way as in your storefront. total_cents and checkout.amount_cents are the full amount the patient pays — display that total, don’t recompute it.
  • Your markup accrues to you once the order is paid, exactly like a storefront order.
  • Pass shipping_method (ground or overnight) to carry the patient’s delivery choice.
If your storefront isn’t enabled, patient_checkout falls back to catalog prices.

The doctor consult fee

The consult fee is always charged on a 503A order, and VitaRelay always collects its base. Your clinic chooses only how it is shown: as its own line, or built into the displayed product prices (the patient pays the same total either way). Shipping is always its own line.

Buying a package (treatment plan)

A package is an item in your storefront (item_kind: "bundle", see GET /shop).

One-time

The package goes through the normal prescription, consult-fee and fulfilment pipeline, the same as product lines. A package that includes a clinic service can’t be ordered through the API (422 bundle_has_services); an unlisted or ineligible package returns 422 product_not_found.

As a subscription

A subscription needs the patient’s saved card (payment_method_id) — a one-time purchase does not; the patient just pays with the card form. If the patient has no saved card yet, there are two ways to get one, neither needs the portal: A. Save a card without charging — best when the patient is starting with a subscription:
  1. Tokenize the card on your own page with Accept.js (you get a single-use nonce).
  2. POST /patients/{id}/payment-methods with { "opaque_data": { "dataDescriptor": "…", "dataValue": "…" } }. Billing details default to the patient record; nothing is charged.
  3. Use the returned id as payment_method_id on the subscription order above.
You can list a patient’s saved cards (brand, last four, expiry only) with GET /patients/{id}/payment-methods. B. Save it while paying — have the patient pay any order with save_card: true on POST /orders/{id}/pay; the response returns saved_payment_method_id.

503B products

503B (bulk office-use) products are never available in a patient store, for any organization. Adding one to your shop returns an error. A clinic can order 503B only through Place Order, with an NPI and your office address on file.