Skip to main content

Moka United sanal POS API'si icin Python istemcisi

Project description

moka-python

Moka United sanal POS API'si icin Python istemcisi.

Bu kutuphane, Moka United API servislerine Python uygulamalarindan erisim saglar. Resmi PHP istemcisindeki (moka-php) tum servisleri ve istek modellerini birebir kapsar. Harici hicbir bagimliligi yoktur; yalnizca Python standart kutuphanesini kullanir.

Ozellikler

  • 3D Secure olmadan odeme (Non-3D)
  • 3D Secure ile odeme
  • 3D Secure ile mobil odeme
  • On provizyon ve capture islemi
  • Havuz odemesi onaylama ve onay iptali
  • Odeme iptali (void) ve iade talebi
  • Odeme guncelleme
  • Odeme linki olusturma (odeme istegi gonderme)
  • Odeme listesi, transaction listesi ve odeme detay sorgulama
  • Bin sorgulama, taksit tablosu ve karttan cekilecek tutar hesaplama
  • Kart saklama servisleri (kart ekleme, guncelleme, silme, listeleme)
  • Musteri yonetimi servisleri
  • Tekrarlayan odeme servisleri (satis, takvim, odeme plani, urun)
  • Bayi bilgisi, muhasebe ve ekstre raporlari
  • CheckKey uretimi ve 3D Secure hash dogrulamasi
  • Moka United test kartlari ve banka hata kodlari sozlugu

Gereksinimler

  • Python 3.8 ve uzeri

Kurulum

pip install moka-python

Kaynak koddan kurulum:

cd moka-python
pip install .

Ortam Adresleri

Ortam Adres
Test ortami https://service.refmokaunited.com
Canli ortam https://service.mokaunited.com

Istemci varsayilan olarak canli ortama baglanir. Test ortami icin base_url parametresi verilmelidir. Eski service.moka.com ve service.refmoka.com adresleri icin LEGACY_API_BASE ve LEGACY_TEST_API_BASE sabitleri de mevcuttur.

Moka United servisleri PCI-DSS kurallari geregi yalnizca TLS 1.2 ve ustu protokollere izin verir. Bu kutuphanenin HTTP katmani TLS 1.2 zorunlulugunu otomatik olarak uygular.

Hizli Baslangic

from moka import MokaClient, TEST_API_BASE, models

client = MokaClient(
    dealer_code="bayi kodunuz",
    username="api kullanici adiniz",
    password="api sifreniz",
    base_url=TEST_API_BASE,  # canli ortam icin bu satiri kaldirin
)

Kimlik dogrulamada kullanilan CheckKey degeri (DealerCode + "MK" + Username + "PD" + Password bilgisinin SHA-256 ozeti) her istekte otomatik olarak uretilir ve eklenir.

Alan adlari

Istek modelleri, Moka United dokumantasyonundaki alan adlariyla (PascalCase) birebir ayni alanlari tasir. Alanlar hem API'deki adiyla hem de Python uslubundaki snake_case adiyla kullanilabilir:

istek = models.CreatePaymentRequest(CardNumber="...", Amount=10)
istek.card_holder_full_name = "Ali Yilmaz"   # snake_case
istek.ClientIP = "192.168.1.116"             # PascalCase

Yanit nesnesi

Tum servisler ApiResponse nesnesi dondurur:

Alan Aciklama
data Istek basarili ise servis verisi (dict), aksi halde None
result_code Basarili istekte "Success", hatada Moka hata kodu
result_message Hataya iliskin varsa aciklama
exception Beklenmeyen hata olustugunda (EX) aciklama
is_success Istek Moka United tarafinda islendiyse True
is_payment_successful Istek ve banka islemi birlikte basariliysa True

Onemli: is_success yalnizca istegin Moka United tarafinda islendigini gosterir. Odeme islemlerinde bankanin islemi onaylayip onaylamadigini gormek icin is_payment_successful ozelligi veya data["IsSuccessful"] alani kontrol edilmelidir.

Odeme Islemleri

3D Secure Olmadan Odeme (Non-3D)

from moka import models

istek = models.CreatePaymentRequest(
    CardHolderFullName="Ali Yilmaz",
    CardNumber="5127541122223332",
    ExpMonth="12",
    ExpYear="2030",
    CvcNumber="000",
    Amount=0.01,
    Currency="TL",
    InstallmentNumber=1,
    ClientIP="192.168.1.116",
    OtherTrxCode="SIPARIS-2026-0001",
    IsPoolPayment=0,
    IsTokenized=0,
    Software="yazilim adiniz",
    IsPreAuth=0,
    BuyerInformation=models.Buyer(
        BuyerFullName="Ali Yilmaz",
        BuyerGsmNumber="5551110022",
        BuyerEmail="ali@ornek.com",
        BuyerAddress="Tasdelen / Cekmekoy",
    ),
)

