Skip to main content

Moka United sanal POS API'si için Python istemcisi. Bu kütüphane bağımsız olarak geliştirilmiştir; Moka United'ın resmi ürünü değildir, Moka United tarafından geliştirilmemiş, onaylanmamış ve desteklenmemektedir.

Project description

moka-python

Bu kütüphane bağımsız olarak geliştirilmiştir; Moka United'ın resmi ürünü değildir, Moka United tarafından geliştirilmemiş, onaylanmamış ve desteklenmemektedir.

Moka United sanal POS API'si için Python istemcisi.

Bu kütüphane, Moka United API servislerine Python uygulamalarından erişim sağlar. Resmi PHP istemcisindeki (moka-php) tüm servisleri ve istek modellerini birebir kapsar. Harici hiçbir bağımlılığı yoktur; yalnızca Python standart kütüphanesini kullanır.

Özellikler

  • 3D Secure olmadan ödeme (Non-3D)
  • 3D Secure ile ödeme
  • 3D Secure ile mobil ödeme
  • Ön provizyon ve capture işlemi
  • Havuz ödemesi onaylama ve onay iptali
  • Ödeme iptali (void) ve iade talebi
  • Ödeme güncelleme
  • Ödeme linki oluşturma (ödeme isteği gönderme)
  • Ödeme listesi, transaction listesi ve ödeme detay sorgulama
  • Bin sorgulama, taksit tablosu ve karttan çekilecek tutar hesaplama
  • Kart saklama servisleri (kart ekleme, güncelleme, silme, listeleme)
  • Müşteri yönetimi servisleri
  • Tekrarlayan ödeme servisleri (satış, takvim, ödeme planı, ürün)
  • Bayi bilgisi, muhasebe ve ekstre raporları
  • CheckKey üretimi ve 3D Secure hash doğrulaması
  • Moka United test kartları ve banka hata kodları sözlüğü

Gereksinimler

  • Python 3.8 ve üzeri

Kurulum

pip install moka-python

Kaynak koddan kurulum:

cd moka-python
pip install .

Ortam Adresleri

Ortam Adres
Test ortamı https://service.refmokaunited.com
Canlı ortam https://service.mokaunited.com

İstemci varsayılan olarak canlı ortama bağlanır. Test ortamı için base_url parametresi verilmelidir. Eski service.moka.com ve service.refmoka.com adresleri için LEGACY_API_BASE ve LEGACY_TEST_API_BASE sabitleri de mevcuttur.

Moka United servisleri PCI-DSS kuralları gereği yalnızca TLS 1.2 ve üstü protokollere izin verir. Bu kütüphanenin HTTP katmanı TLS 1.2 zorunluluğunu otomatik olarak uygular.

Hızlı Başlangıç

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 doğrulamada kullanılan CheckKey değeri (DealerCode + "MK" + Username + "PD" + Password bilgisinin SHA-256 özeti) her istekte otomatik olarak üretilir ve eklenir.

Alan adları

İstek modelleri, Moka United dokümantasyonundaki alan adlarıyla (PascalCase) birebir aynı alanları taşır. Alanlar hem API'deki adıyla hem de Python üslubundaki snake_case adıyla kullanılabilir:

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

Yanıt nesnesi

Tüm servisler ApiResponse nesnesi döndürür:

Alan Açıklama
data İstek başarılı ise servis verisi (dict), aksi halde None
result_code Başarılı istekte "Success", hatada Moka hata kodu
result_message Hataya ilişkin varsa açıklama
exception Beklenmeyen hata oluştuğunda (EX) açıklama
is_success İstek Moka United tarafında işlendiyse True
is_payment_successful İstek ve banka işlemi birlikte başarılıysa True

Önemli: is_success yalnızca isteğin Moka United tarafında işlendiğini gösterir. Ödeme işlemlerinde bankanın işlemi onaylayıp onaylamadığını görmek için is_payment_successful özelliği veya data["IsSuccessful"] alanı kontrol edilmelidir.

