⚙️

Xpensio — SAP Entegrasyon Teknik Kılavuzu

ECC 6.0 · S/4HANA On-Premise · S/4HANA Cloud · SuccessFactors
Versiyon 2.0 · Mart 2026 · Gizlilik: Müşteri Teknik Dokümanı

📑 İçindekiler

1 Genel Mimari

1.1 Adapter Kalıbı (Factory Pattern)

Xpensio, tüm ERP/HR entegrasyonlarını Adapter Factory kalıbıyla yönetir. Ortam değişkenine (SAP_TYPE, IDENTITY_PROVIDER) göre uygun adapter otomatik seçilir:

┌─────────────────────── Xpensio Backend (NestJS) ───────────────────────┐
│                                                                         │
│  SapAdapterFactory                    IdentityAdapterFactory            │
│  ├─ ECC     → SapEccAdapter           ├─ SAP_HCM     → SapHcmAdapter   │
│  ├─ S4_ONPREM → SapS4OnPremAdapter    ├─ SAP_S4_ONPREM → S4OnPrem…     │
│  ├─ S4_CLOUD  → SapS4CloudAdapter     ├─ SAP_S4_CLOUD  → S4Cloud…      │
│  └─ MOCK      → SapMockAdapter        ├─ AZURE_AD    → AzureAdAdapter  │
│                                        ├─ LDAP        → LdapAdapter     │
│                                        └─ MOCK        → MockAdapter     │
└─────────────────────────────────────────────────────────────────────────┘

1.2 FI Posting (Masraf Muhasebeleştirme) Adapterleri

SAP_TYPEAdapterBağlantı YöntemiAuthBelge OluşturmaNot
ECC SapEccAdapter SICF REST endpoint HTTP Basic (TLS) Z-ABAP class ZCL_EXPENSE_POSTINGBAPI_ACC_DOCUMENT_POST ECC 6.0+ için tek desteklenen yol; ZEXP_S_INT_* yapıları DDIC'de tanımlı olmalı.
S4_ONPREM SapS4OnPremAdapter OData v2/v4 (Gateway) veya legacy SICF HTTP Basic / OAuth2 API_OPLACCTGDOCITEMCUBE / Z-BAPI yoluyla journal entry S/4 1909+; Gateway service aktif olmalı (SEGW). Müşteri Gateway kullanmıyorsa ECC adapter pattern'ı kullanılır.
S4_CLOUD SapS4CloudAdapter REST → A_JournalEntry Cloud API OAuth2 (XSUAA / BTP) Native Cloud SDK ile; ABAP gereksinimi yok 2402 release+; service binding üzerinden XSUAA token. F110 polling A_OperationalAcctgDoc ile.
SAP_SF_CLOUD SapSuccessFactorsAdapter SuccessFactors OData (HR only) OAuth2 (SAML Assertion) FI yok — sadece HR / Identity sync 1.3'te de listelenir; FI posting müşterinin başka bir SAP/ERP'sine yapılır.
MOCK SapMockAdapter Bellek içi simülasyon Rastgele belge no + %5 simüle hata oranı Dev / E2E test için. Belge no'nun son rakamı çift → polling'de PAID dönülür.

1.3 HR / Kimlik Sync Adapterleri

IDENTITY_PROVIDERAdapterKaynak Sistem & ProtokolAuthSync PeriyoduNot
SAP_HCM SapHcmAdapter SAP ECC HR — ABAP SICF endpoint /sap/bc/xpensio/user_list HTTP Basic / OAuth2 (ZXPENSIO_TOKEN) Her gece 01:00 PA0001 + PA0002 + HRP1000 zinciri; costCenterCode fallback chain: OPHCODE → KOSTL → COSTCENTER → RELID
SAP_S4_ONPREM SapS4OnPremAdapter (Identity) OData API_BUSINESS_PARTNER + API_DEPARTMENT HTTP Basic / OAuth2 Her gece 01:00 HR-FI ayrımı olan müşteriler için; ECC HR adapter ile karıştırma.
SAP_S4_CLOUD SapS4CloudAdapter (Identity) S/4 Cloud Identity Service (IPS / IAS) OAuth2 (XSUAA) Her gece 01:00 Genelde SuccessFactors ile birleşik kullanılır; standalone S/4 Cloud HR varsa devreye alınır.
SAP_SF_CLOUD SapSuccessFactorsAdapter SuccessFactors OData v4 — EmployeeCentral OAuth2 (SAML Assertion) Her gece 01:00 SF master HR olan müşteriler; FI başka bir adapter ile çözülür (per-org config).
AZURE_AD AzureAdAdapter Microsoft Graph API — /users + /groups OAuth2 (client_credentials, Graph scope) Her gece 01:00 Entra ID müşterileri için; grade/department extensionAttribute üzerinden veya gruplar üzerinden çözülür.
LDAP LdapAdapter LDAP / LDAPS — RFC 4511 Simple Bind (DN + password) Her gece 01:00 On-prem AD, OpenLDAP. baseDN, filter, alan eşleme adminden config.
EXTERNAL_DB ExternalDbAdapter Müşterinin doğrudan veritabanına salt-okunur view sorgusu (PostgreSQL / MSSQL / Oracle JDBC) DB user / password (encrypted) Her gece 01:00 Logo / Mikro / özel ERP'ler için. Müşteri tarafında v_xpensio_users view'i hazırlanır.
MOCK MockAdapter Bellek içi seed verisi Manuel Demo + E2E test için.
NONE NullAdapter HR sync devre dışı; kullanıcılar manuel veya Excel import ile yönetilir.

