Skip to content
Kayana

Build an Advanced Kayana Integration with Stripe in Node.js

Last updated Mar 10, 2026

Build an advanced Kayana integration to securely collect card payments using Kayana’s Payment API powered by Stripe for your e-commerce store.

Overview

The Kayana Payment API enables you to accept payments without building your own PCI-compliant checkout.

This guide walks you through integrating the Stripe Embedded Checkout flow using Node.js in sandbox mode.

What You’ll Build

In this guide you will:

  1. Create a payment instance on your Node.js server
  2. Retrieve the Stripe publishable key
  3. Initialise Stripe on the frontend
  4. Render Stripe’s secure Embedded Checkout capsule
  5. Complete the payment securely

Before You Begin

You’ll need:

  • A Kayana property ID
  • Access to the sandbox environment
  • Basic knowledge of Node.js
  • A Node.js backend server
  • A React / Next.js frontend

Sandbox vs Production

Sandbox

Safe test environment

  • Uses Stripe test keys
  • No real transactions
  • Ideal for development and testing

Production

  • Requires authorisation token
  • Uses live Stripe keys
  • Processes real payments

How It Works

The Stripe payment flow consists of:

Server-side (Node.js)

Create a payment instance using Kayana’s API.

Server receives

  • client_secret
  • publishable_key

Client-side

Initialise Stripe and render Embedded Checkout

Stripe

Handles payment confirmation securely.

Server Setup (Node.js)

Base URL

Sandbox:

https://integration.dev.kayana.co.uk

Step 1 - Create a Payment (Node.js Backend)

Create a Node.js API endpoint that calls Kayana’s payment API.

Example using Express.js.

Install dependencies

npm install express node-fetch dotenv

Node.js Server Implementation

require("dotenv").config();

const express = require("express");

const fetch = require("node-fetch");

const app = express();

app.use(express.json());

app.post("/api/business-payment", async (req, res) => {

try {

const response = await fetch(

"https://integration.dev.kayana.co.uk/business/payment",

{

method: "POST",

headers: {

"Content-Type": "application/json",

"x-api-key": process.env.KAYANA_API_KEY,

type: "business",

},

body: JSON.stringify({

property_id: "Prop_abc123example",

psp_code: "STRIPE",

currency_code: "GBP",

amount: 12.0,

customer_email: "customer@example.com",

}),

}

);

const data = await response.json();

res.json(data);

} catch (error) {

res.status(500).json({

status: false,

message: "Payment creation failed",

});

}

});

app.listen(3001, () => {

console.log("Server running on port 3001");

});

Environment Variables

Create a .env file:

KAYANA_API_KEY=YOUR_API_KEY

⚠️ Never expose this key in the frontend.

Request Parameters

ParameterTypeDescription
property_idstringFormat Prop_*
psp_codestringSTRIPE
currency_codestringGBP, EUR, USD
amountnumberDecimal amount (example: 12.0)
customer_emailstringCustomer email

Example API Response

{

"status": true,

"data": {

"instance_id": "Payment_xyz789example",

"client_secret": "cs_test_abc123_secret_xyz456",

"publishable_key": "pk_test_abc123example",

"next_step": {

"action": "FORM",

"proceed": true

},

"transaction_id": "Tx_txn456example"

}

}

Response Parameters

ParameterDescription
instance_idUnique payment instance ID
client_secretStripe Checkout session secret
publishable_keyStripe public key
transaction_idInternal transaction reference

⚠️ Important

client_secret must only be used on the frontend to initialise Stripe.

Step 2 - Frontend Integration (Stripe Embedded Checkout)

Install Stripe SDK:

npm install @stripe/react-stripe-js @stripe/stripe-js

React / Next.js Frontend Implementation

"use client";

import { useState } from "react";

import { loadStripe } from "@stripe/stripe-js";

import {

EmbeddedCheckoutProvider,

EmbeddedCheckout,

} from "@stripe/react-stripe-js";

export default function PaymentPage() {

const [clientSecret, setClientSecret] = useState(null);

const [stripePromise, setStripePromise] = useState(null);

const createPayment = async () => {

const res = await fetch("http://your-server.com/api/business-payment", {

method: "POST",

});

const data = await res.json();

if (data.status) {

setStripePromise(loadStripe(data.data.publishable_key));

setClientSecret(data.data.client_secret);

} else {

alert(data.message);

}

};

if (clientSecret && stripePromise) {

return (

<EmbeddedCheckoutProvider

stripe={stripePromise}

options={{ clientSecret }}

>

<EmbeddedCheckout />

</EmbeddedCheckoutProvider>

);

}

return (

<>

<h1>Stripe Payment Testing Page</h1>

<button onClick={createPayment}>

Open Payment Capsule

</button>

</>

);

}

Payment Flow

User clicks "Pay"

Frontend calls Node.js API

Node.js calls Kayana API

Kayana creates a Stripe Checkout session

Returns:

client_secret

publishable_key

Frontend loads Stripe

Stripe Embedded Checkout appears

User enters card details

Stripe confirms payment

Testing in Sandbox

Use Stripe test cards.

Card NumberBrandScenario
4242 4242 4242 4242VisaSuccessful
4000 0025 0000 3155VisaRequires 3D Secure
4000 0000 0000 9995VisaDeclined

Additional Details:

  • Expiry → Any future date
  • CVC → Any 3 digits
  • ZIP → Any valid format

⚠️ Never use test cards in production.

Error Handling

All responses include:

{

"status": false,

"message": "Description of error"

}

Common Errors

ErrorCauseSolution
Invalid API keyIncorrect x-api-keyVerify with Kayana
Invalid property IDWrong formatMust start with Prop_*
Unsupported currencyNot enabledContact Kayana
Stripe configuration missingPSP not enabledContact Kayana

Going Live Checklist

Before production:

  • Obtain production x-api-key
  • Switch to production base URL
  • Use live Stripe publishable key
  • Test real card transactions
  • Implement Stripe webhooks

Never:

  • Use sandbox keys in production
  • Expose secret keys in the frontend

Support

Technical Support: Kayana Technical Team Production credentials: Contact Kayana account manager.

Still need a hand?Contact support← All help