Choose the Documentation MX Merchant MX Connect

Integration Steps

Securely integrate and configure a seamless payment experience.

Integrating the Checkout Widget is a streamlined process designed to get you from sandbox to your first successful transaction in minutes. By following this sequential workflow, you can securely initialize the SDK, mount the payment interface, and handle real-time event callbacks with minimal backend overhead .

The integration consists of two synchronized parts:

  1. Server-Side: Generates a secure, short-lived "Client Secret" for each transaction.
  2. Client-Side: Uses the secret token to mount the widget and handle user interactions.

This integration utilizes a secure, synchronized workflow to authorize, render, and finalize a protected payment session.

  • Initiation: Your frontend requests a checkout session from your backend.
  • Authentication: Your backend authenticates with Priority API and requests a clientSecret.
  • Handoff: Your backend passes the clientSecret to your frontend.
  • Rendering: The frontend initializes the WidgetSDK using the secret.
  • Completion: The user completes payment; the widget notifies your frontend via callbacks (onSuccess, onError).

The widget supports credit/debit cards as payment methods as of today.


Server Side

The server-side implementation is the foundation of your security, acting as a protected bridge between your private credentials and the Priority Commerce Engine.

Step 1: Create a Checkout Session

For every new checkout attempt, your server must generate a unique, short-lived clientSecret using the POST/client-secrets This token authenticates the widget without exposing your private API keys. You can refer to the below code for request, response and example to create client secret.

{
    "widgetType": "CHECKOUT",
    "businessId": "{{businessId}}"
}
{
    "clientSecret": "cs_test_...",
    "expiresAt": "2026-02-28T12:00:00Z",
    "widgetType": "CHECKOUT",
    "businessId": "{{businessId}}"
}
const response = await fetch(
  'https: //sandbox-api.prioritycommerce.com/client-secrets',
{
    method: 'POST',
    headers: {
      'x-api-key': process.env.SECRET_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      widgetType: 'CHECKOUT',
        "businessId": "{{businessId}}"
    })
}
);

const { clientSecret, expiresAt
} = await response.json();

// Return clientSecret (and optionally expiresAt) to your frontend

Idempotency & Duplicate Prevention:

To prevent double-charging (e.g., if a user refreshes the page), ensure your backend logic checks if a successful transaction already exists for the current orderId before requesting a new secret.

Please ensure Client secrets expire (e.g. after 30 minutes); your frontend should request a new one if the user returns to checkout after expiry.


Client Side

The client-side phase focuses on the user experience, where the SDK takes over to render the secure interface and manage the payment lifecycle. By following these three steps, you will mount the widget into your UI and configure the real-time callbacks that guide your customers through a successful checkout.

Step 1: Load the Widget - import module sdk

Include the widget library on the specific page where the checkout will appear. This exposes the global WidgetSDK object for you to use.

Loading the script directly from our secure Content Delivery Network ensures you are always using the latest, PCI-compliant version of the payment form without needing to manually update code.

<script src="https://sandbox-widgets.prioritycommerce.com/widgets-sdk/widget-sdk.js">
</script>

Step 2: Create a Container Element

Reserve a DOM element (usually a div with an id) on your page where the widget will be rendered. You must ensure this element exists in your HTML before you attempt to initialize the WidgetSDK.create() .

This container acts as a specific "placeholder" in your site's layout. It allows you to control exactly where the payment form appears (e.g., inside a dedicated "Payment Details" section), preserving your site’s design and user experience.

<div id="checkout-container"></div> 

Step 3: Initialize the Widget

Call the WidgetSDK.create() method using the clientSecret you generated on your server (Server side - Step 1). This is where you pass configuration options like the transaction amount and user details.


