API Reference

Build a Custom Checkout

This tutorial guides you through building a complete, custom e-commerce workflow using the Care Portals Patient and Public Cart APIs. You will learn how to create a shopping cart, manage its items, authenticate a patient, and finalize the purchase to make an order.

This guide is designed for developers building a bespoke checkout experience in a single-page application (SPA), mobile app, or server-rendered frontend.

Pre-requisites

Before you begin, make sure you have the following:

  • Configured Products: Ensure you have products available and configured for ordering within your organization's catalog.
  • Authorization: Bearer <YOUR_JWT>: You need to have a valid token to access the Care Portals API. See the Authentication guide for instructions on how to generate one.
📘

Organization ID (<ORG_ID>)

  • For a CarePortals subdomain: You don’t need to send the Organization ID (<ORG_ID>) in the request header since it’s retrieved from the domain.
  • For a custom domain configuration: If you are hosting the checkout on a custom domain, you must send the Organization ID (<ORG_ID>) in the request header.

Flow Overview

Here's a high-level overview of the checkout flow we'll build:

  1. Create a Patient Account: Register a new patient.
  2. Log in the Patient: Authenticate the patient to obtain a JSON Web Token (JWT) for secure requests.
  3. Create a Cart: Initialize a new shopping cart and get a unique Cart ID.
  4. Start the Checkout: Fetch the complete checkout state, including the cart details and the patient's saved payment methods.
  5. Apply a Coupon (Optional): Apply a discount coupon to the cart.
  6. Finalize the Checkout: Submit the payment and shipping details to create the final order.

Step 1: Create a Patient Account

Before a user can check out, they need an account. Collect the user's information and send it to the Patient API to create a new patient record. Use the Create a Patient endpoint to send a POST request. A successful request creates the patient and returns the new user object.

curl -X POST '<https://patient-api.portals.care/patient/users>' \\
-H 'organization: <ORG_ID>' \\
-H 'Content-Type: application/json' \\
-d '{
  "firstName": "John",
  "lastName": "Doe",
  "phone": "+11234567890",
  "email": "[email protected]",
  "password": "ValidPassword@123",
  "dob": "2000-11-11",
  "gender": "male",
  "acceptMarketing": true,
  "provinceCode": "AB"
}'
{
  "_id": "a1b2c3d4e5f6a1b2c3d4e5f6",
  "uname": "[email protected]",
  "email": "[email protected]",
  "firstName": "John",
  "lastName": "Doe",
  "provinceCode": "AB",
  "phone": "+11234567890",
  "isInsuranceAvailable": false,
  "organization": "<ORG_ID>",
  "tags": "",
  "currency": "CAD",
  "notificationsCount": 0,
  "contactPreference": {},
  "watchlist": [],
  "usedCoupons": [],
  "meta": {},
  "verifications": {}
}

Step 2: Log In and Get JWT

Now that the patient has an account, you need to log them in to get an authentication token (JWT). This token is required for all subsequent checkout steps. To authenticate the user, you have to share their username and password using the Authenticate Patient with Password endpoint.

curl -X POST '<https://patient-api.portals.care/patient/auth/login>' \
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer <YOUR_JWT>'
-d '{
  "username": "[email protected]",
  "password": "ValidPassword@123"
}'
{
  "_id": "a1b2c3d4e5f6a1b2c3d4e5f6",
  "email": "[email protected]",
  "firstName": "John",
  "lastName": "Doe",
  "uname": "[email protected]",
  "provinceCode": "AB",
  "phone": "+11234567890",
  "iat": "1672531200",
  "exp": "1672617600",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "organization": "<ORG_ID>",
  "referrer": ""
}

Step 3: Create a Cart

After creating and logging the patient in, you need to create a shopping cart for the user. To create the cart, you need to use the Post Carts endpoint from the public API. While creating the cart, you can already add items to the cart, informing the productId and respective quantity. The response will contain the full cart object, including the _id, which we'll refer to as the <CART_ID>.

curl -X POST '<https://public-api.portals.care/public/v2/carts>' \\
-H 'Authorization: Bearer <YOUR_JWT>'
-H 'Content-Type: application/json' \\
-d '[
  {
    "productId": "67913a49df75bdf65ad795f3",
    "quantity": 1
  }
]'
{
  "_id": "685c3ed23f131cba09b33247",
  "organization": "<ORG_ID>",
  "lineItems": [
    {
      "id": "<CART_ID>",
      "name": "Finasteride 1mg",
      "productId": "67913a49df75bdf65ad795f3",
      "price": 90,
      "listPrice": 111,
      "quantity": 1,
      "isSubscription": false
    }
  ],
  "baseAmount": 111,
  "discountAmount": 21,
  "totalAmount": 90
}

