Skip to main content
Orders and payment collection work together to handle purchases in the Connect API. Orders track what a customer is buying, while payments — collected through your own provider or via managed payment sessions — fulfill the payment requirement before the order can be submitted.

Core Concept

Every order has requirements that must be met before submission:
  • requiresPayment: Whether the order needs payment before it can be fulfilled
  • requiresPaymentProfile: Whether a stored payment method is needed for future billing
  • requiresSigning: Whether the order requires a digital signature
Each requirement can be NOT_REQUIRED, OPTIONAL, or REQUIRED. Check these after calculating the price to determine the correct submission flow.
Zero-total orders may not require payment at all. Always check the order requirements rather than assuming payment is needed.

Quick Path

Create Order

Create an order and add line items for the products the customer wants to buy.

Calculate Price

Calculate taxes and totals to determine the amount due.

Check Requirements

Inspect the order requirements to determine if payment, a payment profile, or signing is needed.

Collect Payment

Collect payment through your own provider or use a managed payment session.

Submit Order

Submit the order with the payment reference to begin fulfillment.

Choosing a Payment Approach

The Connect API gives you full flexibility in how you collect payments. You can use your own payment infrastructure or leverage managed payment sessions depending on your needs.

Your Own Provider (Recommended)

Collect payment through your existing payment stack (Stripe, Adyen, Braintree, etc.) and pass the reference when submitting the order. Full control over the checkout experience, payment methods, and provider relationship.

Hosted Payment Page

Use a managed payment session with hosted: true to get a provider-hosted checkout URL. Redirect customers to a pre-built payment page with no frontend payment UI to build.

Embedded Payment Widget

Use a managed payment session with hosted: false to get provider credentials for rendering a payment form directly in your UI using the provider’s SDK.

When to Use Each Approach

ApproachBest for
Your own providerTeams with an existing payment infrastructure who want full control over the payment experience, provider selection, and checkout flow
Hosted payment pageQuick integrations where you want a turnkey payment UI without building frontend payment components
Embedded widgetTeams who want a managed payment backend but need to customize the payment UI within their application
Most integrations use the external payment approach because it lets you keep your existing payment provider, maintain a single payment relationship, and have complete control over the customer checkout experience.

1. Create an Order and Add Line Items

Create an order for a customer and include the products they want to purchase.
const response = await fetch("https://connect.telnesstech.com/api/v2/orders", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.CONNECT_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    customer: {
      customerId: "123e4567-e89b-12d3-a456-426614174000",
    },
    lineItems: [
      {
        type: "SUBSCRIPTION",
        lineItemId: "sub-1",
        productOfferingId: "offering-id",
        subscriber: {
          name: "Jane Doe",
          email: "jane@example.com",
        },
      },
    ],
  }),
});

const order = await response.json();
const orderId = order.orderId;
You can also add line items to an existing order separately:
await fetch(
  `https://connect.telnesstech.com/api/v2/orders/${orderId}/line-items`,
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      type: "ADDON",
      lineItemId: "addon-1",
      productOfferingId: "addon-offering-id",
      parentLineItemId: "sub-1",
    }),
  },
);
See Create Order and Add Line Items

2. Calculate the Price

Calculate taxes and totals before collecting payment.
const priceResponse = await fetch(
  `https://connect.telnesstech.com/api/v2/orders/${orderId}/calculate-price`,
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
      "Content-Type": "application/json",
    },
  },
);

const pricedOrder = await priceResponse.json();
console.log("Total:", pricedOrder.pricing.total);
console.log("Currency:", pricedOrder.pricing.currency);
See Calculate Order Price

3. Check Order Requirements

After calculating the price, inspect the order to determine what is needed before submission.
const orderResponse = await fetch(
  `https://connect.telnesstech.com/api/v2/orders/${orderId}`,
  {
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
    },
  },
);

const orderDetails = await orderResponse.json();

const { requiresPayment, requiresPaymentProfile, requiresSigning } =
  orderDetails.requirements;

if (requiresPayment === "REQUIRED") {
  // Collect payment through your provider or via a payment session
}

if (requiresPaymentProfile === "REQUIRED") {
  // Set up a payment profile session for recurring billing
}

if (requiresSigning === "REQUIRED") {
  // Create a signing session for digital signature
}
See Get Order

4. Collect Payment

Once you know the order requires payment, choose one of the following approaches. Collect payment through your existing payment provider (Stripe, Adyen, Braintree, or any other provider). This approach gives you full control over the checkout experience and lets you use your existing payment infrastructure without any additional dependencies. After collecting payment on your side, submit the order with an externalPayment reference:
// Step 1: Collect payment through your own provider
// (This happens in your existing payment flow)

