Partner POS API

Nuvio Partner POS API

The Nuvio Partner POS API allows external POS systems to integrate Nuvio loyalty without accessing internal terminal endpoints.

Nuvio acts as a headless loyalty service. The POS system remains the source of truth for checkout, pricing, and fiscalization.

Quick Start

  1. Pair the POS installation with POST /pair.
  2. Read the loyalty card with POST /card.
  3. Commit the final sale with POST /transaction.
POST /card
{
  "cardToken": "DISC00000000000000000000"
}
JavaScript example
// Read card
const cardResponse = await fetch('/card', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer pos_xxx',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ cardToken })
})

const card = await cardResponse.json()

// Apply discount locally
if (card.programType === 'DISCOUNT') {
  applyDiscount(card.discountPercent)
}

// Commit transaction
await fetch('/transaction', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer pos_xxx',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    transactionId,
    cardToken,
    type: 'ADD',
    amountOriginal,
    amountPaid,
    status: 'CONFIRMED'
  })
})

Environments

Environment Base URL Usage
PROD https://loyalty.nuvio.group/api/pos/v1 Use this for live partner installations.
DEV https://dev.loyalty.nuvio.group/api/pos/v1 Use this for integration work and validation.
Local http://localhost:3300/api/pos/v1 Use this for local wrapper development.
Route separation

