MevvPos documentation

From one virtual POS to a card routed to the bank that issued it.

MevvPos connects WooCommerce to Turkish virtual POS systems: several POS accounts side by side, each card routed by its BIN to the bank that issued it, instalments and per-instalment commission. This page covers installation, every admin screen, what the free edition does, what Pro adds, and what the plugin deliberately does not do.

Installation

MevvPos needs WordPress 6.0+, PHP 8.1+ and WooCommerce 9.0 or newer. WooCommerce is a hard dependency, declared in the plugin header: without it WordPress refuses the activation, and on older WordPress versions the plugin simply does nothing.

  1. Upload the plugin under Plugins → Add New → Upload Plugin and activate it.
  2. Open MevvPos in the left admin menu. There is also a shortcut under WooCommerce, where merchants tend to look for payment settings.
  3. On the Genel tab, switch the payment method on and set the title the customer will see at checkout.
  4. On Banka API, pick your bank and enter the credentials it gave you.
  5. On Taksit ve Komisyon, enter your instalment rates.
  6. Test with your bank’s test credentials before going live.

No database tables are created and no scheduled job is registered by the free edition. Everything lives in WordPress options and in order meta.

Pro is a separate plugin, installed alongside the free one — not a replacement for it. The free plugin ships on WordPress.org, where anything published can be redistributed under the GPL; keeping the paid source in the same package would have made it legally redistributable by anyone who deleted the licence checks. The licence key is entered on the Lisans tab.

Opening WooCommerce → Settings → Payments → MevvPos redirects you to the MevvPos screen. That is deliberate: there is one place for these settings, not two that can disagree.

How it works

  1. You define one or more POS records. A POS record is one bank’s virtual POS: its credentials, its gateway address, its instalment rates.
  2. At checkout the customer types their card. The first six digits — the BIN — identify the bank that issued it.
  3. MevvPos looks the BIN up and sends the payment to your POS at that bank, if you have one. Otherwise it falls to your default POS.
  4. Instalments are offered only when the card belongs to that POS’s own bank, because banks do not grant instalments on another bank’s cards.
  5. The customer goes through 3-D Secure at the bank, and the bank returns to a single callback address on your site.
  6. The signature on the return is verified with the key of the POS the order actually used, the order is completed and the result is recorded.

The card number, expiry and CVV are never written to your database or to the WooCommerce session. The only card data kept is the first six digits and the recognised bank name.

POS records

The POS bar sits above the tabs and is visible on every one of them. Each card shows the bank, the merchant number, and a badge when something needs your attention.

Varsayılan
The POS that takes the payment when no better match is found. There is always exactly one.
Pasif
Kept but not collecting. Use this rather than deleting when a POS is configured but not yet live at the bank — a customer holding that bank’s card would otherwise be unable to pay.
Lisans bekliyor
The record exists but is dormant because the licence is not active. Nothing was deleted; it resumes where it left off when the licence is renewed.
API bilgileri girilmedi
The record has no merchant number yet.

Banks are shown by a colour stripe rather than a logo. Bank logos are trademarks, and fifteen of them is both legal exposure and permanent maintenance — you already know which bank is yours.

The last POS cannot be deleted and the last enabled one cannot be switched off. To stop taking card payments entirely, turn the payment method off on the Genel tab instead.

The free edition allows one POS. Extra records are a Pro capability — and so, as a consequence, is BIN routing: with a single POS there is nothing to route between.

Banka API — credentials and the gateway address

Banka
Choose the bank your POS is with. The gateway address and the BIN list used for instalments both follow this choice. Institutions with no implementation yet are listed with “— yakında” and cannot be selected.
Mağaza No (Client ID)
The merchant number the bank gave you.
İşyeri Anahtarı (Store Key)
The merchant security key. Stored as a password field; once saved it is shown masked.
Gate URL
The address the payment form posts to.
Test modu
Stops the automatic redirect so you can inspect the request before it is sent.

Leaving Store Key blank when you save means “do not change it”. Writing the blank value would wipe the key and your store would stop taking payments without a single error message. The same rule applies to the other secret fields.

Some families need extra credentials, and the form shows them only for the bank you picked:

  • Garanti BBVA — Üye İşyeri No (MerchantId), Provizyon Kullanıcı Adı, Provizyon Parolası.
  • VakıfBank — Terminal No, and an MPI address (leave it empty to use the test address).
  • PayTR — Merchant Salt.
  • iyzico, Craftgate, Sipay — no extra fields: the API key goes in Mağaza No and the secret in İşyeri Anahtarı.

These extra credentials go into the signature. If one is missing, the signature is computed with an empty value and the bank refuses the payment silently — no error, no message, just a decline.

For the seven NestPay banks the gateway address is filled in from your bank choice, so you can leave Gate URL empty. For the others the field is not pre-filled: enter the address your bank or provider gave you, otherwise the payment form has nowhere to post.

The thirteen supported institutions