The API will respond with the newly created cart object. You must save the _id from this response. You'll need it for all subsequent cart and checkout operations.

📘

Anytime you modify the cart (add, update, or remove an item), the API returns the latest cart state. Always use the most recent response as your application's source of truth to avoid state drift.

Step 4: Start the Checkout

With an authenticated user and a cart created, you can now retrieve the complete checkout context. This includes the final state of the cart and a list of the patient's available payment methods. This data is everything you need to render your checkout UI. To retrieve this information, use the Start Checkout endpoint, ensuring that you include the patient's JWT.

curl -X GET '<https://patient-api.portals.care/patient/v2/checkout/><CART_ID>/start' \\
-H 'Authorization: Bearer <YOUR_JWT>'
{
  "cart": {
    "_id": "685c3ed23f131cba09b33247",
    "organization": "<ORG_ID>",
    "lineItems": [
      {
        "id": "UQ2XGj7d",
        "name": "Finasteride 1mg",
        "productId": "67913a49df75bdf65ad795f3",
        "price": 90,
        "listPrice": 111,
        "quantity": 1,
        "isSubscription": false
      }
    ],
    "baseAmount": 111,
    "discountAmount": 21,
    "totalAmount": 90
  },
  "paymentMethods": [
    {
      "id": "pm_1LzG9q2eZvKYlo2Cc0Q4f3gN",
      "type": "card",
      "last4": "4242",
      "exp": "12/2025"
    }
  ]
}

The response contains the final cart details and an array of saved paymentMethods. If the array is empty, you'll need to prompt the user to add a new payment method.

Step 5 (Optional): Apply a Coupon

Here, if a coupon was applied, call the Apply Coupon to Cart endpoint with a POST request. Ensure you input the <CART_ID> and the <COUPON_CODE> in the request's path parameters.

curl -X POST 'https:https://patient-api.portals.care/v2/checkout/<CART_ID>/coupon/<COUPON_CODE>
-H 'Authorization: Bearer <YOUR_JWT>'

Step 6: Finalize the Checkout

This is the final step. To place an order, please select a payment method and provide your shipping address. To do this, use the Finalize Checkout endpoint with a POST request. Ensure you input the <CART_ID> of the created cart in the URL path.

📘

If a coupon was applied to this cart, you need to input the coupon in the couponcode body parameter.

curl -X POST '<https://patient-api.portals.care/patient/v2/checkout/<CART_ID>/finalize' \\
-H 'Authorization: Bearer <YOUR_JWT>' \\
-H 'Content-Type: application/json' \\
-d '{
  "paymentMethodId": "pm_1LzG9q2eZvKYlo2Cc0Q4f3gN",
  "shippingAddress": {
    "address1": "123 Test Street",
    "address2": "Suite 100",
    "city": "Calgary",
    "provinceCode": "AB",
    "postalCode": "T2X 2X2",
    "countryCode": "CA"
 
  "isNewShippingAddress": true,
  "couponCode": "AG10"
}'
{
  "organization": "<ORG_ID>",
  "_id": "f1e2d3c4b5a6f1e2d3c4b5a6",
  "id": 12345,
  "createdAt": "2025-08-28T17:51:16.000Z",
  "updatedAt": "2025-08-28T17:51:16.000Z",
  "customer": {
    "_id": "a1b2c3d4e5f6a1b2c3d4e5f6",
    "firstName": "John",
    "lastName": "Doe"
  },
  "status": "Awaiting Fulfillment",
  "source": "api",
  "lineItems": [
    {
      "name": "Finasteride 1mg",
      "productId": "67913a49df75bdf65ad795f3",
      "sku": "FINA-1",
      "price": 90,
      "listPrice": 111,
      "quantity": 1
    }
  ],
  "shippingAddress": {
    "address1": "123 Test Street",
    "city": "Calgary",
    "provinceCode": "AB",
    "postalCode": "T2X 2X2",
    "countryCode": "CA"
  },
  "totalAmount": 90,
  "discountAmount": 21,
  "baseAmount": 111
}

A successful request will return the final IOrder object with an id and a status.