@light-stack/yookassa-payments
v1.3.0
Published
Readme
@light-stack/yookassa-payments
Browser helpers and a small server module for YooKassa payments.
| Mode | YooKassa scenario | Client (runYookassaIntegration) | Server (createYookassaPaymentSession) |
|------|-------------------|-----------------------------------|----------------------------------------|
| smart | Smart payment | Redirect | confirmation.type = redirect |
| widget | Checkout widget | Embed widget | confirmation.type = embedded |
| direct | Manual integration | Redirect to fixed method | payment_method_data.type + redirect |
For React apps, use @light-stack/yookassa-payments-react and the useYookassaPayment hook.
Install
npm install @light-stack/yookassa-paymentspnpm add @light-stack/yookassa-paymentsyarn add @light-stack/yookassa-paymentsServer — create a payment session
Import from @light-stack/yookassa-payments/server (Node, Deno, Cloudflare Workers, Supabase Edge, any HTTP handler):
import { createYookassaPaymentSession } from '@light-stack/yookassa-payments/server';
const session = await createYookassaPaymentSession(
{ shopId: process.env.YOOKASSA_SHOP_ID!, secretKey: process.env.YOOKASSA_SECRET_KEY! },
{
integration: 'direct',
paymentMethod: 'sbp',
amount: '100.00',
returnUrl: 'https://example.com/thanks',
},
);
// { paymentId, confirmationUrl }Never expose secretKey to the client.
API route (Node / Next.js / etc.)
import { createYookassaPaymentSession } from '@light-stack/yookassa-payments/server';
export async function POST(request: Request) {
const input = await request.json();
const session = await createYookassaPaymentSession(
{
shopId: process.env.YOOKASSA_SHOP_ID!,
secretKey: process.env.YOOKASSA_SECRET_KEY!,
},
input,
);
return Response.json(session);
}Supabase Edge Function
import { createYookassaPaymentSession } from '@light-stack/yookassa-payments/server';
Deno.serve(async (req) => {
const input = await req.json();
const session = await createYookassaPaymentSession(
{
shopId: Deno.env.get('YOOKASSA_SHOP_ID')!,
secretKey: Deno.env.get('YOOKASSA_SECRET_KEY')!,
},
input,
);
return Response.json(session);
});Client — run the integration
import { runYookassaIntegration } from '@light-stack/yookassa-payments';
await runYookassaIntegration({
integration: 'smart',
createPayment: async () => {
const res = await fetch('/api/payments', {
method: 'POST',
body: JSON.stringify({ integration: 'smart', amount: '100.00', returnUrl: '…' }),
});
return res.json();
},
});Reuse order fields (amount, return URL) with bindCreatePayment:
import { bindCreatePayment, runYookassaIntegration } from '@light-stack/yookassa-payments';
await runYookassaIntegration({
integration: 'direct',
paymentMethod: 'sbp',
createPayment: bindCreatePayment(
async (input) => {
const res = await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(input),
});
return res.json();
},
{
amount: '100.00',
returnUrl: 'https://example.com/thanks',
receipt: {
customer: { email: '[email protected]' },
items: [
{
description: 'Order item',
quantity: 1,
amount: { value: '100.00', currency: 'RUB' },
vat_code: 1,
payment_mode: 'full_payment',
payment_subject: 'service',
},
],
internet: 'true',
},
},
),
});If the shop has 54-FZ fiscalization, YooKassa rejects payments without receipt.
API
| Export | Import path | Description |
|--------|-------------|-------------|
| createYookassaPaymentSession | @light-stack/yookassa-payments/server | POST to YooKassa API, return PaymentSession |
| bindCreatePayment | @light-stack/yookassa-payments | Merge order defaults into createPayment requests |
| runYookassaIntegration | @light-stack/yookassa-payments | Browser redirect / widget flow |
| loadCheckoutWidget / createCheckoutWidget | @light-stack/yookassa-payments | Widget script |
Types
type PaymentSession = {
paymentId: string;
confirmationUrl?: string; // smart / direct
confirmationToken?: string; // widget
};
type CreateYookassaPaymentOrder = {
amount: string; // required, e.g. "100.00"
currency?: string; // default RUB
description?: string;
returnUrl?: string; // smart / direct redirect
locale?: 'ru_RU' | 'en_US'; // widget / redirect UI language
capture?: boolean; // default true
savePaymentMethod?: boolean;
metadata?: Record<string, string | number | boolean | null>;
merchantCustomerId?: string;
receipt?: YookassaReceipt; // 54-FZ — required if fiscalization is on
clientIp?: string;
paymentMethodId?: string; // recurring with saved method
};
type YookassaReceipt = {
customer?: { email?: string; phone?: string; full_name?: string; inn?: string };
items: Array<{
description: string;
quantity: number | string;
amount: { value: string; currency: string };
vat_code: number;
payment_mode?: 'full_payment' | 'full_prepayment' | string;
payment_subject?: 'commodity' | 'service' | string;
}>;
internet?: 'true' | 'false' | boolean;
};Pass order fields via bindCreatePayment, hook order, or directly to createYookassaPaymentSession.
License
MIT