NestPay / Asseco (Payten)
İş Bankası, Akbank, Halkbank, QNB, Şekerbank, TEB, Ziraat Bankası
Garanti GT3D
Garanti BBVA
PayFlex V4
VakıfBank
Payment institutions
iyzico, PayTR, Craftgate, Sipay

Institutions without an implementation stay in the bank list on purpose, marked “— yakında”. Removing them would hide which protocol families are still missing. If yours is one of them, the Banka Talebi tab is where you say so.

Only the NestPay signature has a golden-vector test against the bank’s own published example. Every other provider is marked beta in its own source: the flow is implemented to the documentation, but it has not yet been verified end to end with a live merchant account at that institution. That label stays until it has been.

Payment institutions do not issue cards, so they carry no BIN list. You select them as your POS rather than routing to them.

BIN-based routing

A card’s first six digits identify the bank that issued it. MevvPos matches on exactly those six digits.

  • A snapshot of the BIN table ships inside the plugin — 1.449 BINs across 36 banks in the current build — so routing works offline, on the free edition, from the moment you install it.
  • Pro refreshes it weekly from our servers. The refresh merges over the packaged table rather than replacing it: a partial or empty response must never leave a store with no BIN data at all.
  • A response carrying fewer than a hundred BINs is rejected as implausible and not written.
  • Conflicts — the same BIN claimed by two banks — are resolved on our side before the list is sent. A store that resolved them locally could count a card as “ours” and route it elsewhere at the same time.

An unrecognised BIN is never refused. It falls through to your default POS. Turning away a card we simply do not have on file would be losing a sale to protect a lookup table.

The same table answers a second, different question at checkout: is this card from this POS’s own bank? That is what decides whether instalments are offered — see below.

BIN accuracy is not a paid feature. What Pro pays for is freshness, not correctness: the packaged list is the same list, just frozen at build time.

Instalments and commission

Rates are set per POS, from single charge up to twelve, on the Taksit ve Komisyon tab. They are percentages: write 5.50 for 5,5%.

0
The option is shown and no commission is added.
Empty
The option is not shown at all. Empty and zero are not the same thing.

The commission appears in the cart as a taxable fee named “N Taksit Komisyonu”, calculated on the cart total including shipping and tax.

Instalments are offered only on cards issued by that POS’s own bank, and this is enforced on the server — not merely hidden in the interface. A card from another bank is forced back to a single charge and the fee is cleared.

The free edition shows the customer at most three instalments; Pro raises the ceiling to twelve. The ceiling is applied in three places: the list the customer sees, the value that arrives with the form, and the value sent to the bank. The last one matters because a value chosen while the licence was still valid can survive in the session.

The settings form always shows all twelve fields, whatever your licence. If they disappeared when a licence lapsed, saving the page would quietly delete rates you had already entered. Fields above your ceiling are marked “Pro’da açılır” and your numbers are kept.

There is no bank-supplied instalment table. The rates are the ones you enter, and commission on a past order is calculated from the rate that applied on the day of the sale — changing a rate today does not rewrite yesterday’s report.

The payment flow and card handling

Every family goes through 3-D Secure. There is no non-3D mode and no setting to turn it off.

Form flow
NestPay, Garanti, PayTR and Sipay: the browser posts a signed form to the bank, the customer authenticates, and the bank returns to your site.
Server flow
VakıfBank, iyzico and Craftgate: your server talks to the provider, gets the 3-D page, shows it, and completes the sale server to server after authentication.

The bank always returns to one address on your site: ?wc-api=mevvpos_callback. The signature on that return is verified using the key of the POS the order actually used, recorded on the order itself — with more than one POS, verifying against the wrong key produces a hash error on every single payment.

The card never reaches your database. It is held in the browser for the length of the redirect and removed afterwards. If it is not there when the pay page loads — a new tab, a refresh, storage disabled, a back-navigation from the bank — a visible card form is shown instead of sending empty fields to the bank. The card form is visible by default, on purpose: a payment flow cannot depend on JavaScript having run.

When the bank approves the payment, the order is completed even if the 3-D status code was unexpected — an order note records the anomaly and asks you to confirm it from the bank’s own screen. If the bank says approved, the customer has been charged; refusing that would mean “your card was charged but your order failed”.

Each attempt records the POS used, the card’s bank and BIN, the instalment count and rate, the result, the bank’s response code and message, and the authorisation and transaction references.

Reports

The Raporlar tab shows revenue, successful transactions, success rate and the single-charge vs instalment split, with a daily chart. Transactions still waiting for the bank to return are counted separately and left out of the success rate.

The free edition reports on a fixed 30-day window. Pro adds 7 / 30 / 90 day ranges and three breakdowns:

  • Instalment and commission load — count, revenue and commission burden per instalment tier.
  • POS and bank breakdown — revenue, successes, failures and success rate for each POS and for each issuing bank.
  • Decline code distribution — with CSV export. A repeating decline code points at something you can fix: insufficient funds is the customer’s problem, but 3-D verification and POS configuration errors are yours.

The data behind the reports is collected by the free plugin, so history keeps accruing whether or not you have Pro. It has to be that way: past data cannot be generated retroactively when you upgrade.

