npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@healthcloudai/hc-stripe-connector

v0.2.0

Published

Healthcheck Stripe Payment SDK with TypeScript

Readme

Stripe Connector

This connector handles authenticated Stripe PaymentIntent payment flows for the active patient session.

HCStripeClient uses the active authenticated session from HCLoginClient, so payment requests do not require a separate authentication setup.

The backend creates the Stripe PaymentIntent and the UI completes the payment using Stripe SDK, PaymentSheet, or Payment Element.


Node.js Package

@healthcloudai/hc-stripe-connector

Client

HCStripeClient

Authentication

Reuses the authenticated patient session from HCLoginClient.


Features

  1. Create a backend-owned Stripe PaymentIntent for the authenticated patient
  2. Return the tenant-level Stripe publishable key to the UI
  3. Return the PaymentIntent client secret to the UI
  4. Complete or verify the PaymentIntent status after UI confirmation
  5. Reuse the authenticated login client for headers and base URL
  6. Optionally attach API key headers to Stripe connector requests

Setup

Configure and authenticate HCLoginClient before passing it into HCStripeClient.

Reuse the same authenticated HCLoginClient instance so both connectors share the same authentication state.

const httpClient = new FetchClient();

const authClient = new HCLoginClient(
  httpClient
);

authClient.configure(
  "healthcheck",
  "dev"
);

await authClient.login(
  "<PATIENT_EMAIL>",
  "ExamplePassword123!"
);

const stripeClient =
  new HCStripeClient(
    httpClient,
    authClient
  );

API Key

Use setApiKey(...) to attach an API key header to Stripe connector requests.

const apiKey =
  process.env.HEALTHCLOUD_API_KEY;

if (!apiKey) {
  throw new Error(
    "HEALTHCLOUD_API_KEY is required."
  );
}

stripeClient.setApiKey(
  "x-api-key",
  apiKey
);

Parameters

| Parameter | Type | Description | | ------------ | -------- | ------------------- | | headerName | string | API key header name | | value | string | API key value |

Notes

  • Header name should typically be x-api-key.
  • API key headers are attached only to Stripe connector requests.

Resources

Create PaymentIntent

Method Signature

stripeClient.createPaymentIntent(
  request: PaymentIntentCreateRequest
): Promise<
  PaymentIntentCreateResponse
>

Behavior

Sends an authenticated POST request and creates an internal HealthCheck payment session plus a Stripe PaymentIntent.

The PaymentIntent is created without confirming it. The UI should confirm payment through Stripe SDK using the returned StripePublishableKey and PaymentIntentClientSecret.

Raw card details are never sent through this connector.

Parameters

| Parameter | Type | Description | | --------- | ---------------------------- | ---------------------------------------- | | request | PaymentIntentCreateRequest | Payment session and product information |

Request Fields

| Field | Type | Description | | ------------- | -------- | ------------------------------------------------ | | referenceId | string | Caller-defined payment reference | | productId | string | Product or catalog item identifier | | amount | number | Amount in the smallest currency unit | | currency | string | Currency code, such as usd |

Returns

Returns the raw backend response:

PaymentIntentCreateResponse

Usage

const response =
  await stripeClient.createPaymentIntent({
    referenceId: "order-test-001",
    productId: "copay_40",
    amount: 4000,
    currency: "usd"
  });

console.log(response.StripePublishableKey);
console.log(response.PaymentIntentClientSecret);

API Request

{
  "referenceId": "order-test-001",
  "productId": "copay_40",
  "amount": 4000,
  "currency": "usd"
}

API Response

{
  "SessionId": "SESSION_ID",
  "ReferenceId": "order-test-001",
  "ExpiresAt": "2026-06-09T22:35:01Z",
  "StripePublishableKey": "pk_test_...",
  "StripePaymentIntentId": "pi_...",
  "PaymentIntentClientSecret": "pi_..._secret_...",
  "StripeCustomerId": "cus_...",
  "Amount": 4000,
  "Currency": "usd"
}

Notes

  • The connector preserves the raw backend response contract.
  • StripePublishableKey is safe for the UI to use.
  • PaymentIntentClientSecret is used by Stripe SDK to confirm the PaymentIntent.
  • The backend secret key is never exposed to the UI.