1.4 Platform Karşılaştırma Matrisi

ÖzellikSAP ECC 6.0S/4 On-PremS/4 Cloud
FI PostingBAPI_ACC_DOCUMENT_POSTBAPI compat / ODataREST Journal Entry
HR SyncABAP SICF endpointOData EmployeeEntitySuccessFactors OData v4
AuthHTTP BasicOAuth2 / BasicOAuth2 (XSUAA)
ABAP GereksinimiEvet (7.0+)Opsiyonel (7.50+)Hayır
Kurulum ZorluğuOrtaOrtaDüşük
ENV: SAP_TYPEECCS4_ONPREMS4_CLOUD

2 Ortak Referanslar

2.1 Kullanıcı / HR Alan Eşleşmesi

Xpensio DBHR Sistemi KarşılığıAçıklama
emailE-postaBirincil anahtar
nameAd + SoyadBirleştirilmiş
externalIdPERNR / EmployeeIdPersonel No
sapEmployeeIdPERNRFI kalemlerinde kullanılır
departmentCodeDEPARTMENTNO / OrgUnit→ departmentId FK
positionCodeTITLENO / PositionId→ positionId FK
gradeGRADE / PayGrade7–19 arası, onay limiti belirler
managerEmailMANAGEREMAILYönetici → managerId FK
isActive'1' / 'X' = aktifAktiflik durumu

2.2 Masraf → FI Mapping

XpensioFI KarşılığıÖrnek
netAmountNet Tutar (vergi hariç)100.00 TRY
taxAmountKDV Tutarı20.00 TRY
grossAmountBrüt Tutar120.00 TRY
expenseTypeCodeMasraf Türü → GL Hesap21 → Ulaşım GL
taxPercentageCodeVergi KoduV5 → %20
costCenterMasraf Yeri (KOSTL)10 hane
projectCodeWBS ElementiOpsiyonel

2.3 Grade → Rol Eşleştirmesi

GradeUnvan TipiAtanan Rol
17–19VP / GM / CTOMANAGER
14–16Division HeadMANAGER
13Unit HeadMANAGER
7–12Engineer / AnalystEMPLOYEE
⚠️ FINANCE ve ADMIN rolleri grade ile asla değiştirilmez. Eşik: MANAGER_GRADE_THRESHOLD = 13

2.4 Çok Seviyeli Onay Zinciri

AdımOnaylayanKoşul
1MANAGERHer zaman zorunlu
2UPPER_MANAGERTutar > çalışanın grade limiti
3CFO / ADMINTutar > 50.000 TRY
4FINANCEHer zaman zorunlu (son adım)

Grade Limit Örnekleri: G7–12 → 10.000 TRY  |  G13–15 → 25.000 TRY  |  G16–18 → 50.000 TRY

2.5 Vergi & Ödeme Kodları

Vergi KoduOranÖdeme TipiAçıklama
V0%00Nakit
V1%11Kişisel Kart
V4%102Şirket Kartı
V5%203Kurumsal Kart

3 SAP ECC 6.0 Entegrasyonu

IDENTITY_PROVIDER=SAP_HCM SAP_TYPE=ECC ABAP 7.0+

3.1 Kurulum Sırası

#AdımSAP TxAçıklama
1DDIC NesneleriSE11Tablo ve yapıları oluştur + aktive et
2ABAP SınıflarıSE24ZCL_EXPENSE_POSTING + ZCL_EXPENSE_USER_LIST
3SICF ServisleriSICFHandler ata + aktive et
4SAP KullanıcısıSU01API sistem kullanıcısı oluştur
5YetkilendirmePFCGRol + izin nesneleri ata
6İlk VerilerSM30ZEXP_AUTH + ZEXP_CFG tabloları doldur
7FI UyarlamaOBA7 / FS00 / KS01 / FTXPBelge tipi, GL, masraf yeri, vergi kodları

