Skip to main content

Kibo Commerce API Developer Guide for OMS Implementations

Understanding Order Imports in Kibo

For businesses using Kibo’s Order Management System (OMS) with a separate, external e-commerce front-end, the primary goal is not to process transactions in real-time but to import completed orders for fulfillment. In this context, an “Order” is a record of a transaction that has already occurred elsewhere. Kibo’s API is specifically designed for this. Instead of a multi-step cart-to-checkout process, you use a single, powerful API call to create a complete order record. The key is providing all necessary information—customer details, pre-calculated pricing, and pre-authorized payment details—in one request. This is achieved by using the POST /commerce/orders endpoint with the required isImport=true flag, which tells Kibo to accept the order as a historical record rather than processing it as a new transaction.

How This Domain Fits Into Kibo

The Commerce domain is the entry point for all order data into the Kibo platform. For an OMS-only implementation, this is where your external systems hand off completed sales to Kibo for subsequent management.
  • Fulfillment: Once an order is imported, it enters the Kibo fulfillment workflow, where it can be routed to the appropriate warehouse or location.
  • Customer Service: Imported orders are visible to customer service representatives, who can then manage returns, refunds, and cancellations using Kibo’s tools.
  • Inventory: Subsequent actions on an imported order, like fulfillment, will correctly decrement stock levels within Kibo.

Prerequisites

  • Kibo API credentials and basic setup
  • Node.js 16+ with TypeScript
  • Familiarity with REST APIs and constructing complex JSON objects
  • Access to pre-authorized payment transaction details from your external payment gateway.
  • API Reference: /api-overviews/openapi_overview_overview (bookmark this - you’ll reference it constantly)

What You’ll Learn

After completing this guide, you’ll understand:
  • How to structure a complete JSON payload to import an order into Kibo’s OMS.
  • The key patterns for providing pre-authorized credit card, PayPal, and other payment details.
  • How to correctly structure item-level pricing, taxes, and shipping to avoid validation errors.
  • How to include external fraud check results with an imported order.
  • How to read and navigate the official Orders API documentation for OMS-specific use cases.

Kibo OMS Import Fundamentals

How Kibo Organizes Imported Order Data

For an OMS import, you are essentially building the final Order object yourself. The core data structures you must provide are:
  • isImport: true: This boolean field is mandatory and signals to Kibo that you are importing a completed order.
  • items: An array of line items. For imported orders, you must provide the final, calculated pricing components for each item, including tax, shipping, and discounts.
  • payments: An array of payment objects. Since the payment was authorized on your external system, you must provide the gateway’s transaction details, tokenized card information, and authorization codes.
  • billingInfo: The customer’s billing address and contact information. This object must be populated on both the order level and within each payment object.
  • fulfillmentInfo: The customer’s shipping address and chosen shipping method.
  • email and customerAccountId: Identifiers for the customer.

Key Kibo Patterns You’ll See Everywhere

Authentication Pattern: The Kibo SDK manages authentication for you. You create a single Configuration object containing your credentials (Client ID, Shared Secret, etc.). This object is then passed to the constructor of the OrderApi client, which handles the OAuth 2.0 token exchange for every API call. Error Handling Approach: Kibo provides structured errors. For OMS imports, the most common error is a VALIDATION_ERROR, often with a message like “The order totals do not match the sum of the item totals.” This means you must carefully verify your pricing calculations.
// Actual error schema for a totals mismatch
{
    "message": "The order totals do not match the sum of the item totals.",
    "errorCode": "VALIDATION_ERROR",
    "correlationId": "a1b2c3d4-e5f6-4a7b-8c9d-12345fedcba"
}
API Documentation Reference: The primary endpoint for this guide is POST /commerce/orders.
Find complete specs at: Create Order

Importing an Order: The Kibo OMS Way

When You Need This

This is the core workflow for any OMS-only Kibo client. You use this process to feed orders from your website, mobile app, or other point-of-sale systems into Kibo for centralized fulfillment and management.