yanit = client.payments().create(istek)

if yanit.is_payment_successful:
    # Iptal, iade ve havuz onayi islemleri icin bu deger saklanmalidir
    siparis_no = yanit.data["VirtualPosOrderId"]
elif yanit.is_success:
    # Banka islemi reddetti
    print(yanit.data["ResultCode"], yanit.data["ResultMessage"])
else:
    # Istek Moka United tarafinda islenemedi
    print(yanit.result_code, yanit.result_message)

3D Secure ile Odeme

3D odemede ReturnHash=1 ve RedirectUrl zorunludur. Yanittaki Url degerine kullanici yonlendirilir; CodeForHash degeri veritabaninda saklanir.

istek = models.CreatePaymentRequest(
    CardHolderFullName="Ali Yilmaz",
    CardNumber="5127541122223332",
    ExpMonth="12",
    ExpYear="2030",
    CvcNumber="000",
    Amount=100.50,
    Currency="TL",
    InstallmentNumber=1,
    ClientIP="192.168.1.116",
    OtherTrxCode="SIPARIS-2026-0002",
    Software="yazilim adiniz",
    ReturnHash=1,
    RedirectUrl="https://www.siteniz.com/odeme-sonucu?islem=SIPARIS-2026-0002",
    RedirectType=0,
)

yanit = client.payments().create_threeds(istek)

if yanit.is_success:
    yonlendirme_adresi = yanit.data["Url"]
    code_for_hash = yanit.data["CodeForHash"]  # saklayin

Kart dogrulamasi tamamlandiginda Moka United, RedirectUrl adresinize hashValue, resultCode, resultMessage, trxCode ve OtherTrxCode alanlarini POST eder. Sonuc su sekilde dogrulanir:

from moka import verify_threeds_result

sonuc = verify_threeds_result(code_for_hash, gelen_hash_value)

if sonuc is True:
    # SHA256(CodeForHash + "T") eslesti: odeme basarili
    ...
elif sonuc is False:
    # SHA256(CodeForHash + "F") eslesti: odeme basarisiz
    ...
else:
    # Hash eslesmedi: istek gecersiz veya kurcalanmis
    ...

Basarili islemde trxCode alaninda donen OrderId degeri saklanmalidir; iptal, iade ve havuz onayi islemleri bu degerle yapilir.

3D Secure ile Mobil Odeme

istek = models.CreateMobilePaymentRequest(
    PaymentType=1,
    Amount=100,
    Currency="TL",
    InstallmentNumber=1,
    ClientIP="192.168.1.116",
    RedirectURL="https://www.siteniz.com/odeme-sonucu",
    OtherTrxCode="SIPARIS-2026-0003",
    Software="yazilim adiniz",
)

yanit = client.payments().create_threeds_mobile(istek)

On Provizyon ve Capture

On provizyon icin odeme istegi IsPreAuth=1 ile gonderilir; daha sonra capture ile odemeye cevrilir:

istek = models.CaptureRequest(
    VirtualPosOrderId="ORDER-...",
    OtherTrxCode="",
    Amount=100.50,
    ClientIP="192.168.1.116",
)

yanit = client.payments().capture(istek)

Havuzdaki Odemeyi Onaylama ve Onay Iptali

Havuz odemesi icin odeme istegi IsPoolPayment=1 ile gonderilir. Urun veya hizmet teslim edildikten sonra odeme onaylanir:

yanit = client.payments().approval(
    models.ApprovalRequest(VirtualPosOrderId="ORDER-...")
)

yanit = client.payments().cancel_approval(
    models.CancelApprovalRequest(VirtualPosOrderId="ORDER-...")
)

Odeme Iptali ve Iade

# Iptal (void)
yanit = client.payments().cancel(
    models.CancelPaymentRequest(
        VirtualPosOrderId="ORDER-...",
        ClientIP="192.168.1.116",
        VoidRefundReason=2,
    )
)

# Iade talebi (tutar verilerek kismi iade de yapilabilir)
yanit = client.refunds().create(
    models.CreateRefundRequest(
        VirtualPosOrderId="ORDER-...",
        Amount=50.25,
    )
)