// Step 2: Submit the order with the payment reference
const submitResponse = await fetch(
  `https://connect.telnesstech.com/api/v2/orders/${orderId}/submit`,
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      externalPayment: {
        reference: "pi_3ABC123def456",
        receiptDescription: "Subscription activation payment",
        receiptUrl: "https://yourapp.com/receipts/abc123",
      },
    }),
  },
);

const submittedOrder = await submitResponse.json();
console.log("Order state:", submittedOrder.state);
The externalPayment object accepts:
FieldRequiredDescription
referenceYesThe payment reference or transaction ID from your provider
receiptDescriptionNoA human-readable description of the payment
receiptUrlNoA URL to the payment receipt or confirmation page
When using external payments, you are responsible for collecting the correct amount and handling refunds through your payment provider.
See Submit Order

Option B: Hosted Payment Page

If you prefer a managed payment flow, create a payment session with hosted: true to get a checkout URL. Redirect the customer to the provider-hosted payment page.
const sessionResponse = await fetch(
  "https://connect.telnesstech.com/api/v2/payment-sessions",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      orderId: orderId,
      paymentProvider: "STRIPE",
      hosted: true,
      returnUrl: "https://yourapp.com/payment/success",
      cancelUrl: "https://yourapp.com/payment/cancel",
    }),
  },
);

const session = await sessionResponse.json();

// Redirect the customer to the hosted payment page
window.location.href = session.provider.checkoutUrl;
After the customer completes payment, they are redirected to your returnUrl. Poll the payment session to confirm the status before submitting the order.
const statusResponse = await fetch(
  `https://connect.telnesstech.com/api/v2/payment-sessions/${session.paymentSessionId}`,
  {
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
    },
  },
);

const sessionStatus = await statusResponse.json();

if (sessionStatus.status === "COMPLETED") {
  // Submit the order with the payment session reference
  await fetch(
    `https://connect.telnesstech.com/api/v2/orders/${orderId}/submit`,
    {
      method: "POST",
      headers: {
        "X-API-Key": process.env.CONNECT_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        paymentSessionId: session.paymentSessionId,
      }),
    },
  );
}
See Create Payment Session and Get Payment Session

Option C: Embedded Payment Widget

Create a payment session with hosted: false (or omit the field) to get provider credentials for rendering a payment form directly in your UI.
const sessionResponse = await fetch(
  "https://connect.telnesstech.com/api/v2/payment-sessions",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      orderId: orderId,
      paymentProvider: "STRIPE",
    }),
  },
);

const session = await sessionResponse.json();

// Use the provider credentials to render a payment widget
const { clientSecret, publishableKey } = session.provider;
Use the returned credentials with the provider’s client SDK. For example, with Stripe Elements:
const stripe = Stripe(publishableKey);
const elements = stripe.elements({ clientSecret });

const paymentElement = elements.create("payment");
paymentElement.mount("#payment-element");

// When the customer submits the form:
const { error } = await stripe.confirmPayment({
  elements,
  confirmParams: {
    return_url: "https://yourapp.com/payment/success",
  },
});
After the payment completes, submit the order with the payment session ID:
await fetch(
  `https://connect.telnesstech.com/api/v2/orders/${orderId}/submit`,
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      paymentSessionId: session.paymentSessionId,
    }),
  },
);
See Create Payment Session

Zero-Total Orders with Payment Profile

For orders with a zero total that still require a stored payment method (e.g., trial subscriptions), submit with a payment profile session ID instead.
const submitResponse = await fetch(
  `https://connect.telnesstech.com/api/v2/orders/${orderId}/submit`,
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.CONNECT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      paymentProfileSessionId: "profile-session-id",
    }),
  },
);

Order States

StateDescription
PENDINGOrder is in cart state, can be modified
PENDING_PAYMENTOrder is locked and awaiting payment completion
SUBMITTEDOrder has been submitted for processing
PENDING_APPROVALOrder is pending approval
PROCESSINGOrder is being fulfilled
COMPLETEDOrder has been successfully fulfilled
CANCELLEDOrder was cancelled before completion
EXPIREDOrder expired due to inactivity
FAILEDOrder fulfillment failed

Payment Session Statuses

StatusDescription
PENDINGSession created, awaiting customer payment
REQUIRES_ACTIONAdditional action needed from the customer (e.g., 3D Secure)
COMPLETEDPayment successfully collected
FAILEDPayment failed

Requirements Reference

When you retrieve an order after calculating the price, the requirements object tells you what is needed before submission.
RequirementValuesDescription
requiresPaymentNOT_REQUIRED, OPTIONAL, REQUIREDWhether payment must be collected
requiresPaymentProfileNOT_REQUIRED, OPTIONAL, REQUIREDWhether a stored payment method is needed
requiresSigningNOT_REQUIRED, OPTIONAL, REQUIREDWhether a digital signature is needed

Next Steps