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 odemecreate_threeds_payment.py: 3D Secure ile odemeretrieve_bin.py: Bin sorgulamaretrieve_installment_info.py: Taksit tablosu hesaplama
Lisans
MIT lisansi ile dagitilmaktadir. Ayrintilar icin LICENSE dosyasina bakiniz.
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.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7aca686746b2c148d8fec30f3f1d4305a7a834bf25ee74fa6cdfbe32b3bff0f8
|
|
| MD5 |
b93f8774a5a41eb7894fadadb336a483
|
|
| BLAKE2b-256 |
cd2511f50c5233ba5b11fb425abc13e0edcfca418a7b8b0708bc43db7b2ff2d8
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5f92e655160001db3bfceaf5882ad45bff86844481159caf76cec76dc7ccbc2
|
|
| MD5 |
eeddbd9d1d9ee3887184187b9671936f
|
|
| BLAKE2b-256 |
cb9f986c697ad3bc757cb3975e7cf058a0be2abee6548da26b9d1d6a82c80519
|