Odeme Guncelleme

yanit = client.payments().update(
    models.UpdatePaymentRequest(
        DealerPaymentId=12345,
        Description="Guncellenmis aciklama",
    )
)

Odeme Linki Olusturma

istek = models.CreatePaymentLinkRequest(
    OtherTrxCode="SIPARIS-2026-0004",
    FullName="Ali Yilmaz",
    GsmNumber="5551110022",
    Email="ali@ornek.com",
    Amount=250,
    Currency="TL",
    IsThreeD=1,
)

yanit = client.payment_links().create(istek)

Bilgi Alma Islemleri

# Odeme listesi
yanit = client.payments().all(
    models.RetrievePaymentListRequest(
        PaymentStartDate="2026-01-01",
        PaymentEndDate="2026-01-31",
    )
)

# Transaction listesi
yanit = client.transactions().all(
    models.RetrieveTransactionListRequest(
        TrxStartDate="2026-01-01",
        TrxEndDate="2026-01-31",
    )
)

# Odeme detayi (kendi islem kodunuzla sorgulayabilirsiniz)
yanit = client.payments().retrieve(
    models.RetrievePaymentDetailRequest(OtherTrxCode="SIPARIS-2026-0001")
)

# Bin sorgulama
yanit = client.bin_number().retrieve(
    models.RetrieveBinNumberRequest(BinNumber="512754")
)

# Taksit tablosu hesaplama
yanit = client.payments().retrieve_installment_info(
    models.RetrieveInstallmentInfoRequest(
        BinNumber="512754",
        Currency="TL",
        OrderAmount=1000,
        IsThreeD=1,
    )
)

# Karttan cekilecek tutar hesaplama
yanit = client.payments().retrieve_amount(
    models.RetrievePaymentAmountRequest(
        BinNumber="512754",
        Currency="TL",
        OrderAmount=1000,
        InstallmentNumber=3,
        IsThreeD=1,
    )
)

Kart Saklama Servisleri

Kart saklama servislerini kullanabilmek icin bayinin Moka United tarafinda kart saklama hizmetinin aktive edilmis olmasi gerekir.

# Musteri ekleme
yanit = client.customers().create(
    models.CreateCustomerRequest(
        CustomerCode="MUSTERI-1",
        FirstName="Ali",
        LastName="Yilmaz",
        Email="ali@ornek.com",
    )
)

# Kartiyla birlikte musteri ekleme
yanit = client.customers().create_with_card(
    models.CreateCustomerWithCardRequest(
        CustomerCode="MUSTERI-2",
        FirstName="Veli",
        LastName="Yilmaz",
        CardHolderFullName="Veli Yilmaz",
        CardNumber="5127541122223332",
        ExpMonth="12",
        ExpYear="2030",
        CardName="Is kartim",
    )
)

# Musteriye kart ekleme
yanit = client.cards().create(
    models.CreateCardRequest(
        CustomerCode="MUSTERI-1",
        CardHolderFullName="Ali Yilmaz",
        CardNumber="5127541122223332",
        ExpMonth="12",
        ExpYear="2030",
        CardName="Maximum kartim",
    )
)

# Kart listesi, bilgi alma, guncelleme, silme
yanit = client.cards().all(models.RetrieveCardListRequest(CustomerCode="MUSTERI-1"))
yanit = client.cards().retrieve(models.RetrieveCardRequest(CardToken="..."))
yanit = client.cards().update(models.UpdateCardRequest(CardToken="...", CardName="Yeni ad"))
yanit = client.cards().delete(models.DeleteCardRequest(CardToken="..."))

# Musteri listesi, bilgi alma, guncelleme, silme
yanit = client.customers().all()
yanit = client.customers().retrieve(models.RetrieveCustomerRequest(CustomerCode="MUSTERI-1"))
yanit = client.customers().update(models.UpdateCustomerRequest(CustomerCode="MUSTERI-1", Email="yeni@ornek.com"))
yanit = client.customers().delete(models.DeleteCustomerRequest(CustomerCode="MUSTERI-1"))

Sakli kartla odeme yapmak icin odeme isteginde kart bilgileri yerine CardToken gonderilir.

Tekrarlayan Odeme Servisleri

# Urun tanimlama
yanit = client.products().create(
    models.CreateProductRequest(ProductName="Aylik Uyelik", ProductCode="UYELIK-AY")
)

# Takvim tanimlama (ornek: her ayin 1'i)
yanit = client.schedules().create(
    models.CreateScheduleRequest(
        ScheduleName="Aylik",
        DailyWeeklyMonthly=3,
        EveryX=1,
        DaysOfMonth="1",
    )
)

