DEVELOPER
Products

Embedded Checkout Direct Post Integration Guide


Base URL
https://checkout.north.com

Take full control of your payment experience with the Embedded Checkout Direct Post integration method. Build your own payment form and use our lightweight JavaScript library to securely submit payments directly to the Embedded Checkout API. This integration gives you maximum flexibility but requires that your client handles raw payment data, which increases your PCI compliance requirements. Consider using the Embedded Checkout Fields integration method for minimized PCI scope while maintaining flexibility.


What You'll Build

Use this guide to build a completely custom payment form. You'll create and style your own payment input fields, and use our JavaScript library to securely submit payments directly to our payment API.


Checkout Flow

  1. Add the checkout.js script to your page.
  2. For each payment attempt, create a checkout session on your server.
  3. Build your own payment form
  4. Submit the payment when your form is submitted using checkout.sendPayment()
  5. Handle the payment response by configuring a webhook in the Embedded Checkout Designer or verifying completion via the session status endpoint.

Session Lifecycle & Statuses

A checkout session progresses through the following statuses:

StatusDescription
OpenSession created; customer has not yet loaded the checkout form
VerifiedCustomer has loaded the checkout form; session was verified via the verify endpoint
ApprovedPayment was successfully processed and approved
DeclinedPayment was declined

Use these statuses to track checkout progress and determine when payment is complete.


Prerequisites

Before you begin, ensure you complete the following prerequisites. Your private keys and IDs can be obtained by navigating to your North Developer dashboard and selecting a checkout instance.

Get started quickly by downloading the provided sample code from a checkout instance on your dashboard, including the code for your customized Direct Post integration as well as the backend code required to submit payments from your website. You'll need:



Step 1: Create a Checkout Session

From your server, create a checkout session by calling the Create Session API endpoint and passing your private API key in the header as a bearer token. This request returns a short-lived token that authorizes payment submissions. Sessions expire after 30 minutes.


API Endpoint


Request Headers

HeaderValue
Content-Typeapplication/json
AuthorizationBearer {YOUR_PRIVATE_API_KEY}

Request Body

Note: For Direct Post, you can create sessions without products or amount. The payment amount is specified when calling sendPayment().


Request Parameters


Example cURL Request


Response


Step 2: Add the Checkout Script

Include the checkout.js script on your page. This script provides the checkout object with the sendPayment() method.


Script Tag

Once loaded, the checkout object is available globally with the checkout.sendPayment(token, paymentRequest) method, enabling you to submit a payment directly.


Step 3: Build Your Payment Form

Create your own payment form with card input fields. You have complete control over the design and user experience.


Example Form


Step 4: Submit the Payment

When your form is submitted, build a payment request object and call checkout.sendPayment() to process the payment.


sendPayment Method Signature

Parameters


Payment Request Object


Payment Request Example


Step 5: Handle the Payment Response

The checkout.sendPayment() method returns the payment result directly from the payment processor.


Success Response


Declined Response


Response Handling Example


Server-Side Verification

Your server should never trust the client alone. When the user reaches your confirmation page (e.g., after a redirect), your backend must verify payment completion. There are two ways:


Method 1: Verify Payment Completion (Session Status Endpoint)

Endpoint: GET /public/api/sessions/status

Use this endpoint to verify whether a payment was approved or declined before fulfilling an order. The session status and payment response are stored at the server and cannot be tampered with by the client, so the status endpoint gives your backend a trusted source of truth.


Typical Flow

  1. The user completes payment in your form (via checkout.sendPayment()).
  2. The front-end redirects to your callback URL (e.g., a confirmation page), potentially passing the session token or payment data in the URL or via client-side state. Your backend must not trust that client-side data as a user could tamper with URL parameters or state.
  3. When the user reaches your callback page, your backend calls the /status endpoint with the API key and session token, and receives the authoritative status and payment response from the server.
  4. That response gives your backend a trusted source of truth for whether the payment was approved or declined and what the response was, which should be used to decide whether to fulfill the order.

Authentication

  • API key in Authorization header as Bearer token
  • Session token in SessionToken header

Request (API key + session token in header)

Note: The session token must not be sent from browser-based JavaScript. Use server-side code only to avoid exposing the session token. The status endpoint rejects requests with an Origin header.


Response (200 OK)

statusMeaning
OpenSession created, checkout not yet loaded
VerifiedCheckout form loaded and verified
ApprovedPayment successfully processed and approved; body contains payment response
DeclinedPayment was declined; body may contain decline response

When status is Approved, body contains the full payment authorization response (receipt data). When status is Declined, body may contain the decline response.


Method 2: Transaction Webhook (Receipt)

Configure a webhook URL in your checkout using the Checkout Designer. When a payment completes, the API sends a POST request to your URL with the transaction and receipt data. The webhook URL must use HTTPS.


Webhook Delivery

  • URL: {webhookURL}/transaction
  • Method: POST
  • Content-Type: application/json

Request Headers

HeaderDescription
Content-Typeapplication/json
X-YourApp-Signature-256HMAC-SHA256 signature for verification
X-YourApp-TimestampUnix timestamp (milliseconds)