A freshly installed store has no chart. Recording begins with the plugin, and the screen fills after the first payment attempt.

Bank requests and support

Banka Talebi
Lists every institution that is not implemented yet, with the reason: either the protocol family has not been determined, or the family is known and we are waiting for documentation. You can open a request for one, or name an institution that is not in the list at all.
Destek
A subject, the POS or bank concerned, what happens when you do what, and the error message the bank showed.

The support form asks you not to include a card number or security code. They are never needed to diagnose a payment problem, and no payment or card data is sent with either form.

The free plugin contacts our servers only when you press one of these buttons. Nothing is sent on a schedule and there is no licence call at all in the free edition.

Free and Pro

The split is in quantity, not capability. All thirteen institutions, 3-D Secure, test mode, unlimited transaction volume and the basic revenue report are in the free edition.

Free
One POS. Up to three instalments shown to the customer. A fixed 30-day revenue summary. The BIN table packaged with the plugin.
Pro
Unlimited POS records — and therefore BIN routing. Up to twelve instalments. Report ranges and the POS, bank, instalment and decline-code breakdowns, with CSV export. Weekly live BIN refresh. Automatic updates for the Pro plugin itself.

When a licence expires or is absent:

  • Your store keeps taking payments. There is no licence check anywhere on the payment path. Cutting off a shop’s revenue is not an acceptable way to send a renewal reminder.
  • The default POS keeps working, 3-D Secure and test mode included.
  • Extra POS records go dormant but are never deleted, credentials included. They resume on renewal.
  • The instalment ceiling drops back to three. Rates you entered above it are kept, not cleared.
  • Reports fall back to the 30-day summary. Collected history is not deleted.
  • The live BIN refresh stops; the packaged table keeps working.

If our servers are unreachable, an active licence keeps working for seven days on the strength of the last successful check. But a licence whose own expiry date has passed reads as expired regardless — otherwise blocking our address would be a way to extend a licence by a week.

When something does not work

The bank refuses every payment with no useful message
Almost always the signature. A wrong signature raises no error anywhere — the bank simply declines. Check the merchant number, the store key, and any extra credentials for that family: they all go into the signature. A useful test is that banks answer a signature error and an invalid card differently; getting an “invalid card” message means your signature is right.
“Hash error” on the way back, with more than one POS
The return is a separate request with no session. MevvPos records which POS an order used and verifies with that key. If you deleted the POS record an order was paid through, verification falls back to the default POS and can fail.
The customer reaches a blank pay page, or the Öde button does nothing
A caching or optimisation plugin is deferring scripts. On LiteSpeed, exclude mevvpos, jquery and the WooCommerce frontend scripts from the delay list. The card form is shown by default so the flow still works, but the automatic redirect does not.
The order stays “pending” after a successful payment
The bank or provider did not reach the callback address. Check that ?wc-api=mevvpos_callback is reachable from outside — a maintenance mode, an IP restriction or a login wall in front of the site will block it.
The payment form posts back to the same page
The Gate URL field is empty for a bank whose address is not pre-filled. Enter the address your bank or provider gave you.
Test mode is on but the payment still goes to the live bank
Test mode stops the automatic redirect and shows you the request; it does not rewrite the gateway address for the NestPay banks. Put your bank’s test address into Gate URL while you are testing.
Instalments do not appear
Either the rate for that count is empty rather than zero, the card is from another bank, or you are above the free edition’s ceiling of three.
Cards go to the wrong POS after an upgrade
Older versions carried hand-written BIN ranges that were partly wrong. Check that each POS is filed under the bank it is really with.
The admin screen looks unstyled, or a fix does not appear
A stale browser cache. Reload the page bypassing the cache.

Limits

The list below is deliberate. None of it is a bug.

  • No refunds or cancellations from WordPress. The plugin does not implement WooCommerce’s refund API and no provider carries a refund call. Refund from your bank’s own screen.
  • Turkish lira only. The currency code is fixed in every provider; there is no multi-currency setting.
  • No saved cards, no tokenisation, no subscriptions or recurring payments.
  • No pre-authorisation. Every transaction is a direct sale.
  • No rule-based routing. Routing is by issuing bank only — not by amount, card brand or country.
  • The payment form is written for the classic WooCommerce checkout. No separate component for the block-based Checkout is shipped in the package.
  • 3D Pay Hosting was rejected on purpose. The hosted page removes PCI scope but also removes the BIN and the instalment table — and the entire value of this plugin is in the routing they make possible.
  • No BIN editor. The table is managed by us and merged with the live refresh; there is no screen for editing it by hand.
  • Twenty-six institutions are listed but not implemented. They stay visible so the gap is visible.
  • Every provider except NestPay is self-declared beta until it has been verified end to end with a live merchant account.
  • The tabs are in-page. The sidebar entries open the MevvPos screen; switch tabs on the page itself.

What is never stored, in any form: the card number, the expiry date and the security code. The only card data kept is the first six digits and the bank they identify. Storing the security code is forbidden under every circumstance, and even a masked one leaks its length.