Payment Processing
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
- Persist the order-to-intent association on the server.
- Return the secret only to the authenticated payer.
- Run reconciliation from a server-owned job using the saved intent ID, or use payment watchers with the implementation's verified webhook events.
- 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
GetClientwhen 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
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Custom identifier stored in metadata.payload. |
params | Stripe.PaymentIntentCreateParams | Yes | Stripe payment intent creation parameters. |
options | Stripe.RequestOptions | No | Additional Stripe request options. |
Returns
Promise<Stripe.PaymentIntent>-- The created payment intent.
Note: Any existing
metadatayou pass inparamsis preserved. Themetadata.payloadfield is set to the providedidvalue.
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
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentIntentId | string | Yes | The Stripe payment intent ID to monitor. |
Returns
Promise<Stripe.PaymentIntent>-- Resolves when the intent succeeds.- Rejects with the
cancellation_reasonstring when the intent is canceled.
Important: Calling
WaitForPaymentmultiple 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
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentIntentId | string | Yes | The Stripe payment intent ID to complete. |
source | Stripe.Source | Yes | A source object that must be in chargeable status. |
Behavior
- Validates that the source status is
chargeable. Throws an error if it is not. - Retrieves the payment intent to read its
amountandcurrency. - Creates a charge using the source, with an idempotency key set to
metadata.payload(or the payment intent ID as a fallback). - Updates the payment intent metadata with the created charge ID.
Warning: The source must be in
chargeablestatus before calling this function. Passing a source in any other state throws an error immediately.
Interface Stripe Documentation
Event Monitoring
Interface Stripe provides functions for monitoring payment intent status changes. Watchers receive callbacks whenever a payment intent transitions to a new state, enabling your application to react to successful payments, cancellations, and other status updates.