Partners use only /api/pos/v1/*. Internal terminal routes stay private.

Authentication

Use a partner API key on every runtime request.

Authorization header
Authorization: Bearer pos_<api_key>
Route Authentication
POST /pair No partner key required.
POST /card Partner key required.
POST /rewards Partner key required.
POST /transaction Partner key required.
GET /health No authentication required.

Pairing

Pair each POS installation once. Store the returned API key securely.

  1. Open Nuvio settings in the POS back office.
  2. Enter the merchant pairing code.
  3. Call POST /pair.
  4. Store the returned partner key.
Pairing example
POST /api/pos/v1/pair

{
  "pairingCode": "1234-5678",
  "deviceFingerprint": "register-01",
  "source": "android-pos",
  "installationName": "Front counter"
}

200 OK

{
  "status": "PAIRED",
  "merchantId": "merch_demo_krk",
  "merchantName": "Nuvio Demo Merchant",
  "apiKey": "pos_xxxxxxxxxxxxxxxxxxxxxx",
  "baseUrl": "https://loyalty.nuvio.group/api/pos/v1"
}

Integration Model

Build a hidden loyalty adapter inside the partner POS.

Layer Partner builds Nuvio provides
Settings Pairing field and secure key storage. Merchant resolution and key issuance.
Runtime adapter HTTP client for /api/pos/v1/*. Loyalty logic and card state.
Cashier UI Prompts, tiles, and checkout controls. Reward availability and balances.
Checkout Discount, tenders, receipt close, fiscalization. Post-checkout accrual and redemption.
Integration rule

Nuvio owns loyalty state. The partner owns checkout and cashier UX.

Responsibilities

Concern Partner POS Nuvio
Card scanning Read scanner input and pass cardToken. Resolve token to active loyalty state.
Discount Apply price change locally. Return current discount entitlement.
Cashback Apply chosen cashback locally. Return balance and burn committed amount.
Rewards Show tiles and send selected reward id. Return eligibility and burn rewards.
Final commit Send final amounts after receipt close. Persist loyalty outcome.

Flow

  1. Pair the installation once.
  2. Scan the card during checkout.
  3. Call POST /card.
  4. Call POST /rewards for points or stamps.
  5. Apply local checkout changes.
  6. Close the receipt in the partner POS.
  7. Call POST /transaction with final values.
Recommended internal service boundary
Scanner input -> Partner loyalty adapter -> Nuvio Partner POS API
                                      |
                                      +-> Partner cashier UI
                                      +-> Partner checkout engine
                                      +-> Partner receipt close and fiscalization
                                      +-> Final transaction commit
POST /pair

Pair installation

Bind one POS installation to one merchant.

Request body

Field Type Required Description
pairingCodestringyesMerchant-issued code. Example: 1234-5678.
deviceFingerprintstringyesStable device or installation id.
sourcestringnoPartner source name.
installationNamestringnoHuman-readable register name.

Response body

FieldTypeDescription
statusstringExpected value: PAIRED.
merchantIdstringNuvio merchant id.
merchantNamestringMerchant display name.
apiKeystringPartner key for runtime calls.
baseUrlstringEnvironment base URL.

Status codes

StatusMeaning
200Pairing succeeded.
400Request is invalid.
404Pairing code is invalid or expired.
POST /card

Read card

Resolve the scanned card and return current loyalty state.

Request body

FieldTypeRequiredDescription
cardTokenstringyesScanned loyalty token or normalized card id.

Example: discount card

Discount response
{
  "merchantId": "merch_demo_krk",
  "cardToken": "DISC00000000000000000000",
  "programType": "DISCOUNT",
  "discountPercent": 10,
  "currentTier": "silver",
  "nextTier": "gold"
}

Example: cashback card

Cashback response
{
  "merchantId": "merch_demo_krk",
  "cardToken": "CASH0000000000000000000",
  "programType": "CASHBACK",
  "cashbackBalance": 3000,
  "cashbackRate": 10
}

Example: points card

Points response
{
  "merchantId": "merch_demo_krk",
  "cardToken": "POINT0000000000000000000",
  "programType": "POINTS",
  "pointsBalance": 320,
  "readyRewards": 2
}
POST /rewards

List rewards

List merchant-defined rewards for points or stamps cards.

Request body

FieldTypeRequiredDescription
cardTokenstringyesScanned loyalty token or normalized card id.

Example: points rewards

Points rewards response
{
  "merchantId": "merch_demo_krk",
  "cardToken": "POINT0000000000000000000",
  "member": {
    "points_balance": 320,
    "ready_rewards": 2
  },
  "rewards": [
    {
      "reward_id": "points_0_100",
      "name": "100 pts = Hot dog",
      "required_points": 100,
      "type": "POINTS"
    },
    {
      "reward_id": "points_1_200",
      "name": "200 pts = Coffee",
      "required_points": 200,
      "type": "POINTS"
    }
  ]
}

Example: stamps rewards

Stamps rewards response
{
  "merchantId": "merch_demo_krk",
  "cardToken": "STMP0000000000000000000",
  "member": {
    "stampsBalance": 10,
    "stampsRequired": 10,
    "readyRewards": 1
  },
  "rewards": [
    {
      "reward_id": "stamp_0_10",
      "name": "10 stamps = Ice cream scoop",
      "required_stamps": 10,
      "type": "STAMPS"
    }
  ]
}
POST /transaction

Commit transaction

Commit the final loyalty result after receipt close.

Request body

FieldTypeRequiredDescription
transactionIdstringyesPartner transaction id used for idempotency.
cardTokenstringyesCard token used in the sale.
typeenumyesADD, REDEEM, or REDEEM_REWARD.
amountOriginalintegerconditionalOriginal basket value in minor units.
amountPaidintegerconditionalFinal paid value in minor units.
cashbackUsedintegernoRedeemed cashback in minor units.
selectedRewardstringnoSelected reward identifier.
statusenumyesUsually CONFIRMED.
paymentMethodstringnoPartner-side payment method label.
metadataobjectnoPartner trace metadata.

Field rules by transaction type

TypeRequired fieldsOptional fields
ADD transactionId, cardToken, amountOriginal, amountPaid, status paymentMethod, metadata
REDEEM transactionId, cardToken, amountOriginal, amountPaid, cashbackUsed, status paymentMethod, metadata
REDEEM_REWARD transactionId, cardToken, selectedReward, status amountOriginal, amountPaid, paymentMethod, metadata

Example: discount commit

Discount transaction response
{
  "merchantId": "merch_demo_krk",
  "transactionId": "txn_1001",
  "cardToken": "DISC00000000000000000000",
  "status": "CONFIRMED",
  "programType": "DISCOUNT",
  "pointsEarned": 0,
  "pointsBalance": 0,
  "cashbackEarned": 0,
  "cashbackBalance": 0,
  "discountSavings": 2000
}

Example: cashback redeem

Cashback transaction response
{
  "merchantId": "merch_demo_krk",
  "transactionId": "txn_cashback_1002",
  "cardToken": "CASH0000000000000000000",
  "status": "CONFIRMED",
  "programType": "CASHBACK",
  "cashbackUsed": 3000,
  "cashbackBalance": 0,
  "amountPaid": 7000
}

Example: reward redemption

Reward transaction response
{
  "merchantId": "merch_demo_krk",
  "transactionId": "txn_reward_1003",
  "cardToken": "POINT0000000000000000000",
  "status": "CONFIRMED",
  "programType": "POINTS",
  "selectedReward": "points_0_100",
  "pointsBalance": 220
}
Idempotency

Reuse the same transactionId on every retry for the same receipt.

GET /health

Health check

Use this for deployment checks and runtime diagnostics.

Errors

All failures return the same JSON envelope.

Error envelope
{
  "error": {
    "code": "INVALID_INPUT",
    "message": "cardToken is required.",
    "requestId": "req_01JERR2YJ2V8"
  }
}
FieldTypeDescription
codestringStable machine-readable error id.
messagestringDeveloper-readable message.
requestIdstringCorrelation id for support.

Example: invalid pairing code

404 error
{
  "error": {
    "code": "PAIRING_CODE_INVALID",
    "message": "The provided pairing code is invalid or expired.",
    "requestId": "req_01JPAIR7Y8X4"
  }
}

Example: card not found

404 error
{
  "error": {
    "code": "CARD_NOT_FOUND",
    "message": "The scanned card could not be resolved for this merchant.",
    "requestId": "req_01JCARD4X1E0"
  }
}

Example: duplicate transaction

409 error
{
  "error": {
    "code": "TRANSACTION_ALREADY_PROCESSED",
    "message": "The transactionId was already processed for this merchant.",
    "requestId": "req_01JTXN9M4C1",
    "idempotentReplay": true
  }
}

Discount

  1. Scan the card.
  2. Call POST /card.
  3. Read discountPercent.
  4. Apply the reduction locally in checkout.
  5. Commit final values after receipt close.
StagePartner actionNuvio effect
Card readRead discount and tier data.Return active entitlement.
CheckoutReduce basket total locally.No local checkout calculation in Nuvio.
CommitSend final amounts.Update sale history and tier progression.

Cashback

  1. Scan the card.
  2. Call POST /card.
  3. Show available cashback balance.
  4. Ask whether cashback should be applied.
  5. Reduce the payable amount locally if accepted.
  6. Commit the exact used amount after receipt close.
Partial redemption example
Sale total: 100.00 PLN
Cashback available: 30.00 PLN

POS behavior:
- 30.00 PLN covered by cashback
- 70.00 PLN collected normally

Commit payload:
{
  "transactionId": "txn_cashback_1002",
  "cardToken": "CASH0000000000000000000",
  "type": "REDEEM",
  "amountOriginal": 10000,
  "amountPaid": 7000,
  "cashbackUsed": 3000,
  "status": "CONFIRMED"
}
BranchPartner actionTransaction typeNuvio effect
Cashback usedReduce payable amount locally.REDEEMBurn committed cashback amount.
Cashback not usedClose checkout normally.ADDAccrue new cashback after commit.

Points & Stamps

Nuvio owns balances, reward availability, accrual rules, and burn logic.

Program Read Display Commit
Points POST /card + POST /rewards Points balance and reward tiles. REDEEM_REWARD or ADD
Stamps POST /card + POST /rewards Stamp progress and reward tiles. REDEEM_REWARD or ADD
Recommended decision model
1. Call POST /card
2. If programType is POINTS or STAMPS, call POST /rewards
3. Render rewards as partner-owned tiles
4. If cashier selects a reward, commit REDEEM_REWARD
5. If no reward is selected, close checkout and commit ADD

Cashier UI

Partners keep their own visual style. They should keep the same decision points.

CARD READ Card resolved

Loyalty card resolved successfully

Show this when the card belongs to the current merchant.

CASHBACK PROMPT Operator decision

Apply available cashback to this sale?

Show available balance and the remaining payable amount.

REWARDS LIST Selectable items

Reward selection

Render points or stamps rewards as clickable partner-owned tiles.

Integration Checklist

Component Required implementation
Settings screenOne pairing field and secure partner key storage.
Loyalty adapterDedicated service layer for all /api/pos/v1/* calls.
Scanner inputStable cardToken normalization.
Cashier promptsLocal prompts for discount, cashback, and rewards.
Checkout integrationAbility to reduce basket amount locally.
Transaction commitOne final commit after receipt close.
Retry handlingReuse the same transactionId on retries.
Support loggingPersist request ids and wrapper error codes.
Not required

Partners do not need Nuvio styling, local loyalty balance storage, or direct terminal API access.

Monitoring

Control Requirement
Kill switchSupport global, partner-level, and merchant-level disable.
LoggingLog request id, partner id, merchant id, transaction id, and latency.
Rate limitingApply partner-level and merchant-level limits.
AuditabilityPersist pairing events, key issuance, and idempotent results.

Testing

Use DEV for all validation. There is no separate UAT environment.

Scenario Route sequence Expected result
Discount checkout /pair/card/transaction POS applies discount locally and commits final values.
Cashback partial redeem /pair/card/transaction Cashback covers part of the basket and burns only the committed amount.
Points reward redemption /pair/card/rewards/transaction Selected reward is burned and new balance is returned.
Stamp reward redemption /pair/card/rewards/transaction Ready reward is consumed after explicit cashier action.

Downloads

Use these files in the public Git package for partner handoff.

Artifact Location Purpose
Reference screens /reference-screens.html Cashier UI reference set.
Download package README /downloads/README.md Entry point for the public package.
Integration checklist /downloads/integration-checklist.md Build checklist for partner teams.
Testing scenarios /downloads/dev-validation-scenarios.md DEV validation scenarios.
JSON examples /downloads/json/... Request and response examples.
Reference integration sample /downloads/reference-integration-sample.md Suggested internal module layout.

Integration Package

Artifact Purpose
Download package READMEDefines the public package structure.
JSON request and response examplesGive engineers direct payload references.
Reference integration sampleShows the hidden virtual terminal module layout.
DEV validation card setSupports controlled validation in DEV.
Reference screen packGives product and engineering teams UI references.
Integration checklistSummarizes required platform work.