3.2 DDIC Nesneleri (SE11)

ZEXP_AUTH — Kimlik Doğrulama

AlanTipKeyAçıklama
MANDTCLNT 3Mandant
TYPECHAR 504=HTTP Basic, 05=Form
USERNAMECHAR 100API kullanıcı adı
PASSWORDCHAR 100API şifresi

ZEXP_POST_LOG — FI Posting Log

AlanTipAçıklama
LOGIDCHAR 36UUID (expense ID)
BUKRSBUKRS 4Şirket kodu
BELNRBELNR 10SAP FI belge no
STATUSCHAR 1S=Başarı, E=Hata
MESSAGECHAR 255SAP mesajı
RETRY_CNTINT1Deneme sayısı

ZEXP_CFG — Genel Yapılandırma

CFGKEYÖrnek DeğerAçıklama
EXPENSE_GL<GIDER_GL>Gider GL Hesabı
COUNTER_GL<KARSI_GL>Karşı Hesap
KDV_GL<KDV_GL>İndirilecek KDV
DOC_TYPESABelge Tipi

ZEXP_CFG_GL — Masraf Türü → GL Hesap Eşleşme

AlanKeyAçıklama
BUKRSŞirket kodu
SUBCOMPCODEAlt şirket kodu
EXPENSETYPECODEMasraf türü (21/22/23…)
GLACCOUNTGL hesap numarası
TAXCODEVergi kodu (V0/V1/V4/V5)

ZEXP_USERS — Kullanıcı Tablosu

AlanXpensio KarşılığıAçıklama
EMAILemail (PK)E-posta adresi
NAME / SURNAMEnameAd + soyad birleştirilir
DEPARTMENTNOdepartmentCodeDepartman kodu
TITLENOpositionCodePozisyon kodu
GRADEgradeSeviye (7–19), rol ataması
MANAGEREMAILmanagerEmailYönetici e-posta
PERSONNELCODEexternalId, sapEmployeeIdPersonel numarası
ISACTIVEisActive1=aktif, 0=pasif

ZEXP_GRADE_POLICIES — Grade / Politika Tablosu

AlanKeyAçıklama
BUKRSŞirket kodu
GRADEGrade seviyesi
POLICYCODEMasraf politikası kodu
LIMIT_AMOUNTHarcama limiti (TRY)

ZEXP_COMPANY — Şirket Yapılandırması

AlanKeyAçıklama
BUKRSŞirket kodu
COMP_NAMEŞirket adı
CURRENCYYerel para birimi
TAX_SYSTEMVergi sistemi (TR/EU)

ZEXP_S_POST_PAYLOAD — POST_EXPENSE Giriş Yapısı

COMPANYCODE (BUKRS), EMPLOYEEID (CHAR 20), EMPLOYEENAME (CHAR 100),
EXPENSEDATE (CHAR 8), POSTINGDATE (CHAR 8), DOCUMENTTYPE (BLART),
NETAMOUNT (DEC 13,2), TAXAMOUNT (DEC 13,2), GROSSAMOUNT (DEC 13,2),
TAXCODE (CHAR 2), TAXGLACCOUNT (SAKNR), CURRENCY (WAERS),
GLACCOUNT (SAKNR), COSTCENTER (KOSTL), PROJECTCODE (PS_POSID),
DESCRIPTION (CHAR 50), REFERENCE (CHAR 16), DEBUGMODE (CHAR 1)

3.3 ABAP — ZCL_EXPENSE_POSTING (FI Belge Oluşturma)

Interface: IF_HTTP_EXTENSION  |  SICF: /sap/bc/zexpense/post_expense

HANDLE_REQUEST — Ana Giriş Noktası

METHOD if_http_extension~handle_request.
  " 1. HTTP metod kontrolü (sadece POST)
  " 2. Auth doğrulama: ZEXP_AUTH → username + password
  " 3. JSON body → ZEXP_S_POST_PAYLOAD'a parse
  " 4. Zorunlu alan kontrolü (companycode, glaccount, netamount…)
  " 5. POST_EXPENSE çağır
  " 6. JSON response: { STATUS, BELNR, GJAHR, MESSAGE }
  " 7. ZEXP_POST_LOG'a loglama
ENDMETHOD.

POST_EXPENSE — BAPI Çağrısı