const widget = WidgetSDK.create('CHECKOUT',
{
  clientSecret: clientSecret, // From your backend
  containerId: '#checkout-container', // From your div ID
  businessId: 'biz_123', // Your assigned business ID
  transactionOrigin: 'CARD_PRESENT_KEYED',
  amount: {
    value: '50.00',
    currency: 'USD'
    },
  onSuccess: (result) => {
    console.log('Payment successful:', result.transactionId);
    window.location.href = '/order/success';
    },
  onComplete: (result) => {
        // Optional: cleanup or analytics
    },
  onError: (error) => {
    console.error('Payment error:', error.message);
    }
});
const widget = WidgetSDK.create('CHECKOUT',
{
  clientSecret: clientSecret,
  containerId: '#checkout-container',
  businessId: 'biz_123',
  transactionOrigin: 'CARD_PRESENT_KEYED',
  debug: false,
  amount: {
    value: '100.00',
    currency: 'USD'
    },
  customer: {
    id: 'cust_abc123'
    }, // returning customer
  address: {
    line1: '123 Main St',
    line2: 'Apt 4B',
    city: 'San Francisco',
    state: 'CA',
    postalCode: '94102',
    country: 'US'
    },
  billing: {
    collectAddress: true,
    infoType: 'full'
    },
  paymentMethods: {
    methods: {
      creditCard: true
        },
    enableCardSaving: true,
    showSavedCards: true
    },
  layout: {
    summary: {
      display: true,
      position: 'RIGHT',
      collapsible: true
        }
},
theme: { /* WidgetTheme */ },
 onSuccess: (result) => {
        /* ... */
    },
  onComplete: (result) => {
        /* ... */
    },
  onError: (error) => {
        /* ... */
    }
});

Customization Reference

