Entegrasyonlar
Node.js

Node.js SDK

@lunixi/node-sdk, Lunixi REST API'si üzerinde ince bir sunucu tarafı sarmalayıcıdır. Ed25519 istek imzalamayı, token'ın önbellekte tutulup süresi dolunca yenilenmesini ve yanıt zarfının çözülmesini sizin yerinize yapar. Çerçeveden bağımsızdır; Express, Fastify, NestJS, Hapi, sunucusuz fonksiyonlar ve düz Node.js ile çalışır.

Kurulum

npm install @lunixi/node-sdk

Node.js 18 ve üzeri gerekir. TypeScript tip tanımları pakete dahildir.

İstemciyi oluşturma

const { LunixiClient } = require('@lunixi/node-sdk');
 
const lunixi = new LunixiClient({
  baseUrl: 'https://api-gateway.lunixi.com',
  keyId: process.env.LUNIXI_KEY_ID,
  privateKey: process.env.LUNIXI_PRIVATE_KEY_PEM,
});
SeçenekZorunluVarsayılan
baseUrlevet—
keyIdevet—
privateKeyevet—
timeoutMshayır30000
maxRetrieshayır2

Ortamı anahtar belirler: TEST anahtarıyla (mk_test_…) yapılan çağrılar test ortamına gider; ayrı bir ortam seçeneği yoktur.

İstemciyi uygulama açılışında bir kez oluşturup paylaşın. Token önbelleği bu nesnede durur; her istekte yeni istemci oluşturmak her istekte yeni token almak demektir.

Anahtar çifti

Anahtar çiftini SDK ile üretebilirsiniz:

const { publicKey, privateKey } = LunixiClient.generateKeyPair();

Public anahtarı panele kaydedin; özel anahtar yalnız kendi sunucunuzda kalır. → Kimlik Doğrulama

Kapsam

ÜrünErişim
Ödemelerlunixi.payments
Ödeme linklerilunixi.paymentLinks
Fraud kararları ve olaylarlunixi.fraud
Cüzdanlunixi.wallet
Banka hesaplarılunixi.bankConnect
Sanction taramasılunixi.sanction
Referans veriler (adres kodları)lunixi.reference
Sigortalunixi.insurance
Webhook imza doğrulamaWebhookVerifier

Abonelik, KYC, marketplace ve identity uçları Node.js SDK'sında yoktur; bunlar için PHP SDK'sını ya da SDK'sız REST akışını kullanın.

Express ile ödeme başlatma

SDK'nın Express bağımlılığı yoktur; aşağıdaki örnek yalnız kullanım biçimini gösterir.

const express = require('express');
const {
  LunixiClient,
  CreateIntentRequest,
  Buyer,
  Address,
  BasketItem,
} = require('@lunixi/node-sdk');
 
const lunixi = new LunixiClient({
  baseUrl: process.env.LUNIXI_BASE_URL,
  keyId: process.env.LUNIXI_KEY_ID,
  privateKey: process.env.LUNIXI_PRIVATE_KEY,
});
 
const app = express();
app.use(express.json());
 
app.post('/checkout', async (req, res, next) => {
  try {
    const request = new CreateIntentRequest(10050, 'TRY', `ORD-${Date.now()}`)
      .withCallbackUrl('https://merchant.example/payment/callback')
      .withBuyer(new Buyer({
        name: 'Ada',
        surname: 'Yilmaz',
        identityNumber: '11111111111',
        email: '[email protected]',
        gsmNumber: '+905350000000',
        city: 'Istanbul',
        country: 'Turkey',
        zipCode: '34000',
        ip: req.ip,
      }))
      .withBillingAddress(new Address({
        address: 'Example Street 1',
        zipCode: '34000',
        contactName: 'Ada Yilmaz',
        city: 'Istanbul',
        country: 'Turkey',
      }))
      .withBasketItems([
        new BasketItem({
          id: 'SKU-001',
          price: 10050,
          name: 'Demo Product',
          category1: 'Demo',
          itemType: BasketItem.TYPE_PHYSICAL,
        }),
      ]);
 
    const intent = await lunixi.payments.createIntent(request, `checkout:${request.toJSON().orderId}`);
    res.json(intent);
  } catch (error) {
    next(error);
  }
});

