Skip to content
Kayana

Building an advanced Kayana integration with Stripe in React/Next.js

Last updated Mar 4, 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 Checkout (Embedded) flow in sandbox mode.

What you’ll build:

  • Create a payment instance on your server
  • Retrieve the Stripe publishable key
  • Initialise Stripe on the frontend
  • Render Stripe’s secure Checkout capsule
  • Complete the payment securely

Before you begin

You’ll need:

  • A Kayana property ID
  • Access to the sandbox environment
  • Basic knowledge of server-side development
  • Node.js / Next.js (examples provided)

Sandbox vs Production

Sandbox

  • Safe test environment
  • Uses test Stripe keys
  • No real transactions

Production

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

How it works

The Stripe payment flow consists of:

  1. Server-side – Create a payment instance
  2. Server-side – Receive:
    • client_secret (cs_test_…)
    • publishable_key
  3. Client-side – Initialise Stripe and render Embedded Checkout
  4. Stripe – Handles payment confirmation securely

Set up the server

Base URL

Sandbox:

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

Production:

https://integration.kayana.co.uk

Step 1: Create a Payment

Create a payment instance by calling:

POST /web/payment

Headers

HeaderValueRequired
Content-Typeapplication/jsonYes
x-api-keyYOUR_API_KEYYes
typebusinessYes

How to obtain your X API key

Follow these steps inside Partner Admin:

  • Log in to Kayana Partner Admin.
  • Navigate to Settings (left-hand sidebar).
  • Select API Key Management.
  • Click Create API Key.
  • Copy the generated key immediately and send it in the header.

Request Parameters

ParameterTypeDescriptionRequired
property_idstringKayana property identifier. Format: Prop_*YES
psp_codestringPayment service provider code. Value: STRIPEYES
currency_codestringISO currency code. Supported values include GBP, EUR, USDYES
amountnumberPayment amount in decimal format (e.g., 12.0)YES
customer_emailstringCustomer email address used for the payment sessionYES
payment_modestringPayment method used for the transaction. Value: CARDYES
FieldTypeDescriptionRequired
userAgentstringBrowser user agentNO
acceptHeaderstringAccept headerNO
languagestringBrowser languageNO
colorDepthnumberScreen color depthNO
screenHeightnumberScreen heightNO
screenWidthnumberScreen widthNO
timeZoneOffsetnumberTimezone offsetNO
FieldTypeDescriptionRequired
streetstringStreet addressNO
citystringCityNO
postalCodestringPostal codeNO
countrystringCountry codeNO
statestringState or regionNO

EXAMPLE REQUEST

const response = await fetch( "https://integration.dev.kayana.co.uk/web/payment", { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": "YOUR_API_KEY", "type": "business" }, body: JSON.stringify({ property_id: "Prop_039f025cdbc74ca9957dbec1b3e193c1", psp_code: "STRIPE", currency_code: "GBP", amount: 100.5, customer_email: "customer@example.com", payment_mode: "CARD", browser_info: { userAgent: "Mozilla/5.0", acceptHeader: "/", language: "en-US", colorDepth: 24, screenHeight: 1080, screenWidth: 1920, timeZoneOffset: 0 }, billing_address: { street: "221B Baker Street", city: "London", postalCode: "NW1 6XE", country: "GB", state: "Greater London" } }) } );

const data = await response.json();

EXAMPLE RESPONSE

const data = await response.json();

{

“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: Complete Payment on Frontend (Stripe Embedded Checkout)

Since the API returns:

cs_test_…

This means the Stripe Checkout Session is created.

You must use Stripe Embedded Checkout, not confirmCardPayment.

Install Stripe SDK

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

Frontend Implementation (Next.js Example)

“use client”;

import { useState } from “react”;

import { loadStripe } from “@stripe/stripe-js”;

import {

EmbeddedCheckoutProvider,

EmbeddedCheckout,

} from “@stripe/react-stripe-js”;

export default function Home() {

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

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

const createPayment = async () => {

const res = await fetch(“/api/business-payment”, {

method: “POST”,

});

const data = await res.json();

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

setClientSecret(data.data.client_secret);

};

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>

</>

);

}

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

Warning: 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:

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

Never:

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

Support

Need help?

  • Technical issues: Contact Kayana Technical Support
  • Production credentials: Request from your Kayana account manager
  • PSP configuration: Reach out to Kayana Technical Support

Next steps

  • Explore webhook integration for payment notifications
  • Learn about refunds and dispute handling
  • Set up recurring payments for subscriptions

Next Steps

If you prefer to use RYFT as your Payment Service Provider (PSP), Kayana also supports a full RYFT integration flow. Refer to our guide on Building an advanced Kayana integration with RYFT in React/Next.js.

Still need a hand?Contact support← All help