This section provides a definitive guide to customizing the widget's behavior, appearance, and data handling. It details every property you can pass into WidgetSDK.create(). i.e. Step 3: Intialize the Widget

  1. Base Configuration: These are the mandatory settings required to initialize the widget and link it to your specific transaction session.

    ParameterRequiredDescription
    clientSecretThe unique key generated by your backend for a specific transaction.
    containerIdThe CSS selector (e.g., #checkout-container) where the widget will render.
    businessIdYour assigned Priority business identifier.
    transactionOriginSource of the transaction: ECOM, MOTO, CARD_ON_FILE, or CARD_PRESENT_KEYED.
    debugOptionalEnable debug logging (Default: false).
    onSuccessRecommendedCalled with full transaction result on success.
    onCompleteRecommendedCalled after success. It is useful for performing cleanup actions, or redirecting the user.
    onErrorRecommendedCalled with error payload on failure.
  2. Amount Configuration: These attributes define the transaction amount and currency for the checkout session.

    ParameterRequiredDescription
    amount.valueThe total amount formatted as a string with 2 decimal places (e.g., 50.00).
    amount.currencyThe 3-letter ISO 4217 currency code (e.g., USD, EUR).
  3. Customer & Address Configuration: These optional settings allow you to pre-populate customer and billing related fields and the level of information required from the customer, reducing friction for the user.

    Parameter

    Required

    Description

    customer.id

    Optional

    Unique identifier of an existing customer in Priority Vault (e.g., cust_abc123). Passing this value allows the widget to recognize returning customers and display previously saved cards (if paymentMethods.showSavedCards configuration is true).

    address

    Optional

    Defines billing address fields that may be collected during checkout, including address.line1, address.line2, address.city, address.state, address.postalCode, address.country (ISO 3166-1 alpha-2).

    This configuration allows you to pre-fill customer information. Reducing the number of fields a customer has to type manually, significantly increases success rate.

    billing

    Optional

    High-level configuration that controls billing address collection within the checkout form.

    billing.collectAddress

    Optional

    Determines whether billing address fields should be displayed on the checkout form.

    true: Displays the address details on checkout form

    false : Hides the address details from the checkout form.

    Note: Address requirements may also depend on merchant-level AVS configuration. If AVS is enabled for the merchant, certain address fields (such as ZIP/Postal code) may be required and displayed on the form, even if billing.collectAddress is set to false. Please reach out to the PCE Account Management team to confirm the AVS and address configuration enabled for your account.

    billing.infoType

    Optional

    Specifies the level of billing information to be collected.

    • minimal : Collects limited details such as address.country and address.postalCode.

    • full : Collects complete billing address including address.line1, address.line2, address.city, address.state, address.country and address.postalCode.

      Note: Address requirements may also depend on merchant-level AVS configuration. If AVS is enabled for the merchant, certain address fields (such as ZIP/Postal code) may be required and displayed on the form, even if billing.collectAddress is set to false. Please reach out to the PCE Account Management team to confirm the AVS and address configuration enabled for your account.

  4. Payment Methods Configuration: These fields reflect which payment method will be shown. Please note customer.id is required to display previously saved cards.

    ParameterRequiredDescription
    paymentMethods.enableCardSavingOptionalAllow customers to save cards for future use (true, false)
    paymentMethods.showSavedCardsOptionalDisplays previously saved cards associated with the customer. If true, saved cards are shown on the checkout form. If false, saved cards are not displayed.
  5. Layout Configuration: These fields reflect how on the widget it will look.

    ParameterRequiredDescription
    layout.summary.displayOptionalControls whether the order summary section is displayed within the checkout interface (true / false).
    layout.summary.positionOptionalConfigures where the payment summary section will be displayed i.e., LEFT or RIGHT.
    layout.summary.collapsibleOptionalDetermines whether the order summary section can be expanded or collapsed by the user (true / false).
  6. Customize Checkout: Configure the Checkout experience to align with your brand, including visual elements such as colors, border radius, and text styling.

Option

Required

Description

theme

No

Defines the visual styling of the Checkout widget, allowing you to customize elements such as colors, typography, and component styling to match your brand.

For detailed configuration options, refer to the Customization & Branding.


Handling events After Payment Initiation

The Checkout Widget is event-driven and communicates transaction status directly to your application in real-time. Implementing callbacks is critical for managing user experience during declines and ensuring accurate backend reconciliation.

📘

Please note: To configure the event callbacks refer to Step 3: Intialize the Widget when initializing the widget at Client side.

onSuccess events for Payment Completion

This event is triggered when the Create Payment, Update & Delete vault card actions complete successfully.

  • Create Payment: This event triggers immediately when a payment is successfully authorized and completed. It acts as the definitive signal to finalize the order, redirect the user, and record the amount in your backend systems. This action returns a transactionId and masked card details, as shown in the example below.
    "data": {
        "transactionId": "4000000000735352",
        "reference": "606506268541",
        "totalAmount": {
            "value": "12.34"
        },
        "amount": {
            "value": "12.34"
        },
        "fees": [
            {
                "type": "SURCHARGE",
                "amount": {
                    "value": "0.00"
                }
            }
        ],
        "paymentMethod": {
            "card": {
                "brand": "VISA",
                "last4": "0117",
                "type": "DEBIT"
            }
        }
    }
    }
📘

Note: Update and Delete Cards can only be used if you are leveraging the SavedCards feature.

  • Update Card: Enables returning customers to update details of their previously saved card directly from the checkout experience. The CARD_UPDATE action returns a new secure token and updated masked card details, as shown in the example below.
    {
        "widgetType": "CHECKOUT",
        "status": "SUCCESS",
        "timestamp": 1772779737341,
        "actions": [
            "CARD_UPDATE"
        ],
        "data": {
            "card": {
                "id": "10000000598951",
                "token": "TYT13KSQEBUA8FA3J6CW2ATUADV6KEIH",
                "brand": "VISA",
                "last4": "1830",
                "name": "dfghjeeeww",
                "type": "CREDIT",
                "expiryMonth": "12",
                "expiryYear": "2030",
                "isDefault": false,
                "billingAddress": {
                    "address1": "dddjj",
                    "address2": "kkkss",
                    "city": "ddbbb",
                    "state": "CO",
                    "zip": "67898",
                    "country": "US"
                }
            }
        },
        "customer": {
            "id": "10000000888479"
        }
    }
  • Delete Card: Enables returning customers to remove a previously saved card from their checkout experience. The CARD_DELETEaction returns the masked card details and the unique id of the vaulted card that was successfully removed from the Priority Vault, as shown in the example below.
    {
        "widgetType": "CHECKOUT",
        "status": "SUCCESS",
        "timestamp": 1772779787394,
        "actions": [
            "CARD_DELETE"
        ],
        "data": {
            "card": {
                "id": "10000000598951"
            }
        },
        "customer": {
            "id": "10000000888479"
        }
    }