Request Body

  • transaction – The transaction record. Includes id, tranType, authCode, authResponseText, authResp, authCardType, maskedAccountNumber, amount, authGuid, fullResponse, and other fields.
  • additionalFormFields – (Optional) Custom form fields submitted with the checkout.

Verifying Webhook Signatures

Verify the X-YourApp-Signature-256 header using your checkout's private key:

Compare expected_header with X-YourApp-Signature-256. Reject the request if they do not match. Use the exact raw request body bytes you receive, not a re-stringified parsed object. JSON serialization can differ (key order, whitespace, etc.) and will break the signature check.


Step 6: Test the Integration

When a checkout is in Draft Mode, requests are automatically made in the Sandbox environment. When you're ready to go live and make requests in the Production environment, we'll certify your checkout with no need to manually switch environments.

In Draft Mode, requests are sent to the payment processor's Sandbox environment, guaranteeing that your tests receive real results from the processor, not mock responses, so that you can build accurate response handling into your application with confidence. To test various payment response codes in Draft Mode, the transaction amount can be modified to a designated value that will trigger a specific response code. Read more about response code triggers.

UI/UX testing can also be done from the Checkout Designer using the integrated card testing tools, however these are mock payment requests that do not return real results from the payment processor.

Use the following test card numbers in the Sandbox environment:


Card NumberBrandResult
4111 1111 1111 1111VisaSuccessful transaction
3700 000000 00002AmexSuccessful transaction

Test Card Details:

  • Expiration: Any future date in MMYY format (e.g., "1225")
  • CVV: Any 3 digits (e.g., "123") or 4 digits for Amex
  • ZIP: Any 5 digits (e.g., "12345")

Additional Notes


Success Checklist

Before certification, verify your integration:

  • Session tokens are created successfully
  • Test card transactions are approved
  • Declined transactions show proper error messages
  • Card number formatting is handled correctly
  • Expiration date is converted to MMYY format
  • Amount validation works (positive numbers only)
  • Webhook or session status endpoint receives transaction notifications
  • Error states are handled gracefully

Protect Your API Keys

  • Never expose your private API key in client-side code
  • Store API keys in environment variables
  • Generate session tokens only on your server

PCI Compliance

Direct Post integration requires handling raw card data, which increases your PCI scope to SAQ A-EP. Ensure your implementation meets all PCI DSS requirements .

  • Use HTTPS for all pages handling card data
  • Never log or store raw credit card, payment, or transaction data that's protected under PCI DSS requirements
  • Implement proper input validation
  • Consider using the Embedded Checkout Fields integration to reduce PCI scope

Domain Restriction

In the Production environment, the domain where your checkout is hosted is limited to the domain set during checkout configuration. This prevents unauthorized use of your checkout configuration. This rule is not applied in Draft Mode.


Session Token Expiration

Session tokens expire after 30 minutes. Generate a new token for each checkout session rather than reusing tokens.


Error Handling Best Practices


Secondary Transactions

After completing an initial sale, a transaction token is returned in the response that can be used for subsequent payment functionality, such as voids, refunds, and reversals. View the API Specification to learn more about these transaction types.


Next Steps

Now that you've added payments to your website with the Embedded Checkout Direct Post integration, you can:

  • Manage Your Checkouts - View and manage your checkout configurations in the dashboard.
  • Contact Support - Get help with your integration.
  • Certify and Go Live - Start the certification process with our support team. Once we confirm everything is working as expected, you'll be ready to start accepting payments in the Production environment.



Top of Page
// server.js
// This server creates checkout sessions by securely calling the Embedded Checkout API

const express = require('express');
const app = express();

// Enable JSON parsing for incoming request bodies
app.use(express.json());

// Endpoint that your client-side code will call to create a session
app.post('/api/create-checkout-session', async (req, res) => {
  try {
    // Call the Create Session API endpoint to create a new checkout session
    // This returns a short-lived token (30 min) for authorizing payment submissions
    const response = await fetch('https://checkout.north.com/public/api/sessions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        // Authenticate with your private API key (stored in an environment variable)
        'Authorization': `Bearer ${process.env.CHECKOUT_PRIVATE_KEY}`
      },
      body: JSON.stringify({
        // Your checkout configuration ID from the Checkout Designer
        checkoutId: process.env.CHECKOUT_ID,
        // Your merchant profile identifier
        profileId: process.env.PROFILE_ID
      })
    });

    // Handle API errors by forwarding the error response to the client
    if (!response.ok) {
      const error = await response.json();
      return res.status(response.status).json(error);
    }

    // Return the session data (including token) to the client
    const session = await response.json();
    res.json(session);
  } catch (error) {
    // Log server-side errors for debugging
    console.error('Session creation error:', error);
    res.status(500).json({ error: 'Failed to create session' });
  }
});

// Start the server
app.listen(3000, () => {
  console.log('Server running on port 3000');
});
©2026 North is a registered DBA of NorthAB, LLC. All rights reserved. North is a registered ISO of BMO Harris Bank N.A., Chicago, IL, Citizens Bank N.A., Providence, RI, The Bancorp Bank, Philadelphia, PA, FFB Bank, Fresno, CA, Wells Fargo Bank, N.A., Concord, CA, and PNC Bank, N.A.