Checkout SDK

The Checkout SDK lets you embed sustainability options directly into the checkout flow, so customers can see their impact and add a contribution before paying. Unlike post-purchase SDKs, contributions happen as part of the original payment - no second transaction required.

Checkout SDK

Step-by-step flow

  1. Create a brand. Use POST /organisations/brand/onboarding to create a brand and get a productId.
  2. Create a checkout session. Call POST /checkout/sessions with the productId, transaction details, and merchant info. The response returns a calcReference, checkoutSessionId and a short‑lived clientSecret.
  3. Initialise the SDK. On your frontend, include the SDK and initialise it with your checkout session details, container reference and configuration options. ekko will server‑side render the impact component and dynamic messaging based on your configuration and session data. This lets us iterate content and visuals without you shipping new code.
  4. Subscribe to SDK events and update the payment amount. The SDK emits events when the customer toggles compensation and/ or round‑up options. Listen for these events and update the payment total immediately so the main payment includes the customer’s choice.
  5. Customer completes payment. You process the main payment including any contribution amount added via the toggle.
  6. Record the contribution. After a successful payment, call POST /projects/funds with the calcReference and chosen amount to create the impact record and receive a reference.
  7. Reconciliation (and reversals if needed). Use POST /impact_records for reporting and audit. If the purchase is refunded or cancelled, call POST /reversal with the original reference.

Key features

  • Toggle for carbon compensation and/ or round-ups
  • Event-driven updates so payment totals can be adjusted in real time
  • Customisable look and feel — text and background colours, fonts, images and corner radius can be adjusted to fit the look and feel of your page
  • “Learn more” modal for customer education
  • Error and load state handling with fallback so checkout is never blocked

Customisation options

You can find a visual overview of the Checkout SDK customisation options here.

Checkout SDK customisation options

CustomisationOptionsDefaultGuidance
Carbon compensation toggletrue / falsetrueLets users directly compensate for the footprint of their purchase
Round up toggletrue / falsetrueLets users round their payment to the nearest whole number, with the difference going to impact projects
Learn more modaltrue/ falsetrueShows a modal with information about the organisations being supported
Reward bartrue / falsetruePositive reinforcement – it gives users a visible “well done” moment when they switch on carbon compensation or round-up
Themelight / darklightFit into the general look and feel of your checkout page
Primary colouryour choiceekko green: #1A4432Dark colour
Secondary colouryour choice8% of ekko green: #EDF0EFLight colour; important to make sure the contrast ratio between primary and secondary is at least WCAG Grading AA
Highlight colouryour choice#007A08Accent colour; contrast between this colour and the secondary colour needs to rate at least WCAG Grading AA
Text fontyour choiceInter (weights as per design)Inter is a well designed free font, chosen to clash as little as possible with most fonts applied to checkout screens. Alternatively, choose one of the Google fonts or if you would like to use a proprietary font, contact [email protected]
Corner radiusyour choicefollow radius of input fields up to 20pxInside corners will follow outer corners - if outer radius is 20px, the inside radius will be 16px as the padding is fixed to 4px.
Imageyour choicemountain, elephant, ocean, bird, waterfallMatch image with projects/organisations being supported
Checkout SDK customisation options

Images

Image options

Image options for the Checkout SDK

SDK architecture overview

The ekko Checkout SDK exposes a single public function and an instance interface: • initCheckout(options) → mounts checkout into your container and returns an instance. • CheckoutSDK → the instance interface for lifecycle and event control.

Example initialisation

import { initCheckout, type CheckoutSDK } from '@ekko-earth/checkout-js'

const checkout: CheckoutSDK = initCheckout({
  // Required
  checkoutSessionId: 'sess_123',
  clientSecret: 'cs_abc',
  container: document.getElementById('climate-checkout'),

  // Optional
  locale: 'en-GB',
  cspNonce: 'abc123',

  features: {
    carbonCompensation: true,
    roundUp: true,
    rewardBar: true,
    learnMore: true,
  },

  appearance: {
    theme: 'light',
    image: 'elephant',
    primaryColor: '#0F766E',
    secondaryColor: '#1F2937',
    highlightColor: '#10B981',
    textFont: 'Inter',
    outerBorderRadius: 24,
  },

  // SDK → Host notifications
  events: {
    ready: () => console.log('Checkout ready'),
    error: (e) => console.error('Checkout error:', e),
    toggleChanged: ({ key, enabled }) =>
    	console.log(`Toggle changed: ${key} → ${enabled}`),   
		sizeChanged: (event) => {
      console.log('Height:', event.height);
      console.log('Width:', event.width);
    }

  },
})

// Host → SDK commands
checkout.destroy()

Type Reference

// Event payloads
export type ReadyEvent = {
  checkoutSessionId: string
  carbonImpact: {
    grams: number
    ounces: number
    compensation: {
      compensationValue: number
      serviceFee: number
      currencyCode: string // ISO 4217
    }
  }
}

export type ToggleChangedEvent = {
  key: 'carbonCompensation' | 'roundUp'
  enabled: boolean

  /** Change caused by this toggle (minor units). Positive when enabling, negative when disabling */
  deltaAmount: number

  /** New total contribution for this specific toggle after the change */
  totalContributionAmount: number

  /** New total payment amount after the change */
  totalPaymentAmount: number

  /** ISO 4217 currency code for all amounts (e.g., 'GBP'). */
  currencyCode: string
}