API Documentation Reference

Endpoint: POST /commerce/orders
Method: POST
API Docs: Create Order

Understanding the Kibo Approach

Kibo’s import functionality is built on trust. By setting isImport=true, you are telling the system: “Trust me. This transaction is complete, the payment is authorized, and the prices are final.” Kibo will bypass its internal pricing and payment processing engines and instead record the exact data you provide. This makes the accuracy of your payload important, especially the financial details. The sum of all item-level pricing components must precisely match the overall order total.

Code Structure Walkthrough

We’ll build this step by step:
  1. Configuration: Create a central Configuration instance.
  2. API Client Instantiation: Create a dedicated client for the Order API.
  3. Data Preparation: Meticulously construct the entire Order object, including items with broken-down pricing and payments with gateway authorization details.
  4. API Call: Use the createOrder method to import the order.

Step-by-Step Implementation

Step 1: Setting Up the Foundation
// Essential imports for Commerce operations.
import { Configuration } from "@kibocommerce/rest-sdk";
import { OrderApi } from "@kibocommerce/rest-sdk/clients/Commerce";
import { Order } from "@kibocommerce/rest-sdk/clients/Commerce/models";

// Configuration setup - this single object is reused for all API clients.
const configuration = new Configuration({
    tenantId: process.env.KIBO_TENANT_ID,
    siteId: process.env.KIBO_SITE_ID,
    clientId: process.env.KIBO_CLIENT_ID,
    sharedSecret: process.env.KIBO_SHARED_SECRET,
    authHost: process.env.KIBO_AUTH_HOST,
});
Step 2: The Core Implementation This example shows how to import an order with a pre-authorized Cybersource credit card payment.
// This function constructs and imports a complete order.
async function importCompletedOrder(orderData: any): Promise<Order> {
    console.log(`Importing order from external system...`);
    const orderClient = new OrderApi(configuration);

    // 1. Meticulously construct the Order payload. This is the most important step.
    const orderToImport: Order = {
        // **MANDATORY**: Tell Kibo this is an imported order.
        isImport: true,
        email: orderData.customerEmail,
        customerAccountId: orderData.customerAccountId,
        // You can set order type to Online or Offline
        type: 'Online',
        
        // 2. Build the Fulfillment Info with shipping address and method
        fulfillmentInfo: {
            fulfillmentContact: { 
                firstName: orderData.shippingFirstName || 'John',
                middleNameOrInitial: orderData.shippingMiddleName || '',
                lastNameOrSurname: orderData.shippingLastName || 'Doe',
                phoneNumbers: {
                    home: orderData.shippingPhone || '555-555-1212',
                    mobile: orderData.shippingPhone || '555-555-1212',
                    work: orderData.shippingPhone || '555-555-1212',
                },
                email: orderData.customerEmail,
                address: {
                    address1: orderData.shippingAddress1 || '123 Main St',
                    address2: orderData.shippingAddress2 || '',
                    address3: orderData.shippingAddress3 || '',
                    address4: orderData.shippingAddress4 || '',
                    cityOrTown: orderData.shippingCity || 'Anytown',
                    countryCode: orderData.shippingCountry || 'US',
                    postalOrZipCode: orderData.shippingPostal || '12345',
                    stateOrProvince: orderData.shippingState || 'CA',
                    addressType: 'Residential',
                    isValidated: true
                }
            },
            // This code must match a configured shipping method in Kibo,
            // or you can use a generic code like "KIBO_STANDARD"
            shippingMethodCode: 'fedex_FEDEX_2_DAY',
            shippingMethodName: 'FedEx 2 Day'
        },

        // 3. Build the Billing Info
        billingInfo: {
            billingContact: { 
                firstName: orderData.billingFirstName || 'John',
                middleNameOrInitial: orderData.billingMiddleName || '',
                lastNameOrSurname: orderData.billingLastName || 'Doe',
                phoneNumbers: {
                    home: orderData.billingPhone || '555-555-1212',
                    mobile: orderData.billingPhone || '555-555-1212',
                    work: orderData.billingPhone || '555-555-1212',
                },
                email: orderData.customerEmail || '[email protected]',
                address: {
                    address1: orderData.billingAddress1 || '123 Main St',
                    address2: orderData.billingAddress2 || '',
                    address3: orderData.billingAddress3 || '',
                    address4: orderData.billingAddress4 || '',
                    cityOrTown: orderData.billingCity || 'Anytown',
                    countryCode: orderData.billingCountry || 'US',
                    postalOrZipCode: orderData.billingPostal || '12345',
                    stateOrProvince: orderData.billingState || 'CA',
                    addressType: 'Residential',
                    isValidated: true
                }
             },
            paymentType: 'CreditCard',
        },
        
        // 4. Build the Payments array with pre-authorized details.
        payments: [{
            paymentType: 'CreditCard',
            billingInfo: { 
                paymentType: 'CreditCard',
                billingContact: { 
                    email: orderData.customerEmail || '[email protected]',
                    firstName: orderData.billingFirstName || 'John',
                    lastNameOrSurname: orderData.billingLastName || 'Doe',
                    middleNameOrInitial: orderData.billingMiddleName || '',
                    address: {
                        address1: orderData.billingAddress1 || '123 Main St',
                        address2: orderData.billingAddress2 || '',
                        address3: orderData.billingAddress3 || '',
                        address4: orderData.billingAddress4 || '',
                        cityOrTown: orderData.billingCity || 'Anytown',
                        countryCode: orderData.billingCountry || 'US',
                        postalOrZipCode: orderData.billingPostal || '12345',
                        stateOrProvince: orderData.billingState || 'CA',
                        addressType: 'Residential',
                        isValidated: true
                    }
                },
                isSameBillingShippingAddress: false,
                card: {
                    // This field holds the tokenized card number from the gateway
                    cardNumberPartOrMask: orderData.gatewayToken,
                    isTokenized: true,
                    paymentOrCardType: 'VISA',
                    expireMonth: 12,
                    expireYear: 2025,
                }
            },
            status: 'Authorized',
            amountRequested: 192.50,
            interactions: [{
                interactionType: 'Authorization',
                status: 'Authorized',
                gatewayTransactionId: orderData.gatewayTransactionId,
                gatewayAuthCode: orderData.gatewayAuthCode,
                // Include gateway-specific response data needed for capture/credit
                gatewayResponseData: [
                    { key: "AuthorizationRequestId", value: orderData.cybersourceRequestId },
                    { key: "AuthorizationRequestToken", value: orderData.cybersourceRequestToken }
                ],
                amount: 192.50,
            }]
        }],

        // 5. Build the Items array with explicit, pre-calculated pricing.
        items: [{
            product: {
                productCode: 'ITEM-001',
                name: 'Cool T-Shirt',
                price: {
                    // This is the pre-discount unit price
                    price: 25.00 
                }
            },
            quantity: 1,
            // All of these pricing fields MUST be provided
            discountTotal: 5.00, // Item-level discount
            itemTaxTotal: 1.65, // Item-level tax
            shippingTotal: 10.00, // Shipping cost allocated to this item
            shippingTaxTotal: 0.83, // Shipping tax allocated to this item
            handlingAmount: 1.00, // Handling fee for this item
            // The sum of these values determines the line item total.
            total: 33.48 // (25-5) + 1.65 + 10.00 + 0.83 + 1.00
        }],

        // 6. The order total must match the sum of all item fields.
        total: 33.48, // In this one-item example.
        // Other totals...
        subtotal: 20.00, // quantity * price - discountTotal
        shippingTotal: 10.00,
        taxTotal: 2.48, // itemTaxTotal + shippingTaxTotal
    };

    try {
        const newOrder = await orderClient.createOrder({ order: orderToImport });
        console.log(`Successfully imported order number: ${newOrder.orderNumber}`);
        return newOrder;
    } catch (error) {
        console.error("API Error importing order:", JSON.stringify(error, null, 2));
        throw error;
    }
}