Complete PaymentIntent

Method Signature

stripeClient.completePaymentIntent(
  request: PaymentIntentCompleteRequest
): Promise<
  PaymentIntentStatusResponse
>

Behavior

Sends an authenticated POST request and verifies the current Stripe PaymentIntent status for the authenticated patient session.

If Stripe reports succeeded, the backend saves the payment record and marks the HealthCheck payment session as consumed.

Parameters

| Parameter | Type | Description | | --------- | ------------------------------ | --------------------------------------------- | | request | PaymentIntentCompleteRequest | Payment session and Stripe PaymentIntent IDs |

Request Fields

| Field | Type | Description | | ----------------------- | -------- | ----------------------------------------------- | | sessionId | string | Session ID returned by createPaymentIntent | | stripePaymentIntentId | string | Stripe PaymentIntent ID returned by create flow |

Returns

Returns the raw backend response:

PaymentIntentStatusResponse

Usage

const response =
  await stripeClient.completePaymentIntent({
    sessionId: createResponse.SessionId,
    stripePaymentIntentId:
      createResponse.StripePaymentIntentId
  });

console.log(response.Status);

API Request

{
  "sessionId": "SESSION_ID_FROM_CREATE_RESPONSE",
  "stripePaymentIntentId": "PI_ID_FROM_CREATE_RESPONSE"
}

API Response

Before the UI confirms the payment, the expected status is usually requires_payment_method.

{
  "SessionId": "SESSION_ID",
  "PaymentId": null,
  "StripePaymentIntentId": "pi_...",
  "Status": "requires_payment_method",
  "Last4": null,
  "Brand": null,
  "ReceiptUrl": null
}

After the UI confirms the payment through Stripe SDK, completePaymentIntent(...) should return succeeded.

{
  "SessionId": "SESSION_ID",
  "PaymentId": "PAYMENT_ID",
  "StripePaymentIntentId": "pi_...",
  "Status": "succeeded",
  "Last4": "4242",
  "Brand": "visa",
  "ReceiptUrl": "https://pay.stripe.com/receipts/example"
}

Notes

  • sessionId should be set from SessionId in the createPaymentIntent response.
  • stripePaymentIntentId should be set from StripePaymentIntentId in the createPaymentIntent response.
  • The connector preserves the raw backend response contract.

Frontend Stripe Flow

The payment flow has three separate steps:

  1. Create a backend-owned PaymentIntent with stripeClient.createPaymentIntent(...).
  2. Confirm the payment in the frontend with Stripe SDK.
  3. Call stripeClient.completePaymentIntent(...) to let the backend verify and save the final payment state.

Do not call completePaymentIntent(...) immediately after createPaymentIntent(...).

At that point Stripe usually still returns requires_payment_method, because the patient has not entered and confirmed a payment method yet.

Create the PaymentIntent

const createResponse =
  await stripeClient.createPaymentIntent({
    referenceId: "order-test-001",
    productId: "copay_40",
    amount: 4000,
    currency: "usd"
  });

const publishableKey =
  createResponse.StripePublishableKey;

const clientSecret =
  createResponse.PaymentIntentClientSecret;

const sessionId =
  createResponse.SessionId;

const stripePaymentIntentId =
  createResponse.StripePaymentIntentId;

Use StripePublishableKey and PaymentIntentClientSecret only in the frontend Stripe integration.

Use SessionId and StripePaymentIntentId later when calling completePaymentIntent(...).

Confirm with Stripe in React

Install Stripe's frontend packages in the app that renders the payment form:

npm install @stripe/stripe-js @stripe/react-stripe-js

Initialize Stripe from the backend-provided publishable key:

import {
  Elements,
  PaymentElement,
  useElements,
  useStripe
} from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";

const stripePromise =
  loadStripe(createResponse.StripePublishableKey);

