Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Nexi Pos Api

БесплатноНе проверен

An MCP server for Nexi POS payment operations, enabling creation of purchases and refunds, polling payment states, confirming transactions, and recovering uncon

GitHubEmbed

Описание

An MCP server for Nexi POS payment operations, enabling creation of purchases and refunds, polling payment states, confirming transactions, and recovering unconfirmed transactions.

README

MVP MCP server for Nexi POS payment operations.

It provides tools to create purchases and refunds, poll payment state, confirm transactions, recover unconfirmed transactions, check terminal status, and list terminal events.

Setup

From npm package

npm install -g mcp-nexi-pos-api
mcp-nexi-pos-api

From source

npm install
npm run build
npm start

Minimum working config

You need Nexi POS API credentials before you can use the server:

  • NEXI_POS_API_KEY_ID
  • NEXI_POS_API_KEY_SECRET
  • a Nexi POS terminal ID

The terminal ID is generated together with the API key ID and API key secret. Credential and terminal generation is outside this MCP server for now. Get these values from Nexi API documentation before starting the server.

The smallest useful .env file is:

NEXI_POS_API_KEY_ID=your-api-key-id
NEXI_POS_API_KEY_SECRET=your-api-key-secret
NEXI_POS_TERMINAL_ID=your-terminal-id

NEXI_POS_TERMINAL_ID is optional. It is used as an environment fallback when a tool call does not include terminal_id and no session terminal has been set with set_terminal_id. It has no default value.

A fuller local .env file can include:

NEXI_POS_API_KEY_ID=your-api-key-id
NEXI_POS_API_KEY_SECRET=your-api-key-secret
NEXI_POS_TERMINAL_ID=your-terminal-id
NEXI_POS_BASE_URL=https://api.sandbox.npay.eu/pos/v1
NEXI_POS_DEFAULT_CURRENCY=SEK
NEXI_POS_MAX_AMOUNT_MINOR=100021
NEXI_POS_USER_AGENT=mcp-nexi-pos-api/0.1.4
NEXI_POS_STORAGE_PATH=./data/nexi-pos.sqlite
NEXI_POS_REQUEST_TIMEOUT_SECONDS=30

Environment variables

Variable Description Default
NEXI_POS_API_KEY_ID Nexi Basic Auth username. Generated outside this MCP server. Required
NEXI_POS_API_KEY_SECRET Nexi Basic Auth password. Generated outside this MCP server. Required
NEXI_POS_TERMINAL_ID Optional terminal ID fallback when no tool terminal_id or session terminal ID is available. Generated with the API credentials. No default
NEXI_POS_BASE_URL Nexi POS API base URL. https://api.sandbox.npay.eu/pos/v1
NEXI_POS_DEFAULT_CURRENCY Currency used when a tool omits currency. SEK
NEXI_POS_MAX_AMOUNT_MINOR Safety limit in minor units. Defaults high enough for Nexi test-case amounts. 100021
NEXI_POS_USER_AGENT User agent sent to Nexi. mcp-nexi-pos-api/0.1.4
NEXI_POS_STORAGE_PATH SQLite file for local recovery state. ./data/nexi-pos.sqlite
NEXI_POS_REQUEST_TIMEOUT_SECONDS Hard timeout for each HTTP request to Nexi. 30

Claude Desktop config

Minimum example for a global npm install:

{
  "mcpServers": {
    "nexi-pos": {
      "command": "mcp-nexi-pos-api",
      "env": {
        "NEXI_POS_API_KEY_ID": "your-api-key-id",
        "NEXI_POS_API_KEY_SECRET": "your-api-key-secret",
        "NEXI_POS_TERMINAL_ID": "your-terminal-id"
      }
    }
  }
}

Fuller example for a global npm install:

{
  "mcpServers": {
    "nexi-pos": {
      "command": "mcp-nexi-pos-api",
      "env": {
        "NEXI_POS_API_KEY_ID": "your-api-key-id",
        "NEXI_POS_API_KEY_SECRET": "your-api-key-secret",
        "NEXI_POS_TERMINAL_ID": "your-terminal-id",
        "NEXI_POS_BASE_URL": "https://api.sandbox.npay.eu/pos/v1",
        "NEXI_POS_DEFAULT_CURRENCY": "SEK",
        "NEXI_POS_MAX_AMOUNT_MINOR": "100021",
        "NEXI_POS_STORAGE_PATH": "/absolute/path/to/data/nexi-pos.sqlite"
      }
    }
  }
}