Advanced Import Patterns

Pattern 1: Importing an Order with a PayPal Payment

Business Scenario: Your website uses PayPal Express 2. You need to import the completed order into Kibo, including the necessary PayPal transaction details so you can capture funds later. Kibo’s Architecture Consideration: Kibo has a specific structure for PayPal Express 2 payments. You must provide the payerId, the externalTransactionId (which is the PayPal EC- token), and the gatewayTransactionId from the authorization.
// This function builds a payment object specifically for an imported PayPal order.
function buildPayPalPayment(payPalData: any): any {
    return {
        paymentType: "PayPalExpress2",
        paymentWorkflow: "PayPalExpress2",
        // The EC- token goes in externalTransactionId
        externalTransactionId: payPalData.token, // e.g., "EC-74R44913L24993252"
        status: "Authorized",
        amountRequested: payPalData.amount,
        billingInfo: {
            // Payer ID is nested in the billingInfo.data object
            data: {
                paypal: {
                    payerId: payPalData.payerId // e.g., "B373JG5S4Y388"
                }
            },
            billingContact: { email: payPalData.email }
        },
        interactions: [{
            interactionType: "Authorization",
            status: "Authorized",
            // The authorization transaction ID goes here
            gatewayTransactionId: payPalData.authorizationId, // e.g., "8AF73994TM546221D"
            amount: payPalData.amount,
        }]
    };
}