amount (ilk argüman) para biriminin en küçük biriminde tam sayıdır (10050 = 100,50 TRY); sepet kalemlerinin price toplamı amount'a eşit olmalıdır. → Checkout Form

NestJS ile kullanım

Tek bir LunixiClient sağlayıcısı oluşturup servislerinize enjekte edin:

import { DynamicModule, Global, Module } from '@nestjs/common';
import { LunixiClient, LunixiClientOptions } from '@lunixi/node-sdk';
 
export const LUNIXI_CLIENT = Symbol('LUNIXI_CLIENT');
 
@Global()
@Module({})
export class LunixiModule {
  static forRoot(options: LunixiClientOptions): DynamicModule {
    return {
      module: LunixiModule,
      providers: [{ provide: LUNIXI_CLIENT, useValue: new LunixiClient(options) }],
      exports: [LUNIXI_CLIENT],
    };
  }
}
import { Inject, Injectable } from '@nestjs/common';
import { CreateIntentRequest, LunixiClient } from '@lunixi/node-sdk';
import { LUNIXI_CLIENT } from './lunixi.module';
 
@Injectable()
export class MerchantPaymentsService {
  constructor(@Inject(LUNIXI_CLIENT) private readonly lunixi: LunixiClient) {}
 
  createCheckoutIntent(input: { orderId: string; amount: number }) {
    const request = new CreateIntentRequest(input.amount, 'TRY', input.orderId)
      .withCallbackUrl('https://merchant.example/payments/callback');
 
    return this.lunixi.payments.createIntent(request, `checkout:${input.orderId}`);
  }
 
  capture(paymentId: string) {
    return this.lunixi.payments.capture(paymentId, null, `capture:${paymentId}`);
  }
}

LunixiModule.forRoot({ baseUrl, keyId, privateKey }) çağrısını uygulama modülünüze ekleyin. Gerçek bir ödemede alıcı, fatura adresi ve sepet kalemlerini de gönderin (yukarıdaki Express örneğindeki gibi).

Webhook doğrulama

İmza, gelen gövdenin ham baytları üzerinden hesaplanır. Gövdeyi JSON ara katmanı dokunmadan, ham hâliyle doğrulayın:

const express = require('express');
const { WebhookVerifier } = require('@lunixi/node-sdk');
 
const verifier = new WebhookVerifier(process.env.LUNIXI_WEBHOOK_SECRET);
const app = express();
 
app.post('/webhooks/lunixi', express.raw({ type: '*/*' }), (req, res) => {
  let event;
  try {
    event = verifier.verify(req.body, req.headers);
  } catch {
    res.status(400).send('invalid signature');
    return;
  }
 
  // event.id ile tekrarları ayıklayın; teslimat en az bir kezdir.
  switch (event.type) {
    case 'payment.captured':
      break;
    case 'payment.failed':
      break;
  }
 
  res.status(200).send('ok');
});

Doğrulama varsayılan olarak 300 saniyelik zaman damgası penceresini de denetler (new WebhookVerifier(secret, { toleranceSeconds })). → Webhook'lar

Idempotency

Para hareket ettiren çağrılar sabit bir idempotency anahtarı ister: capture, refund, void, directMethodPayment, storeCard, deactivateStoredCard, paymentLinks.create, paymentLinks.send ve bir şey oluşturan ya da para hareket ettiren wallet.* çağrıları. İşlem başına belirlenimci bir anahtar kullanın ve aynı işlemi yeniden denerken aynı anahtarı gönderin.

Ödeme yöntemleri, parçalı ödeme, ödeme linkleri, cüzdan, banka hesapları, sigorta ve sanction çağrılarının ayrıntısı ilgili ürün sayfalarındadır; oradaki Node.js örnekleri bu SDK'yı kullanır.

İlgili