export type SizeChangedEvent = {
  height: number;
  width: number;
};

export type ErrorEvent = {
  code: string
  message: string
}

// Events
export type CheckoutEvents = {
  ready: (e: ReadyEvent) => void
  error: (e: ErrorEvent) => void
  toggleChanged?: (e: ToggleChangedEvent) => void
  sizeChanged?: (e: SizeChangedEvent) => void;
}

// Init options
export interface InitCheckoutOptions {
  checkoutSessionId: string
  clientSecret: string
  container: HTMLElement | string
  locale?: string
  cspNonce?: string

  features?: {
    carbonCompensation?: boolean // default: true
    roundUp?: boolean            // default: true
    rewardBar?: boolean          // default: true
    learnMore?: boolean          // default: true
  }

  appearance?: {
    theme?: 'light' | 'dark' // default: 'light'
    image?: 'elephant' | 'mountain' | 'forest' | 'ocean' // default: 'elephant'
    primaryColor?: string
    secondaryColor?: string
    highlightColor?: string
    textFont?: string
    outerCornerRadius?: number // px
  }

  events?: Partial<CheckoutEvents>
}

// Instance
export interface CheckoutSDK {
  // Lifecycle
  destroy(): void
}

Key inputs

Required

  • checkoutSessionId. The identifier for the Checkout Session you created via the Checkout Sessions API. Ties the SDK instance to a specific checkout flow.
  • clientSecret. A secure token returned with the Checkout Session. Used by the SDK to authenticate the session.
  • container. The DOM element (or a CSS selector) where the checkout iframe is injected. Checkout expands to 100% of this container’s size.

Optional

  • locale. Language/region in BCP 47 format, e.g. en-GB, en-US, fr-FR. Defaults to en-GB if not provided or not set on the session
  • cspNonce. Optional CSP nonce applied to inline styles inserted by the SDK.
  • features. Toggle specific checkout behaviours. Either carbonCompensation or roundUp needs to be enabled
    • carbonCompensation: boolean (default true) – Enables or disables carbon compensation toggle.
    • roundUp: boolean (default true) – Enables or disables “round up” toggle.
    • rewardBar: boolean (default true) – Controls visibility of the reward progress bar.
    • learnMore: boolean (default true) – Controls visibility of the "Learn more" link and modal
  • appearance Controls visual style and branding.
    • theme: 'light' | 'dark' (default light) – Overall colour scheme preset.
    • image: 'elephant' | 'mountain' | 'forest' (default elephant) – image used in UI
    • primaryColor – Brand’s primary accent colour (hex or CSS colour).
    • secondaryColor – Secondary/ accent colour.
    • highlightColor – Used for highlights or interactive states.
    • textFont– Font family name applied to checkout text.
    • outerCornerRadius: number – Corner radius for cards/containers, in pixels.
  • events?: Partial<CheckoutEvents>. Callbacks for SDK → Client notifications.
    • ready(e: ReadyEvent) – Fired once checkout is initialised and data is loaded. Payload includes session ID and carbon impact summary.
    • error(e: ErrorEvent) – Fired if checkout fails to initialise or a runtime error occurs. Payload includes a code and message.
    • toggleChanged(e: ToggleChangedEvent) – Fired when a user changes a toggle (carbon compensation or round up). Payload includes the toggle key, its new state, and the updated amount.
    • sizeChanged(e: SizeChangedEvent) – Fired when the checkout element's dimensions change. Payload includes the new height and width in pixels, allowing the parent application to adjust its layout or container size accordingly.

CheckoutSDK (returned by initCheckout)

  • destroy(): void Tears down the checkout instance, removes the iframe, and cleans up listeners. Use when unmounting or navigating away.

Behaviour and requirements

  • Sizing → Checkout SDK automatically fits the container you provide. You set the container’s dimensions (width/height, min/max if needed), and checkout will render within those constraints.
  • Default behaviour → When initialised, checkout loads into the given container as a single iframe. It manages its own content, interactions, and internal navigation without additional setup.
  • Responsive → The checkout experience adapts to different screen sizes (mobile, tablet, desktop) out of the box. No extra configuration is required.
  • Container requirements → Must be present in the DOM and visible when you call initCheckout

Best practices

  • Create sessions server-side and pass the checkoutSessionId and clientSecret to the frontend. Never log the secret or include it in url's.
  • Treat the SDK as the UI/editor of state; your system remains the source of truth for amounts and charge/capture.
  • Subscribe to emitted events to update totals in real time and persist toggle state for a smooth UX
  • CSP & network: allow the ekko iframe origin and any fonts/images used by appearance. Avoid blocking third-party iframes.

Security

Content Security Policy (CSP)

Allow the ekko checkout iframe in your host page CSP:

  • Production: https://checkout.ekko.earth
  • Sandbox: https://checkout-sandbox.ekko.earth
Content-Security-Policy: default-src 'self'; frame-src https://checkout-renderer.ekko.earth https://checkout-renderer-sandbox.ekko.earth;

CSP Nonce (Optional)

If your CSP blocks inline styles, pass a cspNonce when initialising so the SDK can apply minimal inline CSS safely: Your CSP must include the same nonce: Content-Security-Policy: style-src 'self' 'nonce-r4nd0mAbCdEf';

Network allowlist (egress)

If your environment restricts outbound traffic from the host page/app, allow HTTPS (443) to:

  • checkout.ekko.earth
  • checkout-sandbox.ekko.earth