onError event

This event is triggered whenever a transaction fails to complete, whether due to user input errors, bank declines, or system interruptions. You can refer to the nodes for error payload here:

ParameterDescription
codeHigh-level error identifier indicating the category of error returned by the widget.
typeSpecifies the context or component where the error occurred.
messageHuman-readable description of the error explaining what went wrong (e.g., “Card number is invalid”). This can be displayed to the user or logged for debugging.
detailsOptional granular data, such as which specific field caused a validation failure.

Best Practice: Log code and type internally; show a simplified message to the user. Avoid exposing internal error details.

{
    "widgetType": "CHECKOUT",
    "status": "ERROR",
    "timestamp": 1772800361824,
    "data": {
        "code": "PAYMENT_DECLINED",
        "type": "PAYMENT_ERROR",
        "message": "Card Not Enabled (BIN: 378282)"
    }
}

onChange event

This event fires in real-time as the user interacts with the saved card details. It is vital for dynamic UI updates before the final submission.

The following important nodes are returned in payload data:

ParameterDescription
changedFieldsIdentifies which input field was modified (e.g., cardNumber).
paymentMethodProvides early brand detection (e.g., VISA) to update UI logos dynamically.

You can refer to the nodes in the example below:

{
    "widgetType": "CHECKOUT",
    "status": "CHANGE",
    "timestamp": 1772800770101,
    "data": {
        "changedFields": [
            "cardNumber"
        ],
        "amount": {
            "value": "12.34",
            "currency": "USD"
        },
        "fees": [
            {
                "type": "SURCHARGE",
                "amount": {
                    "value": "0.37",
                    "currency": "USD"
                }
            }
        ],
        "paymentMethod": {
            "card": {
                "brand": "VISA",
                "last4": "1111"
            }
        }
    }
}

onComplete event for Payment Redirection

This is a Session Completion "onComplete" event, which triggers after onSuccess , once the user has finished the interaction (e.g., clicking a "Done" button). Use this for triggering final analytics events to mark the user journey as fully closed.

The following nodes are returned in payload data:

ParameterDescription
widgetTypeIdentifies the source component as CHECKOUT.
statusReturns COMPLETE, indicating the user has finished the session and the widget can be safely dismantled.

You can refer to the nodes in the example below:

{
    "widgetType": "CHECKOUT",
    "status": "COMPLETE"
}

Testing & Troubleshooting

To finalize your integration and move toward a production launch, follow these defined paths for testing and deployment.

Execution & Support Pathways

  • Sandbox Testing: Utilize the sandbox environment with test credentials to validate your integration and simulate various transaction outcomes.
  • Production Go-Live: Upon successful validation, your account team will provide live production endpoints, unique credentials, and a final go-live checklist.
  • Technical Assistance: If you encounter unresolved issues, prepare your diagnostic logs, including the onError payload and browser environment details and share them with your integration or support contact.

You can use the Card Test Data to simulate common card payment scenarios.

To ensure system uptime and a seamless user experience, use the following to diagnose and resolve integration or transaction-level issues. The table below identifies common technical hurdles, the specific steps required to verify their root cause.

IssueVerification Steps
Widget does not appearVerify the container element exists in your DOM and that the containerId matches your HTML. Confirm the script is correctly loaded and check for JavaScript errors in the browser console.
"Invalid or expired client secret"Ensure your backend generates a new secret for every unique session and verify it has not exceeded its 30-minute time-to-live (TTL).
Payment does not completeConfirm you are using a valid businessId and the correct environment (Sandbox vs. Production). Review the onError payload and check for network or CORS issues.

If these steps do not resolve the issue, capture the browser version, operating system, and the full onError payload to share with your integration support contact team for an expedited resolution.