Medusa Ledger · Concept
← Landing Storage SPEC API manual GitHub

Concept — developer guide

The OSS demo does not simulate a commercial tenant. It shows one fundamental thing: how a system turns a business fact into verifiable, immutable evidence. An event is a fact in the application that deserves to be proven later. Medusa does not decide what matters — the developer does.

You define the event. Medusa makes it verifiable.

1. What is an event?

An event is not necessarily a payment. It is a fact that occurred in a system and that later must be shown exactly as it was recorded. The ledger does not need to know what the event means.

EVENT │ ├── eventId ├── eventType ├── timestamp ├── payload └── metadata ↓ HASH SHA-256 ↓ BLOCK ↓ CHAIN

Medusa is not the business. Medusa is the layer that says: this fact was registered this way, at this time, and the evidence was not altered.

2. Commercial example (Cloud)

Tuk Tuk on Medusa Cloud is a live commercial example: payment captures from a payment platform become ledger events on a tenant chain. That is the hosted product, not the OSS demo. See the Medusa Cloud landing.

In that product path a captured payment looks like:

{
  "eventId": "pay-84721",
  "eventType": "PAYMENT_CAPTURED",
  "amount": 50000,
  "currency": "COP",
  "reference": "ORDER-9182"
}

The OSS download does not need that tenant, that payment provider, or that ERP. The next sections use generic shop events so the Core can be tried on a laptop.

3. Developer demo: ORDER_CREATED / PAYMENT_RECEIVED

After docker compose up, any small domain works: a shop, a warehouse, an ERP module. Typical first events:

Medusa does not “record payments.” It records events from the application.

git clone https://github.com/wbsckt3/medusa-ledger.git
cd medusa-ledger
docker compose up --build
curl -X POST http://localhost:8080/api/events \
  -H "Content-Type: application/json" \
  -d '{
    "eventId": "order-001",
    "eventType": "ORDER_CREATED",
    "payload": {
      "customerId": "customer-42",
      "amount": 50000,
      "currency": "COP"
    }
  }'

Response:

{
  "success": true,
  "eventId": "order-001",
  "block": 1,
  "hash": "a7f92..."
}
curl -X POST http://localhost:8080/api/events \
  -H "Content-Type: application/json" \
  -d '{
    "eventId": "payment-001",
    "eventType": "PAYMENT_RECEIVED",
    "payload": {
      "orderId": "order-001",
      "amount": 50000,
      "currency": "COP"
    }
  }'

4. Verify integrity

The first magic moment of the demo is a green verify after two facts:

curl http://localhost:8080/api/verify
{
  "valid": true,
  "blocks": 2,
  "message": "Ledger integrity verified"
}

Two events are now sealed. The next section shows how they link.

5. See the chain

curl http://localhost:8080/api/ledger/show
MEDUSA LEDGER Block #0 GENESIS hash: 000000... ↓ Block #1 ORDER_CREATED eventId: order-001 previousHash: 000000... hash: a7f92c... ↓ Block #2 PAYMENT_RECEIVED eventId: payment-001 previousHash: a7f92c... hash: 91b83d... ↓ ✓ CHAIN VALID

Visual reading: event → hash → block → previousHash → next block. That is the blockchain idea without a separate lecture.

6. Detect tampering

Suppose a stored amount changes from 50000 to 90000. The block hash no longer matches.

Block #2 │ ├── previousHash ✓ ├── payload ✗ └── hash ✗
curl http://localhost:8080/api/verify
{
  "valid": false,
  "block": 2,
  "reason": "Hash mismatch"
}

Second magic moment: not “there is a blockchain,” but “an altered historical fact is detectable.”

7. Event, payload, evidence, block, chain

Keep these layers separate. Medusa works on evidence and the chain, not on business rules.

Layer Example
Event PAYMENT_RECEIVED
Payload {"orderId":"ORDER-123","amount":50000}
Evidence SHA-256(...)
Block Block #17
Chain #15 → #16 → #17 → #18

The application owns event types and payloads. Medusa owns hashes, blocks, and verify.

8. Same Core, many domains

The Core does not need to know any of these vocabularies. That is the value of a protocol instead of a vertical app.

9. YOUR APPLICATION diagram

YOUR APPLICATION │ │ "Something happened" ▼ MEDUSA CORE │ ├── event ├── timestamp ├── payload │ ▼ SHA-256 │ ▼ BLOCK │ ▼ LEDGER │ ▼ VERIFY

You define the event. Medusa makes it verifiable.

Where the files live, and how Node appends while Spring verifies the same chain, is covered in the Storage SPEC.

10. CLI without a UI

No second application is required. After the container is up:

node bin/medusa.js event create --type PAYMENT_RECEIVED --id payment-001 --amount 50000
node bin/medusa.js ledger verify
node bin/medusa.js ledger show

Append result:

✓ Event appended

Event:     PAYMENT_RECEIVED
ID:        payment-001
Block:     12
Hash:      9d4f...
Timestamp: 2026-08-14T00:21:32Z

Verify result:

MEDUSA LEDGER

Blocks: 12
Events: 11

✓ Genesis block
✓ Hash chain
✓ Previous hashes
✓ Event integrity

LEDGER VALID
MEDUSA CORE "Make events verifiable" │ ┌────────┴────────┐ Developer Enterprise Docker OSS Medusa Cloud Own events Business events Own ledger Tenant ledger CLI / API Dashboard + WL + payment anchors + ERP

Core OSS contains blocks, hashes, events, and verify. Cloud adds multi-tenant, white-label, payment anchors, analytics, and ERP connectors. Product site: medusa-ledger-business.