Pattern 2: Importing an Order with Fraud Review

Business Scenario: Your e-commerce front-end uses a service like Kount for fraud detection. An order is flagged for manual review. You need to import this order into Kibo and ensure it is also placed in a “Pending Review” state. Kibo’s Architecture Consideration: You can pass external fraud results directly into the order payload using the validationResults object. By setting the status within this object to Review, Kibo will automatically place the imported order into a Pending status, preventing it from being fulfilled until it is manually accepted.
// This function builds a validationResults object for an order needing review.
function buildFraudReviewPayload(kountData: any): any[] {
    return [{
        validatorName: "KountValidator",
        validatorType: "Fraud",
        // Setting status to Review flags the order in Kibo
        status: "Review",
        messages: kountData.messages // Pass the raw messages from Kount
    }];
}

// In your main import function, you would add this to the order object:
// const orderToImport: Order = {
//     ...
//     validationResults: buildFraudReviewPayload(fraudDataFromFrontend),
//     ...
// };

Troubleshooting Your OMS Import

Common Import Issues

Issue 1: The createOrder call fails with a VALIDATION_ERROR and a “totals do not match” message.
  • Why it happens: This is the most common import error. The sum of all item-level pricing fields (discountTotal, itemTaxTotal, shippingTotal, shippingTaxTotal, handlingAmount, etc.) across all items does not exactly equal the top-level order.total. This often happens due to floating-point math rounding errors or misinterpreting which fields are additive.
  • How to fix it: Before sending the request, programmatically sum all the calculated pricing fields from your items array and ensure the result is used to set order.total, order.subtotal, order.taxTotal, etc. Do not assume they will be calculated for you.
Issue 2: The order is imported, but subsequent payment capture fails.
  • Why it happens: The authorization details provided in the payment.interactions object were incorrect or insufficient. For gateways like Cybersource or Authorize.net, specific keys and tokens from the original authorization are required to link a future capture or credit action.
  • How to fix it: Double-check the required gatewayResponseData for your specific payment gateway. Ensure you are storing and passing the correct transaction IDs, request tokens, and auth codes from your e-commerce front-end’s payment authorization step. Make sure you are correctly mapping gateway fields, such as CustomerProfileId to cardNumberPartOrMask for Authorize.net.