function PaymentForm() {
  const stripe = useStripe();
  const elements = useElements();

  async function confirmPayment() {
    if (!stripe || !elements) {
      return;
    }

    const submitResult =
      await elements.submit();

    if (submitResult.error) {
      console.error(submitResult.error);
      return;
    }

    const result =
      await stripe.confirmPayment({
        elements,
        clientSecret: createResponse.PaymentIntentClientSecret,
        confirmParams: {
          return_url: window.location.href
        },
        redirect: "if_required"
      });

    if (result.error) {
      console.error(result.error);
      return;
    }

    console.log(result.paymentIntent?.status);
  }

  return (
    <>
      <PaymentElement />
      <button onClick={confirmPayment}>
        Pay
      </button>
    </>
  );
}

function Checkout() {
  return (
    <Elements
      stripe={stripePromise}
      options={{
        clientSecret:
          createResponse.PaymentIntentClientSecret
      }}
    >
      <PaymentForm />
    </Elements>
  );
}

elements.submit() is required before stripe.confirmPayment(...) when using the Payment Element.

Call it as soon as the patient presses the pay button, before any additional asynchronous work.

Complete the PaymentIntent

After Stripe confirms the payment, call the backend completion method:

const completeResponse =
  await stripeClient.completePaymentIntent({
    sessionId: createResponse.SessionId,
    stripePaymentIntentId:
      createResponse.StripePaymentIntentId
  });

console.log(completeResponse.Status);

If the Stripe confirmation succeeded, the backend response should return succeeded and may include PaymentId, Last4, Brand, and ReceiptUrl.

If the response still returns requires_payment_method, the frontend Stripe confirmation did not complete successfully yet.

Test Cards

Use Stripe test cards only with test publishable keys.

4242 4242 4242 4242
Any future expiry date
Any three-digit CVC
Any postal code

For example:

Card: 4242 4242 4242 4242
Expiry: 12/34
CVC: 123
Postal code: 10001

Common Statuses

| Status | Meaning | | ------ | ------- | | requires_payment_method | The PaymentIntent exists, but the patient has not successfully confirmed a payment method yet. | | requires_action | Stripe requires an additional step, such as 3D Secure authentication. | | processing | Stripe accepted the payment and is processing it. | | succeeded | The payment succeeded. Now call or retry completePaymentIntent(...) so the backend can save the final payment state. | | canceled | The PaymentIntent can no longer be completed. Create a new PaymentIntent. |

Implementation Checklist

  • Configure and authenticate HCLoginClient.
  • Construct HCStripeClient with the same httpClient and loginClient.
  • Call createPaymentIntent(...).
  • Render Stripe Payment Element with StripePublishableKey and PaymentIntentClientSecret.
  • On pay button click, call elements.submit().
  • Call stripe.confirmPayment(...).
  • When Stripe returns succeeded or a final successful state, call completePaymentIntent(...).
  • Never collect or send raw card details through this connector.
  • Never expose backend Stripe secret keys in the app.

Notes

  • HCLoginClient must be configured and authenticated before calling Stripe methods.

  • Reuse the same authenticated HCLoginClient instance when constructing HCStripeClient.

  • Public SDK methods do not require consumers to manually provide:

    • authorization headers
    • tenant identifiers
    • resolved service URLs
    • backend Stripe secret keys
  • The connector returns raw backend responses without response transformation or unwrapping.

  • Backend-defined failure responses remain part of the returned API contract.


Prerequisites

HCLoginClient must be configured and the patient must be logged in before calling any method on this connector.

import { HCLoginClient } from "@healthcloudai/hc-login-connector";
import { FetchClient } from "@healthcloudai/hc-http";

const httpClient = new FetchClient();
const loginClient = new HCLoginClient(httpClient);

loginClient.configure("healthcheck", "dev");
await loginClient.login("[email protected]", "ExamplePassword123!");

See the hc-login-connector documentation for the full authentication flow.


Error Handling

All methods throw errors that extend APIError from @healthcloudai/hc-http.

Backend business failures are thrown as HCServiceError when the shared HTTP layer receives a backend error response.

import { HCServiceError, APIError } from "@healthcloudai/hc-http";

try {
  const result =
    await stripeClient.createPaymentIntent({
      referenceId: "order-test-001",
      productId: "copay_40",
      amount: 4000,
      currency: "usd"
    });

  console.log(result);
} catch (err) {
  if (err instanceof HCServiceError) {
    console.error("Backend error:", err.backendMessage);
  } else if (err instanceof APIError) {
    console.error("SDK error:", err.message, err.code);
  }
}