METHOD post_expense.
  " ── HEADER ──
  ls_header-comp_code  = is_payload-companycode.
  ls_header-doc_date   = is_payload-expensedate.
  ls_header-pstng_date = is_payload-postingdate.
  ls_header-doc_type   = is_payload-documenttype.
  ls_header-ref_doc_no = is_payload-reference.
  ls_header-currency   = is_payload-currency.
  ls_header-bus_act    = 'RFBU'.

  " ── KALEM 1: Gider GL (Borç) ──
  ls_accgl-gl_account = is_payload-glaccount.
  ls_accgl-tax_code   = is_payload-taxcode.
  ls_accgl-costcenter = is_payload-costcenter.
  ls_curr-amt_doccur  = is_payload-netamount.

  " ── KALEM 2: KDV GL (Borç, sadece KDV > 0) ──
  IF is_payload-taxamount > 0.
    ls_acctax-gl_account = is_payload-taxglaccount.
    ls_curr-amt_doccur   = is_payload-taxamount.
  ENDIF.

  " ── KALEM 3: Personel Cari (Alacak) ──
  ls_accpay-vendor    = is_payload-employeeid.
  ls_curr-amt_doccur  = - is_payload-grossamount.

  " ── BAPI ÇAĞRISI ──
  IF is_payload-debugmode = 'X'.
    CALL FUNCTION 'BAPI_ACC_DOCUMENT_CHECK' ...
  ELSE.
    CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST' ...
  ENDIF.

  " Hata kontrolü
  IF RETURN tablosunda E tipi mesaj var.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ev_status = 'E'.  ev_message = hata metni.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
    ev_status = 'S'.  ev_belnr = belge no.
  ENDIF.
ENDMETHOD.
💡 DEBUGMODE = 'X' ile BAPI_ACC_DOCUMENT_CHECK kullanılarak commit yapılmadan test edilebilir.

3.4 ABAP — ZCL_EXPENSE_USER_LIST (HR Sync)

SICF: /sap/bc/zexpense/user_list

METHOD if_http_extension~handle_request.
  " ── Auth kontrolü (ZEXP_AUTH) ──
  " GET /           → ZEXP_USERS tablosundan JSON döndür
  " GET ?action=SYNC → PA0001/PA0002'den çekip ZEXP_USERS güncelle
  "   - Mevcut kayıt: UPDATE
  "   - Yeni kayıt:   INSERT
  "   - HR'da yok:    ISACTIVE = '0'
  " JSON Response: { EMPLOYEE_COUNT, SYNCED, INSERTED, DEACTIVATED }
ENDMETHOD.
⚠️ ABAP 7.0 uyumluluğu: &&, inline DATA(), string templates kullanılmaz.

3.5 SICF Servisleri

Transaction: SICF → /sap/bc/zexpense/
  /post_expense  → Handler: ZCL_EXPENSE_POSTING
  /user_list     → Handler: ZCL_EXPENSE_USER_LIST
  Authentication: HTTP Basic (SAP standart)

3.6 Kullanıcı & Yetkilendirme

SU01 — Sistem Kullanıcısı

ParametreDeğer
Kullanıcı AdıZEXP_API_USER
Kullanıcı TipiSystem (Dialog değil)
RolZ_EXPENSE_API_ROLE

PFCG — Yetkilendirme Nesneleri