Ödeme İşlemleri

3D Secure Olmadan Ödeme (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 Ödeme

3D ödemede ReturnHash=1 ve RedirectUrl zorunludur. Yanıttaki Url değerine kullanıcı yönlendirilir; CodeForHash değeri veritabanında saklanır.

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 doğrulaması tamamlandığında Moka United, RedirectUrl adresinize hashValue, resultCode, resultMessage, trxCode ve OtherTrxCode alanlarını POST eder. Sonuç şu şekilde doğrulanır:

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
    ...

Başarılı işlemde trxCode alanında dönen OrderId değeri saklanmalıdır; iptal, iade ve havuz onayı işlemleri bu değerle yapılır.

3D Secure ile Mobil Ödeme

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)

Ön Provizyon ve Capture

Ön provizyon için ödeme isteği IsPreAuth=1 ile gönderilir; daha sonra capture ile ödemeye çevrilir:

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

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

Havuzdaki Ödemeyi Onaylama ve Onay İptali

Havuz ödemesi için ödeme isteği IsPoolPayment=1 ile gönderilir. Ürün veya hizmet teslim edildikten sonra ödeme onaylanır:

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

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

Ödeme İptali ve İade

# 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,
    )
)

Ödeme Güncelleme

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

Ödeme Linki Oluşturma

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 İşlemleri

# 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 için bayinin Moka United tarafında kart saklama hizmetinin aktive edilmiş olması 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"))

Saklı kartla ödeme yapmak için ödeme isteğinde kart bilgileri yerine CardToken gönderilir.

Tekrarlayan Ödeme 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 Kodları

Bankadan dönen işlem hatalarının Türkçe karşılıkları moka.error_codes modülünde yer alır:

from moka import get_bank_error_message

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

Moka United tarafından dönen servis hata kodları (örneğin PaymentDealer.CheckPaymentDealerAuthentication.InvalidAccount) ApiResponse.result_code alanında bulunur; tam liste için Moka United dokümantasyonuna bakınız.

Test Kartları

Test kartlarıyla yapılan ödemeler bankaya gönderilmez; cevap Moka United sisteminden döner. Güncel test kartı listesi için resmi dokümantasyona bakınız (liste zaman içinde değişebilir):

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

Geliştirme kolaylığı için kartlara kod içinden moka.test_cards.TEST_CARDS listesiyle veya get_test_card fonksiyonuyla da erişilebilir:

from moka import get_test_card

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

Testler

Birim testler ağ bağlantısı gerektirmez:

python -m unittest discover -s tests -v

Moka United test ortamına karşı gerçek istek atan canlı testler, aşağıdaki ortam değişkenleri tanımlandığında otomatik olarak çalışır:

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 Yayınlama (twine)

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

Örnek Kodlar

samples/ klasöründe çalıştırılabilir örnekler yer alır:

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

Lisans

MIT lisansı ile dağıtılmaktadır. Ayrıntılar için LICENSE dosyasına bakınız.

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.2.tar.gz (28.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.2-py3-none-any.whl (19.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: moka_python-1.0.2.tar.gz
  • Upload date:
  • Size: 28.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.2.tar.gz
Algorithm Hash digest
SHA256 ee366b4be7b97e38d11e5f40c26eeef7d24abeb93ef83aa74b2520973b08bd7f
MD5 0b88a14f62a7101c58cd84365e74a647
BLAKE2b-256 be08e88570f513f6dc785f7fc489d1b3b6b7e993fe8cde90343b98b5562385da

See more details on using hashes here.

File details

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

File metadata

  • Download URL: moka_python-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 19.6 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7aeaca2b7a02dcd0da624512762da95bf16e47288c2d45a63206245b553de443
MD5 a2d8c071eeea5e51d8c8e8f851173508
BLAKE2b-256 85d36fa3afbef00e1865cf885e050951d17d52e08619e565cf41ad8fd0ddd046

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