Example from source:

{
  "mcpServers": {
    "nexi-pos": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-nexi-pos-api/dist/index.js"],
      "env": {
        "NEXI_POS_API_KEY_ID": "your-api-key-id",
        "NEXI_POS_API_KEY_SECRET": "your-api-key-secret",
        "NEXI_POS_TERMINAL_ID": "your-terminal-id"
      }
    }
  }
}

Amount format

All amounts are integers in ISO 4217 minor units. Do not send floating point values.

Examples:

  • SEK 1.00 = 100
  • EUR 1.00 = 100
  • JPY 1 = 1

The default max amount is 100021, meaning SEK/EUR 1000.21. This allows the documented Nexi simulator/test-case amounts. Set NEXI_POS_MAX_AMOUNT_MINOR to a lower value if your environment should block larger test amounts.

External IDs

external_id is your unique order or payment ID. Use a value that lets you find the payment later, for example order-1001-payment-1.

Rules:

  • Use one unique external_id for one transaction.
  • Reuse the same external_id only when retrying the same transaction after a timeout, restart, or network problem.
  • Use a new external_id for a new order, a new payment attempt, or a different amount.

Reusing an old external_id for a different amount or order can return the old transaction or fail because Nexi treats it as the same transaction request.

Tools

  • set_terminal_id - store a terminal ID for this MCP server session.
  • get_session_terminal_id - show the current session terminal ID.
  • clear_terminal_id - clear the session terminal ID.
  • list_test_cases - list documented Nexi simulator/test cases and their trigger amounts.
  • create_purchase - low-level purchase call. Can use requested_amount or named test_case.
  • take_payment - recommended normal purchase flow. It creates/polls a purchase until Nexi leaves PROCESSING or the timeout is reached. Can use requested_amount or named test_case.
  • create_refund - low-level refund call.
  • confirm_transaction - confirm a purchase or refund result.
  • get_transaction - fetch a transaction by external_id and terminal.
  • get_unconfirmed_transactions - list unconfirmed transactions for a terminal.
  • get_terminal_status - fetch terminal connection, transaction state, screen, and battery status.
  • list_terminal_events - list terminal event stream entries, optionally filtered by event type.

Response guide

All tool responses use this JSON shape:

{
  "ok": true,
  "operation": "take_payment",
  "terminal_id": "terminal-1",
  "external_id": "order-123",
  "state": "AWAITING_CONFIRM",
  "result_code": "SUCCESS",
  "result_description": "Approved",
  "success": true,
  "message": "Payment flow stopped at terminal/current state",
  "user_message": "The card step succeeded, but the transaction is not complete until it is confirmed.",
  "next_action": "Call confirm_transaction to complete the transaction.",
  "summary": {
    "amount": 500,
    "currency": "SEK",
    "state": "AWAITING_CONFIRM",
    "result_code": "SUCCESS",
    "reference": "reference-from-nexi",
    "masked_card": "************0010"
  },
  "transaction": {},
  "raw": {}
}

Field meanings:

  • ok: the MCP tool call was handled. It does not always mean that the card payment succeeded.
  • success: the payment/refund result was successful. This is true only when result_code is SUCCESS.
  • state: the current Nexi transaction state, for example PROCESSING, AWAITING_CONFIRM, CONFIRMED, or COMMITTED.
  • result_code: the payment/refund result from Nexi, when available.
  • summary: short user-friendly payment details. Use this before inspecting raw.
  • user_message: important human-readable warning or context.
  • next_action: suggested next step, for example poll again, confirm, or no action needed.
  • test_case: included when requested_amount matches a documented Nexi simulator/test case, or when test_case was used as input.
  • raw: full Nexi response for debugging and integrations.

Normal payment flow

For most clients, use take_payment for purchases. It calls Nexi purchase repeatedly while the state is PROCESSING, until the total timeout_seconds is reached or Nexi returns a later state such as AWAITING_CONFIRM, CONFIRMED, or COMMITTED.

You can provide the terminal in three ways:

  1. pass terminal_id in the tool call;
  2. call set_terminal_id once for the session;
  3. set NEXI_POS_TERMINAL_ID as an environment fallback.