NesneAlanDeğer
S_TCODETCDSE16, SM30
S_TABU_DISTABLEZEXP_*
S_ICFICFSERVICE/sap/bc/zexpense/*
F_BKPF_BUKBUKRS<Şirket Kodu>
F_BKPF_KOAKOARTA, D, G, K, M, S

3.7 FI Uyarlamalar

TxİşlemDetay
OBA7Belge TipiSA veya özel ZK
FS00GL HesaplarGider GL, Karşı Hesap, KDV GL
KS01Masraf YeriEn az 1 aktif masraf yeri zorunlu
FTXPVergi KodlarıV0=%0, V1=%1, V4=%10, V5=%20
MK01/FK01VendorPersonel → Vendor eşleşmesi

3.8 Bağlantı Yapılandırması (DB Encrypted)

💡 SAP bağlantı bilgileri .env dosyasında tutulmaz. Tüm credential'lar Xpensio Setup Wizard veya Admin Panel üzerinden girilir ve veritabanında AES-256-GCM ile şifrelenerek Organization.erpConfig alanında saklanır. Şifreler API'den okunurken otomatik maskelenir (••••••••).

Admin Panel → ERP Ayarları

AlanÖrnek DeğerAçıklama
erpTypeECCSAP platform tipi
sapBaseUrlhttp://<SAP_HOST>:<PORT>SICF base URL
sapUsername<API_KULLANICI>SICF kullanıcı adı
sapPassword<API_SIFRESI>🔒 AES-256-GCM encrypted
sapClient<CLIENT_NO>SAP mandant
sapCompanyCode<BUKRS>Şirket kodu

Minimal .env (Sadece sistem seviyesi)

# Sadece şifreleme anahtarı .env'de tutulur
ENCRYPTION_KEY=<64_HEX_KARAKTER>   # 32-byte AES key
⚠️ ENCRYPTION_KEY production'da Docker Secret veya K8s Secret olarak yönetilmelidir. SAP kullanıcı adı/şifresi kesinlikle .env'de tutulmamalıdır.

3.9 Test Prosedürü

A) SAP Tarafı Test (SE38)

REPORT ZTEST_EXPENSE_POST.
" 1. ZEXP_S_POST_PAYLOAD yapısını doldur
" 2. DEBUGMODE = 'X' ile BAPI_ACC_DOCUMENT_CHECK çağır
" 3. RETURN tablosunu kontrol et → hata yoksa DEBUGMODE = '' ile tekrarla
" 4. BELNR alındı → FB03 ile belgeyi doğrula

B) REST Client Testi

curl -X POST http://<SAP_HOST>:<PORT>/sap/bc/zexpense/post_expense \
  -H "Content-Type: application/json" \
  -u "<USER>:<PASS>" \
  -d '{
    "COMPANYCODE":"<BUKRS>","EMPLOYEEID":"<VENDOR_NO>",
    "EXPENSEDATE":"20260324","POSTINGDATE":"20260324",
    "DOCUMENTTYPE":"SA","NETAMOUNT":100,"TAXAMOUNT":0,
    "GROSSAMOUNT":100,"TAXCODE":"V0","CURRENCY":"TRY",
    "GLACCOUNT":"<GL>","COSTCENTER":"<KY>",
    "DESCRIPTION":"Test","REFERENCE":"TEST-001","DEBUGMODE":"X"
  }'

C) Xpensio Uçtan Uca Test

  1. POST /api/v1/identity/sync → Kullanıcılar SAP'den çekildi
  2. Dashboard → Yeni masraf oluştur → Onayla
  3. Muhasebe → SAP'ye Gönder → Durum: POSTED_TO_SAP
  4. SAP FB03 ile belge numarasını doğrula

3.10 Kurulum Kontrol Listesi

SAP Tarafı

Xpensio Tarafı

4 S/4HANA On-Premise

IDENTITY_PROVIDER=SAP_S4_ONPREM SAP_TYPE=S4_ONPREM ABAP 7.50+

4.1 ECC ile Temel Farklar

ÖzellikECC 6.0S/4HANA On-Prem
MuhasebeKlasik FI (BKPF/BSEG)Universal Journal (ACDOCA)
ABAP7.0+ (eski syntax)7.50+ (inline DATA, string templates)
FI PostingBAPI_ACC_DOCUMENT_POSTBAPI compat veya OData v4
HR SyncCustom ABAPOData EmployeeEntity veya HCM compat
Silinen TablolarBSEG, BSIS, BSAS…Compatibility view olarak mevcut
💡 S/4HANA Universal Journal (ACDOCA), tüm FI/CO/ML/AA girişlerini tek tabloda birleştirir. Xpensio BAPI'si bu katmanın üzerinde çalışır.

4.2 FI Posting Yaklaşımları

Yaklaşım A — BAPI Compat (Önerilen, En Hızlı Kurulum)

S/4HANA BAPI_ACC_DOCUMENT_POST'u desteklemeye devam eder. Bölüm 3.23.7'deki ECC ABAP kodu ve DDIC nesneleri birebir çalışır. Tek değişiklik:

SAP_TYPE=S4_ONPREM   # (ECC yerine)

Yaklaşım B — OData v4 Journal Entry API

ABAP geliştirme yapmadan doğrudan S/4HANA standart OData servisi kullanılır:

POST /sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV/JournalEntryItem
Authorization: Basic <base64>
Content-Type: application/json

{
  "CompanyCode": "<BUKRS>",
  "PostingDate": "2026-03-24",
  "JournalEntryType": "SA",
  "to_JournalEntryItem": {
    "results": [
      { "GLAccount": "<GIDER_GL>", "DebitCreditCode": "S",
        "AmountInTransactionCurrency": "100.00", "CostCenter": "<KY>" },
      { "GLAccount": "<KARSI_GL>", "DebitCreditCode": "H",
        "AmountInTransactionCurrency": "120.00" }
    ]
  }
}
⚠️ OData yaklaşımı için /IWFND/MAINT_SERVICE'de servis aktive edilmeli + x-csrf-token yönetimi gerekli.

4.3 HR / Kimlik Sync

Seçenek A — HCM Compat: HCM modülü mevcutsa → Bölüm 3.4'teki ABAP user_list aynen uygulanır.

Seçenek B — OData EmployeeEntity:

GET /sap/opu/odata/sap/HCMFAB_EMPLOYEE_SRV/EmployeeCollection
  ?$select=EmployeeId,FirstName,LastName,EmailAddress,
           OrganizationalUnit,Position,Grade
  &$filter=IsActive eq true

Bu yaklaşımda ABAP geliştirme gerekmez; IDENTITY_PROVIDER=SAP_S4_ONPREM ile otomatik seçilir.

4.4 Bağlantı Yapılandırması (DB Encrypted)

Bölüm 3.8'deki yapı aynen geçerlidir. Admin Panel → ERP Ayarları:

AlanÖrnek DeğerAçıklama
erpTypeS4_ONPREMPlatform tipi
sapBaseUrlhttps://<S4_HOST>:<PORT>S/4 base URL
sapUsername<API_KULLANICI>SICF veya OData kullanıcısı
sapPassword<API_SIFRESI>🔒 AES-256-GCM encrypted
sapClient<CLIENT_NO>SAP mandant
sapCompanyCode<BUKRS>Şirket kodu
odataServicePath/sap/opu/odata/sap/API_JOURNAL…OData yaklaşımında ek path

4.5 Kontrol Listesi

5 S/4HANA Cloud + SuccessFactors

IDENTITY_PROVIDER=SAP_S4_CLOUD SAP_TYPE=S4_CLOUD ABAP Gerekmez

5.1 OAuth 2.0 Kurulumu (XSUAA / BTP)

  1. BTP Cockpit → Subaccount → Service Marketplace → S/4HANA Cloud aboneliği
  2. Service Instance oluştur → clientid ve clientsecret al
  3. Scope'lara Journal Entry API erişimi ekle

Token Endpoint

POST https://<XSUAA>.authentication.<REGION>.hana.ondemand.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=<CLIENT_ID>
&client_secret=<CLIENT_SECRET>
💡 Token süresi genellikle 1800sn (30dk). Xpensio expire öncesi otomatik yeniler.

5.2 FI Posting — Journal Entry API

Adım 1: CSRF Token Al

GET /sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV/$metadata
Authorization: Bearer <TOKEN>
x-csrf-token: Fetch

→ Response Header: x-csrf-token: <CSRF_VALUE>

Adım 2: Journal Entry Oluştur

POST /sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV/JournalEntryItem
Authorization: Bearer <TOKEN>
x-csrf-token: <CSRF_VALUE>
Content-Type: application/json

{
  "CompanyCode": "<BUKRS>",
  "AccountingDocumentType": "SA",
  "DocumentReferenceID": "<EXPENSE_ID>",
  "PostingDate": "2026-03-24",
  "to_JournalEntryItem": {
    "results": [
      { "GLAccount": "<GIDER_GL>", "DebitCreditCode": "S",
        "AmountInTransactionCurrency": "100.00",
        "CostCenter": "<KY>", "TaxCode": "V5" },
      { "GLAccount": "<KARSI_GL>", "DebitCreditCode": "H",
        "AmountInTransactionCurrency": "120.00",
        "Vendor": "<TEDARIKCI_NO>" }
    ]
  }
}

5.3 HR Sync — SuccessFactors Employee Central API

SuccessFactors OAuth 2.0

POST https://<SF_HOST>/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=<SF_CLIENT_ID>
&client_secret=<SF_CLIENT_SECRET>
&company_id=<SF_COMPANY_ID>

Çalışan Listesi

GET https://<SF_HOST>/odata/v4/sfsf/User
  ?$select=userId,firstName,lastName,email,department,
           jobTitle,managerId,payGrade
  &$filter=status eq 'active'
  &$top=1000
Authorization: Bearer <SF_TOKEN>

Departman Listesi

GET https://<SF_HOST>/odata/v4/sfsf/FODepartment
  ?$select=departmentId,name,headOfUnit,parentUnit
  &$filter=effectiveStatus eq 'A'

Pozisyon Listesi

GET https://<SF_HOST>/odata/v4/sfsf/Position
  ?$select=positionCode,externalName,payGrade
  &$filter=effectiveStatus eq 'A'

5.4 SuccessFactors → Xpensio Alan Eşleşmesi

SF OData AlanıXpensio DBNot
userIdexternalIdSF kullanıcı ID
emailemailPK — eşleşme anahtarı
firstName + lastNamenameBirleştirilir
departmentdepartmentCode→ departmentId FK
jobTitle / positionjobTitleUnvan
managerId → email resolvemanagerEmail2. sorgu ile resolve
payGradegradeSayısal (7–19)
status='active'isActive=true

5.5 Bağlantı Yapılandırması (DB Encrypted)

Bölüm 3.8'deki yapı aynen geçerlidir. Admin Panel → ERP Ayarları:

AlanÖrnek DeğerAçıklama
erpTypeS4_CLOUDPlatform tipi
s4CloudBaseUrlhttps://<S4CLOUD_HOST>S/4 Cloud API base
s4CloudTokenUrlhttps://<XSUAA>.authentication…XSUAA token endpoint
s4CloudClientId<CLIENT_ID>OAuth2 client
s4CloudClientSecret<CLIENT_SECRET>🔒 AES-256-GCM encrypted
sapCompanyCode<BUKRS>Şirket kodu
sfBaseUrlhttps://<SF_HOST>/odata/v4/sfsfSuccessFactors OData
sfTokenUrlhttps://<SF_HOST>/oauth/tokenSF OAuth2 token
sfClientId<SF_CLIENT_ID>SF OAuth2 client
sfClientSecret<SF_CLIENT_SECRET>🔒 AES-256-GCM encrypted
sfCompanyId<SF_COMPANY_ID>SF şirket ID

5.6 Kontrol Listesi

SAP BTP / S/4HANA Cloud

SuccessFactors

Xpensio

5b Kurumsal Kart Mutabakatı & UMSKZ Akışı

Xpensio, kurumsal kredi kartı ekstresini içeri alarak satırları masraf kayıtlarıyla otomatik eşler ve eşleşmiş satırları mevcut SAP FI Push akışına teslim eder. Banka tarafına ek bir RFC veya web servisi gerekmez — eşleşmiş kayıtlar BAPI_ACC_DOCUMENT_POST üzerinden standart yolla post edilir.

5b.1 Muhasebe Yansıması (UMSKZ Eşlemesi)

Kart TipiÖdeme YöntemiUMSKZSAP HesapAçıklama
CORPORATE (Şirket KK)3 — Kurumsal KartO309 — Şirket KKBorç: Gider GL · Alacak: 309 (Banka tarafından kesilen kurumsal kart)
PERSONAL (Şahsi Kart)1 — Şahsi KartI195 — İş AvansıBorç: Gider GL · Alacak: 195 (Personel iadesi sonrası kapanır)
NAKİT0 — NakitNBorç: Gider GL · Alacak: 100 Kasa
📌 ZEXP_CFG_02 tablosundaki UMSKZ kodları ile birebir uyumludur. 0=N · 1=O · 2=I · 3=N

5b.2 İş Akışı

  1. Ekstre import: Banka CSV/PDF/Excel dosyası Finance tarafından yüklenir. Parser tarih/tutar/merchant/currency çıkarır, satırlar UNMATCHED olarak kayıt edilir.
  2. Auto-match: Skor algoritması (tarih ±2 gün, tutar ±%0.5–2 FX, merchant fuzzy, fatura/VKN bonus) ≥ 80 olan satırları masrafa bağlar.
  3. Manuel + bölme: Kalan satırlar Finance tarafından elle bağlanır veya N parçaya bölünür.
  4. SAP Push: Bağlanmış masraf zaten standart onay zincirini geçmişse mevcut SAP FI Push pipeline'ı tetiklenir; UMSKZ kart tipinden türetilir.

5b.3 Tenant Başına Banka Şablonu

Müşterinin kullandığı banka standart Garanti/İş/Akbank parserlarımızdan farklıysa, admin "CSV Şablonları" sekmesinden kolon eşleştirmesi tanımlar:

Yükleme dropdown'unda "Özel: {şablon adı}" olarak görünür ve seçilince bankFormat=custom:NAME olarak iletilir.

5b.4 Çok Döviz

USD/EUR/GBP harcamalar canlı kurla TRY karşılığına çevrilerek karşılaştırılır. Cross-currency tolerans %2 (TRY/TRY için %0.5). Kur kaynağı: FxRateService — open.er-api.com (1 saatlik cache + admin manuel override).

6 Güvenlik & Ağ Gereksinimleri

6.1 Ağ & Firewall

KaynakHedefPortProtokol
Xpensio BackendSAP ECC/S4 SICF8000/44300HTTPS
Xpensio BackendS/4 Cloud API443HTTPS (OAuth2)
Xpensio BackendSuccessFactors API443HTTPS (OAuth2)
Xpensio BackendBTP XSUAA Token443HTTPS
✅ SAP/ERP sunucusu ile Xpensio backend arasında VPN veya özel ağ (private link) bağlantısı önerilir.

6.2 Kimlik Bilgileri Yönetimi — erpConfig AES-256-GCM

Şifreleme Akışı

AdımDetay
Algoritmaaes-256-gcm (Node.js crypto modülü — authenticated encryption)
AnahtarENCRYPTION_KEY env var — 32 byte (64 hex karakter). openssl rand -hex 32 ile üretilir.
IVHer şifrelemede yeniden üretilen 12 byte random IV (NIST SP 800-38D önerisi)
Auth Tag16 byte — şifrelemenin bütünlüğünü doğrular (tampering korunması)
Saklama Formatıv1:<iv-hex>:<authtag-hex>:<ciphertext-hex> — versiyon prefix'i ileride rotasyon için
EncodeJSON.stringify(config) → utf-8 → AES-GCM → hex; ters yönde JSON.parse
ScopeSadece Organization.erpConfig kolonunda. Diğer DB kolonları (email, password hash vb.) ayrı mekanizmalarla korunur.
⚠️ Anahtar Kaybı Felaketi: ENCRYPTION_KEY kaybedilirse hiçbir tenant'ın SAP yapılandırması okunamaz. Backup & restore akışlarında bu değer DB dump ile birlikte güvenli kasada (vault) tutulmalı. Anahtar rotasyonu manuel iştir: eski anahtar ile decrypt → yeni anahtar ile re-encrypt → versiyon prefix güncellenir.

Şifrelenen Alanlar (örnek erpConfig payload)

{
  "sapType": "S4_ONPREM",
  "baseUrl": "https://sap.musteri.com:44300",
  "username": "XPENSIO_API",
  "password": "•••••••• (encrypted at rest)",
  "clientSecret": "•••••••• (encrypted at rest)",
  "client": "100",
  "language": "TR",
  "ca": "-----BEGIN CERTIFICATE----- ... (encrypted at rest)",
  "glConfig": {
    "byCompany": {
      "1000": {
        "expenseGl": "770000",
        "taxGl": "190000",
        "expenseCostCenter": "10001",
        "paymentConfig": { "umskz": "0", "payableGl": "335000" }
      }
    }
  }
}

Güvenlik Kontrolleri

6.3 SAP Tarafı Güvenlik

§7. 2026 SAP Yenilikleri (Mayıs Sürümü)

Bu bölüm canlı kodda son sprint'te (Mayıs 2026) eklenen SAP entegrasyonuyla ilgili yenilikleri özetler.

7.1 Per-Org SAP Adapter

Her organizasyon kendi Organization.erpConfig + adapter instance'ı ile çalışır. Multi-tenant izolasyonu tam — bir müşterinin SAP credential'ları başka bir müşterinin sorgularında kullanılamaz. SapAdapterFactory her request'te orgId üzerinden adapter çözümler.

7.2 KKEG Otomatik Split (7194)

Personel araç giderleri ve diğer kanunen kabul edilmeyen giderler hem PUSH hem PULL akışında otomatik ayrıştırılır. gl_kkeg_mappings tablosu (/admin/gl-kkeg-mappings) ile yönetilir. SAP FI'ya KKEGGLACCOUNT ve KKEGTAXGLACCOUNT alanları doğru hesaplara düşer.

7.3 F110 Ödeme Polling

Günlük 09:00 cron payment-polling.service.ts üzerinden F110 raporu çekilir, POSTED_TO_SAP statüsündeki masraflar eşleştirilir, ödenenler PAID statüsüne geçer. Çalışan mobil/web'de canlı görür.

7.4 Per-User Cost Center Whitelist

Yeni UserCostCenterAccess M2M tablosu. resolveAllowedCostCenters async resolver: EMPLOYEE/MANAGER kendi RELID + whitelist; FINANCE/ADMIN whitelist boşsa serbest, doluysa kısıtlı. Yetkisiz CC seçimi 403 döner. Admin panel: /admin/users modal → "Yetkili Masraf Yerleri" çoklu seçim.

7.5 Mükerrer Fiş VKN Kontrolü

expenses.service.ts create akışında receiptNumber + merchantTaxId çifti unique check'i. Aynı fiş + aynı satıcı VKN ile ikinci masraf 400 BadRequest döner.

7.6 GL Bakım Modülleri

İki ayrı admin ekranı: /admin/gl-mappings (standart GL eşleştirmeleri) ve /admin/gl-kkeg-mappings (KKEG split kuralları). Her ikisi de Excel ile toplu içe aktarma destekler. computeKkegSplit servis fonksiyonu personel araç giderini Personel + KKEG hesabı olarak ikiye böler.


Xpensio SAP Entegrasyon Teknik Kılavuzu v2.1 — Mayıs 2026