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 ödemecreate_threeds_payment.py: 3D Secure ile ödemeretrieve_bin.py: Bin sorgulamaretrieve_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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee366b4be7b97e38d11e5f40c26eeef7d24abeb93ef83aa74b2520973b08bd7f
|
|
| MD5 |
0b88a14f62a7101c58cd84365e74a647
|
|
| BLAKE2b-256 |
be08e88570f513f6dc785f7fc489d1b3b6b7e993fe8cde90343b98b5562385da
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7aeaca2b7a02dcd0da624512762da95bf16e47288c2d45a63206245b553de443
|
|
| MD5 |
a2d8c071eeea5e51d8c8e8f851173508
|
|
| BLAKE2b-256 |
85d36fa3afbef00e1865cf885e050951d17d52e08619e565cf41ad8fd0ddd046
|