Short answer: The Param API (ParamPOS) is a SOAP web service of TURK Elektronik Para A.Ş., and on 6 November 2026 its developer portal and test host returned access-denied pages. According to the Savings Deposit Insurance Fund (TMSF), the Central Bank temporarily suspended the company's activities on 30 April 2026, and TMSF has run it as trustee since 13 July 2026. Archived official documents describe the 3D flow: TP_WMD_UCD, a bank redirect, a SHA1-hashed callback and TP_WMD_Pay.
This Param API integration (Param API entegrasyonu) guide uses pages read on 6 November 2026: TMSF's announcements, TCMB's registers, Law No. 6493 and Param's website. The developer portal, dev.param.com.tr, refused a script and a browser that day with an access-denied page, so API details come from Internet Archive copies of the official documents captured from July 2024 to April 2025; confirm them with the company.
Nothing here is a recommendation or legal advice. Fincode sells software and API integration work, so this guide is not neutral on that point. Crypto assets may not be used in payments in Turkey, directly or indirectly, under a 2021 TCMB regulation (opens in a new tab) (Turkish); see crypto payment API integration. Who may collect payments is covered in the Turkey payment gateway guide.
Is Param still operating? Status on 6 November 2026
Param's operator, TURK Elektronik Para A.Ş., has been run by a trustee since 13 July 2026, after the Central Bank of the Republic of Türkiye (TCMB, also CBRT) temporarily suspended its activities on 30 April 2026, according to the Savings Deposit Insurance Fund (TMSF).
| Date | What TMSF says |
|---|---|
| 30 April 2026 | TCMB temporarily suspended the company's activities |
| 13 July 2026 | The court lifted the stay of execution granted to the company against that decision; TMSF became trustee of PARAM and its group companies under Provisional Article 2 of Law No. 7145, in an Istanbul Chief Public Prosecutor's investigation |
| 12 August 2026 | Merchants' due ParamPOS settlements paid up to TRY 100,000, excluding disputed spending |
| 8 September 2026 | Paid up to TRY 250,000 |
| 23 September 2026 | 8% of accrued settlements paid |
| 27 October 2026 | Payments began to individual ParamCüzdan wallet customers verified before 14 July 2026 |
| 3 November 2026 | A further 8% for merchants, announced on 2 November; no confirmation seen |
TMSF says work continues so that the remaining balances can be paid to the extent of the company's financial means. Other records read the same day:
- TCMB register. The e-money institution list still names Turk Elektronik Para A.Ş., code 827. Services (a), (ç), (e), (f) and (g) of Law No. 6493 Article 12(1) are ticked; (b) money transfer, (c) issuing or acquiring payment instruments, and e-money issuance carry a red cross the page does not explain.
- TCMB decisions. The decision list, which runs to 10 October 2026, names no 2026 decision about the company; its latest entry for it is a 10 January 2025 decision widening its licence.
- Param's website. The Turkish home page carries the company's notice of TMSF's trusteeship, and every subpage tried, including the developer and virtual POS pages, redirects to it. The English home page has no notice and still describes the company as CBRT-authorized to issue e-money.
Before a new integration, get written confirmation from the company, under its trustee, of which services it may provide. For unpaid balances, follow TMSF's announcements and ask a Turkish lawyer.
What Turkish law says about merchant money at a payment institution
Money held by a payment or e-money institution is not a bank deposit; Law No. 6493 protects it through safeguarding instead.
| Article | What it says |
|---|---|
| 14(3) | Funds received for payment services are not deposits or participation funds under Article 60 of Banking Law No. 5411 |
| 20(7) | The same for funds collected against e-money |
| 21(8) | TCMB may order measures with up to six months to comply, suspend the licence meanwhile and cancel it if they are not taken |
| 22(1), 22(3) | Funds are safeguarded under TCMB rules and, on liquidation or licence cancellation, go to compensating fund owners regardless of priorities set in other laws |
Until it is settled, captured money is a claim on the provider, so keep your own ledger of captured, refunded and settled amounts rather than relying on the provider's panel.
Param POS API basics from the archived official documents
ParamPOS is a SOAP web service: each call carries a security object and a merchant key, and both environments expect your server's IP address to be registered first.
| Point | What the documents say |
|---|---|
| Production | posws.param.com.tr/turkpos.ws/service_turkpos_prod.asmx (July 2024 document) |
| Test | testposws.param.com.tr/turkpos.ws/service_turkpos_prod.asmx (April 2025 page); the July 2024 document named test-dmz.param.com.tr |
| Credentials | ST_WS_Guvenlik object with CLIENT_CODE (terminal ID), CLIENT_USERNAME and CLIENT_PASSWORD, plus GUID, the merchant key |
| Access | Register your server's static outbound IP: in the Param panel for production, by email for test |
| Amounts | Strings with a decimal comma, such as 1000,50; the refund method types its amount as Double |
| Order ID | Siparis_ID; one sent before gets a new ID assigned |
On 6 November 2026 the newer test host refused access and the older one returned 404, so no Param call was run. Keep CLIENT_PASSWORD and GUID in a secret store, as in API key security, and use a fixed outbound IP, since a new autoscaled address fails the check.
Param 3D Secure flow: TP_WMD_UCD, callback and TP_WMD_Pay
A 3D payment is two calls with a bank redirect between them, and only the second call takes the money.
- Read the installment's commission rate from
TP_Ozel_Oran_SK_Liste;Toplam_Tutar = Islem_Tutar + ((Islem_Tutar x rate) / 100), with no rounding rule given. - Join
CLIENT_CODE,GUID,Taksit,Islem_Tutar,Toplam_TutarandSiparis_IDand send the string to theSHA2B64web method forIslem_Hash. The page does not name the algorithm, so call the method instead of guessing. - Call
TP_WMD_UCDwithIslem_Guvenlik_Tipset to3D(NSfor non-secure), sendUCD_HTMLto the browser and storeIslem_GUID. - After the bank page, Param posts
md,mdStatus,orderId,transactionAmount,islemGUIDandislemHashto yourBasarili_URLorHata_URL. - Check
islemHash: base64 of SHA1 overislemGUID + md + mdStatus + orderIdplus the merchant key. - Call
TP_WMD_Paywith the MD value,Islem_GUIDandSiparis_ID; success needsSonucandDekont_IDboth above zero.
| mdStatus | Meaning | Call TP_WMD_Pay? |
|---|---|---|
| 1 | Verified (full 3D) | Yes |
| 2, 3, 4 | Card not enrolled (half 3D) | Allowed |
| 5, 6, 7, 8 | No valid verification, or system error | No |
| 0 | Verification failed | No |
The documents conflict in three places; test each against real traffic:
- Key case. The callback text says to lower-case the key; its sample code does not, and the pre-authorization section is silent.
- mdStatus. The callback field table calls 1 success and any other value a failed verification; the mdStatus table allows
TP_WMD_Payfor 1 to 4. - 3D Pay result hash. For
Pos_Odeme, the text listsCLIENT_CODE, key,TURKPOS_RETVAL_Dekont_ID, amount,Siparis_IDandIslem_ID, but the sample beneath it hashes the 3D callback fields.
A tested Python check for the Param 3D callback
This check validates the callback before any lookup or network call; it ran on Python 3.11.3 on 6 November 2026 with synthetic values and no network.
Worked string, synthetic values. For the test post in the code, the lower-case reading hashes 11111111-2222-3333-4444-555555555555MD-SYNTH1ORD-10010a1b2c3d-synthetic-key.
import base64, hashlib, hmac, re
from decimal import Decimal
KEY = "0A1B2C3D-SYNTHETIC-KEY" # synthetic merchant key (GUID), not a real one
AMOUNT = re.compile(r"^\d{1,12}(?:[.,]\d{1,2})?$")
FIELDS = ("md", "mdStatus", "orderId", "transactionAmount", "islemGUID", "islemHash")
def parse_amount(value):
"""'1000,50' or '1000.50' -> Decimal; refuses '1e400', 'inf', '0', '-5' and floats."""
s = str(value).strip()
if isinstance(value, float) or not AMOUNT.match(s) or not Decimal(s.replace(",", ".")) > 0:
raise ValueError(f"bad amount {repr(value)}")
return Decimal(s.replace(",", "."))
def to_wire(value): # Islem_Tutar format: '1000,50'
return format(parse_amount(value).quantize(Decimal("0.01")), "f").replace(".", ",")
def callback_hash(form, key=KEY, lower_key=True):
k = key.lower() if lower_key else key
msg = "".join(str(form[f]) for f in ("islemGUID", "md", "mdStatus", "orderId")) + k
return base64.b64encode(hashlib.sha1(msg.encode("utf-8")).digest()).decode()
def handle_callback(form, orders, key=KEY, lower_key=True):
if not isinstance(form, dict):
return "reject: not a form"
for f in FIELDS:
if not str(form.get(f) or "").strip():
return f"reject: missing {f}"
if not hmac.compare_digest(callback_hash(form, key, lower_key).encode(),
str(form["islemHash"]).encode()):
return "reject: hash mismatch"
rows = [o for o in orders if o.get("id") == form["orderId"]]
if not len(rows) == 1:
return f"error: {len(rows)} rows for order {form['orderId']}"
try:
if not parse_amount(form["transactionAmount"]) == parse_amount(rows[0].get("amount")):
return "reject: amount differs"
except ValueError as e:
return f"reject: {e}"
if form["mdStatus"] not in ("1", "2", "3", "4"):
return f"stop: mdStatus {form['mdStatus']}, no TP_WMD_Pay"
return "ok: call TP_WMD_Pay"
def pay_succeeded(result):
"""TP_WMD_Pay: success only if Sonuc > 0 and Dekont_ID > 0."""
def num(v):
try:
return int(str(v))
except ValueError:
return 0
return isinstance(result, dict) and num(result.get("Sonuc")) > 0 and num(result.get("Dekont_ID")) > 0
orders = [{"id": "ORD-1001", "amount": "1000,50"}]
post = {"md": "MD-SYNTH", "mdStatus": "1", "orderId": "ORD-1001",
"transactionAmount": "1000,50", "islemGUID": "11111111-2222-3333-4444-555555555555"}
post["islemHash"] = callback_hash(post)
zero = {**post, "mdStatus": "0"}
zero["islemHash"] = callback_hash(zero)
tests = [post, {**post, "mdStatus": "0"}, {**post, "islemHash": "ş"}, zero,
{k: v for k, v in post.items() if not k == "islemHash"},
{**post, "transactionAmount": "1e400"}, {**post, "orderId": ""}]
for t in tests:
print(handle_callback(t, orders))
print(handle_callback(post, orders * 2))
print(callback_hash(post) == callback_hash(post, lower_key=False))
print(*[pay_succeeded(r) for r in ({"Sonuc": "1", "Dekont_ID": "0"},
{"Sonuc": "-1", "Sonuc_Str": "error"}, {"Sonuc": "1", "Dekont_ID": "88412"}, None)])
for v in ("1000.5", 1e400, "inf", "0"):
try:
print(to_wire(v))
except ValueError as e:
print(e)Output:
ok: call TP_WMD_Pay
reject: hash mismatch
reject: hash mismatch
stop: mdStatus 0, no TP_WMD_Pay
reject: missing islemHash
reject: bad amount '1e400'
reject: missing orderId
error: 2 rows for order ORD-1001
False
False False True False
1000,50
bad amount inf
bad amount 'inf'
bad amount '0'The ninth line shows why the key-case conflict matters: with an upper-case key the two readings differ. The string 1e400, an empty order ID and a duplicated order row are refused by name; the float 1e400 (inf) never reaches the wire; pay_succeeded reads an error body without KeyError. Allowing mdStatus 1 to 4 follows the mdStatus table; accepting only 1 is stricter.
Param API failure handling: timeouts, refunds and reconciliation
A reused Siparis_ID gets a new ID instead of being refused, so a blind retry can create a second payment; look the payment up before sending it again.
- Before the call. Write the order, its ID and amount to your database first, so a crash leaves a record.
- After a timeout. The April 2025 index lists Transaction Query, Transaction Summaries and Reconciliation Detail pages, which could not be read; the July 2024 document covers
TP_Mutabakat_OzetandTP_Mutabakat_Detay. - Cancel or refund.
TP_Islem_Iptal_Iade_Kismi2takesDurumasIPTALwith the full amount, orIADEwith the full or a smaller amount; itsTutaris a Double, unlike the comma strings elsewhere. - Stored cards.
KK_Saklamastores a card at Param and returns aKS_GUIDforKS_Tahsilat; the documents list no export, so plan to collect cards again if you move. - A second route. Put the provider behind your own interface, so switching providers means a new adapter, not a rewrite.
Checklist before signing with any Turkish virtual POS provider
Check the regulator's records, the settlement terms and your exit path before anyone writes code.
- Regulator records. Search TCMB's register by legal name on the day you sign, read every column, ask in writing about any red cross and check TCMB's decision list.
- Settlement. Ask how long funds wait, how Article 22 safeguarding applies and how disputed spending is held back.
- Exports. Confirm daily transaction and settlement downloads, and keep your own ledger.
- Test access. Get test credentials, test cards and IP registration steps in writing.
- Exit. Plan refunds for past orders and stored cards if the provider stops.
See the guide to hiring a software company in Turkey and fintech app development cost. For integration work in general, see Fincode's fintech app development page; naming Param here does not mean Fincode integrates it or has built on it.
Frequently asked questions
Is Param accepting new merchants?
The official pages read on 6 November 2026 do not say. TMSF's announcements cover paying existing merchants and wallet customers, and Param's virtual POS page redirected to its home page, so ask the company in writing.
How do I verify a Param 3D Secure callback?
Compute the base64 SHA1 of islemGUID, md, mdStatus, orderId and your merchant key and compare it with islemHash, per the archived July 2024 document. It conflicts on lower-casing the key, so test both readings.
What does mdStatus mean in Param?
1 means verified, 2 to 4 card not enrolled, 5 to 8 no valid verification or a system error, and 0 failed. The documents allow TP_WMD_Pay only for 1 to 4.
Can I take crypto payments through Param?
No. A TCMB regulation of 16 April 2021 bars crypto assets from payments, directly or indirectly, and bars payment service providers from business models that use them.
Sources
- TMSF: Press announcement on Param, no date on the page (Turkish) (opens in a new tab)
- TMSF: Param companies press announcement, 23 September 2026 (Turkish) (opens in a new tab)
- TMSF: Param companies press announcement, 26 October 2026 (Turkish) (opens in a new tab)
- TMSF: Param companies press announcement, 2 November 2026 (Turkish) (opens in a new tab)
- TMSF: Press announcements list, latest entry 2 November 2026 when read on 6 November 2026 (Turkish) (opens in a new tab)
- TCMB: E-money institutions register (Turkish) (opens in a new tab)
- TCMB: Payment systems legislation and institution decisions (Turkish) (opens in a new tab)
- TCMB: Law No. 6493 as published on its legislation page, Articles 12, 14, 20, 21 and 22 (Turkish) (opens in a new tab)
- Resmî Gazete: TCMB Regulation on the Disuse of Crypto Assets in Payments, 16 April 2021, no. 31456 (Turkish) (opens in a new tab)
- Param: Turkish home page with the trusteeship notice (opens in a new tab)
- Param: English home page (opens in a new tab)
- Internet Archive: Param developer API page, captured 17 April 2025 (opens in a new tab)
- Internet Archive: Param hash calculation page, captured 27 March 2025 (opens in a new tab)
- Internet Archive: Param 3D Model page, captured 22 July 2024 (opens in a new tab)
- Internet Archive: Param integration document PDF, captured 17 July 2024 (Turkish) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.