Recommended flow:

  1. Start a payment with take_payment.
  2. If the response state is AWAITING_CONFIRM, call confirm_transaction when your business flow is ready.
  3. If the response is still PROCESSING, retry later with the same external_id and terminal ID.

Examples

Take a 5 SEK payment

Tool: take_payment

{
  "external_id": "order-1001-payment-1",
  "requested_amount": 500,
  "currency": "SEK",
  "timeout_seconds": 60
}

Run a named Nexi test case

Tool: take_payment

{
  "external_id": "test-issuer-error-1",
  "test_case": "issuer_error",
  "currency": "SEK",
  "timeout_seconds": 60
}

The tool maps issuer_error to requested_amount: 100006. You can also use descriptions or aliases, for example "bank declined".

To list supported names and descriptions, call list_test_cases:

{}

Confirm payment

Tool: confirm_transaction

{
  "external_id": "order-1001-payment-1",
  "result_code": "SUCCESS"
}

Refund 5 SEK

Tool: create_refund

{
  "external_id": "order-1001-refund-1",
  "requested_amount": 500,
  "currency": "SEK",
  "original_purchase_external_id": "order-1001-payment-1"
}

Purchase with environment terminal

Set NEXI_POS_TERMINAL_ID in the environment, then omit terminal_id in the tool call.

Tool: create_purchase

{
  "external_id": "order-1002-payment-1",
  "requested_amount": 500,
  "currency": "SEK"
}

Purchase with explicit terminal

Tool: create_purchase

{
  "terminal_id": "your-terminal-id",
  "external_id": "order-1003-payment-1",
  "requested_amount": 500,
  "currency": "SEK"
}

Recovery after restart

If the server restarts during a payment, use the same external_id and terminal ID.

Tool: get_transaction

{
  "terminal_id": "your-terminal-id",
  "external_id": "order-1001-payment-1"
}

Then check unconfirmed transactions.

Tool: get_unconfirmed_transactions

{
  "terminal_id": "your-terminal-id"
}

You can also check the terminal status.

Tool: get_terminal_status

{
  "terminal_id": "your-terminal-id"
}

If a transaction is waiting for confirmation, confirm it.

Tool: confirm_transaction

{
  "terminal_id": "your-terminal-id",
  "external_id": "order-1001-payment-1",
  "result_code": "SUCCESS"
}

List terminal events

Tool: list_terminal_events

{
  "terminal_id": "your-terminal-id",
  "event_type": "eu.npay.api.pos.v0.TerminalStatus",
  "limit": 20,
  "wait_seconds": 30
}

If wait_seconds is omitted, the tool uses short polling with 0. Set a positive wait_seconds value for long polling.

Use next_token from a previous response to continue the same event list. When next_token is sent, the server does not send a new filter because Nexi keeps the previous filtering criteria.

{
  "terminal_id": "your-terminal-id",
  "next_token": "token-from-previous-response",
  "limit": 20,
  "wait_seconds": 30
}

Confirmation

This MVP does not confirm by default.

When a transaction reaches AWAITING_CONFIRM, call confirm_transaction:

{
  "external_id": "order-1001-payment-1",
  "result_code": "SUCCESS"
}

You can also let take_payment confirm automatically:

{
  "external_id": "order-1002-payment-1",
  "requested_amount": 500,
  "auto_confirm": true
}

Use auto_confirm only when your business flow is ready to accept the transaction result immediately.

SQLite storage and recovery

The server stores payment-relevant state in SQLite at NEXI_POS_STORAGE_PATH.

Stored data includes:

  • external ID
  • terminal ID
  • transaction type
  • currency
  • requested amount
  • state
  • result code and description
  • confirmation flag
  • timestamps
  • redacted raw transaction JSON

API credentials are never stored. Card-related fields should be redacted by the storage/client layer.

Recovery workflow after a restart:

  1. Call set_terminal_id if the session terminal ID was lost and you do not use NEXI_POS_TERMINAL_ID.
  2. Call get_transaction with the known external_id.
  3. Call get_unconfirmed_transactions for the terminal.
  4. If needed, call confirm_transaction with the correct result_code.

SQLite improves recovery, but it is not a full production operations system. Keep your own order records and reconcile with Nexi when needed.

Troubleshooting

HTTP 401 or 403

Check NEXI_POS_API_KEY_ID and NEXI_POS_API_KEY_SECRET. Also check that the credentials are valid for the selected NEXI_POS_BASE_URL environment, for example sandbox versus production. The credentials and terminal ID are generated outside this MCP server.

