[data-reveal]{opacity:1!important;transform:none!important}
Payment Processing
Stripe

Payment Processing

Interface Stripe provides functions for creating payment intents, waiting for their completion, and finalizing payments with chargeable sources.

Pick the confirmation path

For browser card checkout, start with the complete payment flow: create an intent, return its client secret, and let Stripe.js confirm it. Reconcile the result separately on the server.

CompletePayment is a different, Source-based operation. It creates a charge and updates intent metadata; it does not call paymentIntents.confirm. Do not insert it into the browser confirmation path just because of its name.

Complete Payment Flow

Return the client secret from the checkout request first. The browser needs it to confirm the payment with Stripe.js; waiting for completion inside that request would prevent confirmation. Calculate the amount from the saved order on the server, not from a browser-supplied total.

import {
  InitializePayment,
  WaitForPayment,
} from "@antelopejs/interface-stripe";

export async function startCheckout(orderId: string, amountInCents: number) {
  const intent = await InitializePayment(orderId, {
    amount: amountInCents,
    currency: "usd",
    payment_method_types: ["card"],
  });

  return {
    clientSecret: intent.client_secret,
    paymentIntentId: intent.id,
  };
}

// Run separately from the request that returns the client secret.
export async function reconcilePayment(paymentIntentId: string) {
  const completed = await WaitForPayment(paymentIntentId);
  return { orderId: completed.metadata.payload, paymentIntentId: completed.id };
}

Keep checkout and fulfilment separate

  1. Persist the order-to-intent association on the server.
  2. Return the secret only to the authenticated payer.
  3. Run reconciliation from a server-owned job using the saved intent ID, or use payment watchers with the implementation's verified webhook events.
  4. Check the order's expected amount and currency, then apply an idempotent fulfilment update.

WaitForPayment resolves only for succeeded and rejects on canceled. It has no built-in timeout and does not reject a payment that still needs payer action. Configure webhook delivery, handle cancellation or provider errors in the job, and use your own job retry/recovery policy. The browser's return alone is not proof that the payment succeeded.

The functions above show the interface calls, not a complete HTTP route or durable job. Before retrying checkout creation, reuse the saved intent or supply a stable Stripe idempotencyKey through InitializePayment's third argument for the same creation attempt. The order ID in metadata.payload is not an idempotency key.

GetClient

Returns the initialized Stripe client instance. The returned promise resolves once the Stripe client has been configured by the implementing module.

import { GetClient } from "@antelopejs/interface-stripe";

async function listCharges() {
  const client = await GetClient();
  const charges = await client.charges.list({ limit: 10 });
  return charges;
}

Returns

  • Promise<Stripe> -- Resolves to the configured Stripe SDK client.

Tip: Use GetClient when you need direct access to the Stripe SDK for operations not covered by the higher-level interface functions.

InitializePayment

Creates a new Stripe payment intent and stores a custom identifier in its metadata.payload field. This identifier ties the payment intent to an application-level entity such as an order or invoice.

import { InitializePayment } from "@antelopejs/interface-stripe";

async function createOrderPayment(orderId: string) {
  const paymentIntent = await InitializePayment(orderId, {
    amount: 2500, // $25.00 in cents
    currency: "usd",
    payment_method_types: ["card"],
  });

  return {
    clientSecret: paymentIntent.client_secret,
    paymentIntentId: paymentIntent.id,
  };
}

Parameters

ParameterTypeRequiredDescription
idstringYesCustom identifier stored in metadata.payload.
paramsStripe.PaymentIntentCreateParamsYesStripe payment intent creation parameters.
optionsStripe.RequestOptionsNoAdditional Stripe request options.

Returns

  • Promise<Stripe.PaymentIntent> -- The created payment intent.

Note: Any existing metadata you pass in params is preserved. The metadata.payload field is set to the provided id value.

WaitForPayment

Waits for a payment intent to reach a terminal state. The returned promise resolves with the payment intent when its status becomes succeeded, or rejects with the cancellation reason when its status becomes canceled.

If the payment intent has already reached a terminal state at the time of the call, the function returns or throws immediately without registering a watcher.

import { WaitForPayment } from "@antelopejs/interface-stripe";

async function awaitPayment(paymentIntentId: string) {
  try {
    const completedIntent = await WaitForPayment(paymentIntentId);
    console.log("Payment succeeded:", completedIntent.id);
    return completedIntent;
  } catch (reason) {
    console.error("Payment canceled or status retrieval failed:", reason);
    throw reason;
  }
}

Parameters

ParameterTypeRequiredDescription
paymentIntentIdstringYesThe Stripe payment intent ID to monitor.

Returns

  • Promise<Stripe.PaymentIntent> -- Resolves when the intent succeeds.
  • Rejects with the cancellation_reason string when the intent is canceled.

Important: Calling WaitForPayment multiple times with the same payment intent ID reuses the same underlying promise. This prevents duplicate watchers and ensures consistent behavior.

CompletePayment

Completes a payment by creating a charge from a chargeable Stripe source. The function retrieves the payment intent to determine the amount and currency, creates the charge with an idempotency key derived from the payload metadata, and stores the resulting charge ID in the payment intent's metadata.

import { CompletePayment } from "@antelopejs/interface-stripe";
import type Stripe from "stripe";

async function finalizePayment(paymentIntentId: string, source: Stripe.Source) {
  try {
    await CompletePayment(paymentIntentId, source);
    console.log("Payment completed successfully");
  } catch (error) {
    console.error("Failed to complete payment:", error);
  }
}

Parameters

ParameterTypeRequiredDescription
paymentIntentIdstringYesThe Stripe payment intent ID to complete.
sourceStripe.SourceYesA source object that must be in chargeable status.

Behavior

  1. Validates that the source status is chargeable. Throws an error if it is not.
  2. Retrieves the payment intent to read its amount and currency.
  3. Creates a charge using the source, with an idempotency key set to metadata.payload (or the payment intent ID as a fallback).
  4. Updates the payment intent metadata with the created charge ID.

Warning: The source must be in chargeable status before calling this function. Passing a source in any other state throws an error immediately.