# Satis olusturma
yanit = client.sales().create(
    models.CreateSaleRequest(
        CustomerCode="MUSTERI-1",
        ProductCode="UYELIK-AY",
        SaleCode="SATIS-1",
        Amount=99.90,
        Currency="TL",
    )
)

# Odeme plani islemleri
yanit = client.payment_plans().all(models.RetrievePaymentPlanListRequest(SaleCode="SATIS-1"))
yanit = client.payment_plans().create(models.CreatePaymentPlanRequest(SaleCode="SATIS-1", PaymentDate="2026-08-01", Amount=99.90))
yanit = client.payment_plans().retrieve_history(models.RetrievePaymentPlanHistoryListRequest(DealerPaymentPlanId=1))

Muhasebe ve Raporlama

# Bayi muhasebesi
yanit = client.reporting().accounting(
    models.ReportingAccountingListRequest(
        TransferStartDate="2026-01-01",
        TransferEndDate="2026-01-31",
    )
)

# Bayi ekstresi
yanit = client.reporting().statement(
    models.ReportingStatementListRequest(
        StatementStartDate="2026-01-01",
        StatementEndDate="2026-01-31",
    )
)

# Bayi bilgisi
yanit = client.dealers().retrieve(models.RetrieveDealerRequest())

Hata Kodlari

Bankadan donen islem hatalarinin Turkce karsiliklari moka.error_codes modulunde yer alir:

from moka import get_bank_error_message

mesaj = get_bank_error_message("002")  # "Limit Yetersiz"

Moka United tarafindan donen servis hata kodlari (ornegin PaymentDealer.CheckPaymentDealerAuthentication.InvalidAccount) ApiResponse.result_code alaninda bulunur; tam liste icin Moka United dokumantasyonuna bakiniz.

Test Kartlari

Test kartlariyla yapilan odemeler bankaya gonderilmez; cevap Moka United sisteminden doner. Guncel test karti listesi icin resmi dokumantasyona bakiniz (liste zaman icinde degisebilir):

https://developer.mokaunited.com/home.php?page=test-kartlari

Gelistirme kolayligi icin kartlara kod icinden moka.test_cards.TEST_CARDS listesiyle veya get_test_card fonksiyonuyla da erisilebilir:

from moka import get_test_card

kart = get_test_card(bank="Garanti Bankasi")
kart = get_test_card(card_type="Troy")

Testler

Birim testler ag baglantisi gerektirmez:

python -m unittest discover -s tests -v

Moka United test ortamina karsi gercek istek atan canli testler, asagidaki ortam degiskenleri tanimlandiginda otomatik olarak calisir:

export MOKA_DEALER_CODE="bayi kodunuz"
export MOKA_USERNAME="api kullanici adiniz"
export MOKA_PASSWORD="api sifreniz"
python -m unittest tests.test_live -v

PyPI Yayinlama (twine)

pip install build twine
python -m build
twine upload dist/*

Ornek Kodlar

samples/ klasorunde calistirilabilir ornekler yer alir:

  • create_payment.py: Non-3D odeme
  • create_threeds_payment.py: 3D Secure ile odeme
  • retrieve_bin.py: Bin sorgulama
  • retrieve_installment_info.py: Taksit tablosu hesaplama

Lisans

MIT lisansi ile dagitilmaktadir. Ayrintilar icin LICENSE dosyasina bakiniz.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moka_python-1.0.0.tar.gz (27.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moka_python-1.0.0-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file moka_python-1.0.0.tar.gz.

File metadata

  • Download URL: moka_python-1.0.0.tar.gz
  • Upload date:
  • Size: 27.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for moka_python-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7aca686746b2c148d8fec30f3f1d4305a7a834bf25ee74fa6cdfbe32b3bff0f8
MD5 b93f8774a5a41eb7894fadadb336a483
BLAKE2b-256 cd2511f50c5233ba5b11fb425abc13e0edcfca418a7b8b0708bc43db7b2ff2d8

See more details on using hashes here.

File details

Details for the file moka_python-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: moka_python-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 19.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for moka_python-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c5f92e655160001db3bfceaf5882ad45bff86844481159caf76cec76dc7ccbc2
MD5 eeddbd9d1d9ee3887184187b9671936f
BLAKE2b-256 cb9f986c697ad3bc757cb3975e7cf058a0be2abee6548da26b9d1d6a82c80519

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page