Missing terminal ID

Pass terminal_id in the tool call, call set_terminal_id, or set NEXI_POS_TERMINAL_ID. There is no default terminal ID.

Amount exceeds max

The server blocks amounts above NEXI_POS_MAX_AMOUNT_MINOR. Lower requested_amount or raise NEXI_POS_MAX_AMOUNT_MINOR for your environment. Amounts are minor units, so SEK 5.00 is 500. The default 100021 allows Nexi's documented test-case trigger amounts.

Transaction stuck in PROCESSING

Do not create a new transaction immediately. Retry take_payment with the same external_id and terminal ID, or call get_transaction. If it remains in PROCESSING, check the terminal and Nexi status before deciding whether to start a new payment with a new external_id.

Transaction awaiting confirm

If state is AWAITING_CONFIRM, the card step has succeeded but the transaction is not complete. Call confirm_transaction with the same external_id and terminal ID when you are ready to accept the result. You can also use auto_confirm with take_payment for flows where immediate confirmation is correct.

Reused external_id

Use the same external_id only to retry the same transaction. If the order, amount, or payment attempt is different, use a new external_id.

Nexi simulator/test cases

Nexi documents special test-case amounts that can be used in sandbox and production simulator testing. The server detects these amounts and adds test_case information to responses. You can also trigger them by name or description with test_case instead of remembering the amount.

Examples:

  • test_case: "instant_success" -> requested_amount: 100002
  • test_case: "bank declined" -> requested_amount: 100006
  • requested_amount: 100017 -> response includes the 10% tip test-case information

Available cases:

Name Amount Category Description
successful_2s_delay 100001 success Successful transaction with 2-second delay
instant_success 100002 success Instant successful transaction (0 seconds)
rejected_by_processor 100003 error Transaction rejected by payment processor
customer_cancelled 100004 error Transaction aborted (customer cancelled)
card_removed 100005 error Card removed during processing
issuer_error 100006 error Issuer error (bank declined)
internal_system_error 100007 error Internal system error
network_connectivity_error 100008 error Network connectivity error
payment_method_not_accepted 100009 error Card/payment method not accepted
contactless_pin_verified 100010 payment_method Successful PIN-verified contactless transaction
contactless_cardholder_verification 100011 payment_method Successful contactless with cardholder verification
chip_without_pin 100012 payment_method Successful chip card without PIN
chip_with_pin 100013 payment_method Successful chip card with PIN
magstripe_signature 100014 payment_method Successful magnetic stripe with signature
magstripe_pin 100015 payment_method Successful magnetic stripe with PIN
chip_with_pin_alternative 100016 payment_method Successful chip card with PIN (alternative mode)
tip_10_percent 100017 special_feature Successful transaction with 10% tip added
surcharge_1_5_percent 100018 special_feature Successful transaction with 1.5% surcharge
dcc_enabled 100019 special_feature Successful transaction with Dynamic Currency Conversion enabled
success_30s_delay 100020 success Successful transaction with 30-second delay
loyalty_link_identity 100021 special_feature Successful transaction with Nexi Loyalty Link customer identity in response

Implementation notes for integration

The MCP tool layer expects these core modules to exist:

  • src/config.ts exporting getConfig() with API, currency, terminal fallback, max amount, request timeout, and storage path settings.
  • src/nexi-client.ts exporting NexiClient with purchase, refund, confirm, getTransaction, getUnconfirmedTransactions, getTerminalStatus, and listTerminalEvents methods.
  • src/storage/sqlite-store.ts exporting SQLiteStore with saveIntent, updateTransaction, and markConfirmed methods.

These modules are intentionally separate from the MCP tool code so the API client and storage can be tested independently.

from github.com/Knoseman/mcp-nexi-pos-api

Установка Nexi Pos Api

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/Knoseman/mcp-nexi-pos-api

FAQ

Nexi Pos Api MCP бесплатный?

Да, Nexi Pos Api MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Nexi Pos Api?

Нет, Nexi Pos Api работает без API-ключей и переменных окружения.

Nexi Pos Api — hosted или self-hosted?

Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.

Как установить Nexi Pos Api в Claude Desktop, Claude Code или Cursor?

Открой Nexi Pos Api на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Nexi Pos Api with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории finance