Checkout SDK
The Checkout SDK lets you embed sustainability options directly into the checkout flow, so consumers 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.
The SDK supports two impact types, carbon and nature. The session's impactType decides which one renders, and the same initCheckout call drives both. See Impact types below for what each experience shows.
Integration sequence
The diagram below shows the complete Checkout SDK flow, from the backend session request through to settlement.
Step-by-step flow
- Create an organisation. If your hierarchy requires it, create a child organisation using
POST /v3/organisations. See Create an organisation. - Create a checkout session. Call
POST /checkout/sessionswith theproductId, transaction details, and merchant info. The response returns aquoteId,sessionIdand a short‑livedclientSecret. - 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.
- Subscribe to SDK events and update the payment amount. The SDK emits events when the consumer toggles and/ or round‑up options. Listen for these events and update the payment total immediately so the main payment includes the consumer's choice.
- Consumer completes payment. You process the main payment including any contribution amount added via the toggle.
- Record the contribution. After a successful payment, call
POST /v3/funds/allocationswith thequoteIdand chosen amount to create the impact record and receive areference. - Reconciliation (and reversals if needed). Use
GET /v3/funds/allocations/impactfor reporting and audit. If the purchase is refunded or cancelled, callPOST /v3/funds/allocations/{id}/reversewith the originalreference.
Key features
- Contribution controls matched to the impact type: carbon credits and round-up toggles for carbon, fixed-value contribution buttons for nature
- 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 consumer education and legal disclosures, always shown
- Error and load state handling with fallback so checkout is never blocked
Impact types
When the session's impactType is carbon, the checkout shows:
- a hero number for the carbon footprint in grams or ounces based on the consumer's locale, with an illustrative equivalent
- toggles for carbon credits and round-up contributions
- an optional reward bar and a "Learn more" modal
When the session's impactType is nature, the checkout shows:
- a hero number for the biodiversity footprint in Mean Species Abundance (MSA), shown in square metres or square feet based on the consumer's locale, with one illustrative equivalent
- a contribution option presented as fixed-value buttons (for example £1, £3, £5) with an optional "contribute more" control
- up to three impact partner logos
- a "Learn more" link covering the methodology and the partners involved
For background on the metrics, see carbon footprint and nature footprint.
SDK events use the same names for both impact types (ready, toggleChanged, resize, error). Each payload carries the session's impactType, and the ready payload describes the footprint and contribution options for that type. Update your payment total from toggleChanged in the same way for both.
Nature checkout in active development
The nature checkout is in active development. The type reference below describes the carbon payloads; nature payload types will be added as the SDK builds out.
Customisation options
The carbon credits toggle, round-up toggle and reward bar rows apply to carbon sessions. Nature sessions present fixed-value contribution buttons in their place.
Learn more is always shown
The "Learn more" modal can't be turned off. It carries the legal disclaimers that have to appear with every checkout, so it renders on all sessions.
| Customisation | Options | Default | Guidance |
|---|---|---|---|
| Carbon credits toggle | true / false | true | Lets consumers purchase carbon credits linked to their transaction, funding verified climate projects |
| Round up toggle | true / false | true | Lets users round their payment to the nearest whole number, with the difference going to impact projects |
| Reward bar | true / false | true | Positive reinforcement – it gives users a visible "well done" moment when they switch on carbon credits or round-up |
| Primary colour | your choice | ekko green: #1A4432 | Dark colour |
| Secondary colour | your choice | 8% of ekko green: #EDF0EF | Light colour; important to make sure the contrast ratio between primary and secondary is at least WCAG Grading AA |
| Highlight colour | your choice | #007A08 | Accent colour; contrast between this colour and the secondary colour needs to rate at least WCAG Grading AA |
| Text font | your choice | Inter (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 radius | your choice | follow radius of input fields up to 20px | Inside corners will follow outer corners - if outer radius is 20px, the inside radius will be 16px as the padding is fixed to 4px. |
| Image | your choice | mountain, elephant, ocean, bird and waterfall | Match image with projects/organisations being supported |
Images

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.
Install with npm
npm install @ekko-earth/checkout-jsInitialise with npm
You can listen to SDK events in two ways: pass callbacks in on during initialisation, or subscribe after initialisation with checkout.on(...).
import { initCheckout, type CheckoutSDK } from '@ekko-earth/checkout-js'
const checkout: CheckoutSDK = initCheckout({
container: '#ekko-checkout-container',
sessionId: session.sessionId,
clientSecret: session.clientSecret,
mode: 'production',
// Option A: subscribe during init
on: {
ready(e) {
console.log('Checkout ready', e)
},
toggleChanged(e) {
console.log('Toggle changed', e)
}
}
})
// Option B: subscribe after init
checkout.on('toggleChanged', (e) => {
console.log('Post-init toggleChanged subscription', e)
})
checkout.destroy()Install with a script tag
Load the SDK from the CDN if you are not using a bundler. The global variable is EkkoCheckout.
<div id="ekko-checkout-container"></div>
<script src="https://static.ekko.earth/v1/checkout/sdk/index.js"></script>
<script>
const checkout = EkkoCheckout.initCheckout({
container: '#ekko-checkout-container',
sessionId: 'sess_123',
clientSecret: 'cs_abc',
mode: 'production',
// Option A: subscribe during init
on: {
ready(e) {
console.log('Checkout ready', e)
},
toggleChanged(e) {
console.log('Toggle changed', e)
}
}
})
// Option B: subscribe after init
checkout.on('toggleChanged', (e) => {
console.log('Post-init toggleChanged subscription', e)
})
</script>Type Reference
// Event payloads
export type ReadyEvent = {
sessionId: string
width: number
height: number
carbonImpact: {
grams: number
ounces: number
credits: {
amount: number
serviceFee: number
currencyCode: string // ISO 4217
}
}
}
export type ToggleChangedEvent = {
key: 'carbonCredits' | 'roundUp'
/** Determines if the toggle was enabled or disabled (i.e. true | false) */
enabled: boolean
/** New total credits amount after the change */
totalCreditsAmount: number
/** New total payment amount after the change */
totalRoundupAmount: number
/** ISO 4217 currency code for all amounts (e.g., 'GBP'). */
currencyCode: string
}
export type ResizeEvent = {
height: number
width: number
}
export type ErrorEvent = {
code: string
message: string
}
// Event callbacks
export type CheckoutEventCallbacks = {
ready?: (e: ReadyEvent) => void
error?: (e: ErrorEvent) => void
toggleChanged?: (e: ToggleChangedEvent) => void
resize?: (e: ResizeEvent) => void
}
// Init options
export interface InitCheckoutOptions {
sessionId: string
clientSecret: string
container: HTMLElement | string
mode: 'sandbox' | 'production'
locale?: string
features?: {
carbonCredits?: boolean // default: true
roundUp?: boolean // default: true
rewardBar?: boolean // default: true
}
appearance?: {
image?: 'elephant' | 'mountain' | 'forest' | 'ocean' // default: 'elephant'
primaryColor?: string
secondaryColor?: string
highlightColor?: string
textFont?: string
outerBorderRadius?: number // px
}
on?: CheckoutEventCallbacks
}
// Instance
export interface CheckoutSDK {
on(eventName: 'ready' | 'error' | 'toggleChanged' | 'resize', handler: Function): void
// Lifecycle
destroy(): void
}Key inputs
Required
sessionId. 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 SDK mounts the checkout UI. Checkout expands to 100% of this container's size.mode. The environment the SDK should use for rendering. Always set this explicitly tosandboxorproduction.
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 sessionfeatures. Toggle specific checkout behaviours. Either carbonCredits or roundUp needs to be enabledcarbonCredits: boolean (default true) – Enables or disables the carbon credits toggle.roundUp: boolean (default true) – Enables or disables "round up" toggle.rewardBar: boolean (default true) – Controls visibility of the reward progress bar.
appearanceControls visual style and branding.image: 'elephant' | 'mountain' | 'forest' (default elephant) – image used in UIprimaryColor– 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.outerBorderRadius: number – Corner radius for cards/containers, in pixels.
on?: CheckoutEventCallbacks. Callbacks for SDK → client notifications during initialisation.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 credits or round up). Payload includes the toggle key, its new state, and the updated amounts.resize(e: ResizeEvent)– Fired whenever the size of the component changes. Use it to set the container height exactly to the rendered checkout.
CheckoutSDK (returned by initCheckout)
initCheckout)on(eventName, handler): void Subscribes to an SDK event after initialisation.destroy(): void Tears down the checkout instance and cleans up all event listeners. Use when unmounting or navigating away.
Behaviour and requirements
- Sizing → Checkout SDK has a
resizeevent which communicates the size of the container. You can then 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 and 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
sessionIdandclientSecretto 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 using
onduring initialisation orcheckout.on(...)after initialisation to update totals in real time and persist toggle state for a smooth UX. - CSP & network: allow the ekko checkout app and CDN domains, plus any fonts/images used by appearance.
Security
Content Security Policy (CSP)
Allow the ekko checkout app and SDK CDN in your host page CSP:
- Production CDN:
https://static.ekko.earth - Sandbox CDN:
https://staging.static.ekko.earth
Content-Security-Policy: default-src 'self'; script-src 'self' https://static.ekko.earth https://staging.static.ekko.earth;Network allowlist (egress)
If your environment restricts outbound traffic from the host page/app, allow HTTPS (443) to:
static.ekko.earthstaging.static.ekko.earth
