On this pageArchitectureQuick Start (Go)Quick Start (Java)Run the FrontendDatabase ConfigurationLocal Development with ngrokKey Implementation DetailsMulti-chain SupportWebhook HandlingPayment Page Redirect

Demo Shop ​

HashNut provides fully working demo merchant applications that demonstrate the complete payment integration flow. Use them as a reference for your own implementation.

ComponentLanguageRepository
Demo Backend (Go)Go + Ginhashnut-demo-go
Demo Backend (Java)Java + Spring Boothashnut-demo
Demo FrontendReact + TypeScripthashnut-demo-web

Both backends implement the same API contract — the frontend works with either one.

Architecture ​

Browser (localhost:5173)           Demo Backend (localhost:1800)          HashNut API
        |                                   |                                |
        |  GET /api/products                |                                |
        |---------------------------------->|                                |
        |  GET /api/chains                  |                                |
        |---------------------------------->|  (reads from DB)               |
        |                                   |                                |
        |  POST /api/orders                 |                                |
        |  {productId, chainCode, coinCode} |                                |
        |---------------------------------->|  SDK.createOrder()             |
        |                                   |------------------------------->|
        |                                   |  payOrderId + receiptAddress   |
        |  payUrl (redirect to HashNut)     |<-------------------------------|
        |<----------------------------------|                                |
        |                                   |                                |
        |  (user pays on HashNut page)      |                                |
        |                                   |  POST /api/notify (webhook)    |
        |                                   |<-------------------------------|
        |                                   |  update order status           |
        |                                   |                                |
        |  redirect to /payment-result      |                                |
        |  (frontend shows success)         |                                |

Quick Start (Go) ​

bash
# 1. Clone
git clone https://github.com/nuttybounty/hashnut-demo-go.git
cd hashnut-demo-go

# 2. Setup database
psql -U postgres -c "CREATE DATABASE demo_shop;"
# Edit migrate.sql — fill in your API credentials in t_hashnut_api_key
psql -U postgres -d demo_shop -f migrate.sql

# 3. Edit etc/application.yaml if needed

# 4. Run
go run main.go

Quick Start (Java) ​

bash
# 1. Clone
git clone https://github.com/nuttybounty/hashnut-demo.git
cd hashnut-demo

# 2. Setup database
psql -U postgres -c "CREATE DATABASE demo_shop;"
# Edit migrate.sql — fill in your API credentials in t_hashnut_api_key
psql -U postgres -d demo_shop -f migrate.sql

# 3. Edit src/main/resources/application.yml if needed

# 4. Run (SDK is downloaded automatically via JitPack)
mvn spring-boot:run

Run the Frontend ​

Both backends serve the same API, so the same frontend works with either:

bash
git clone https://github.com/nuttybounty/hashnut-demo-web.git
cd hashnut-demo-web
npm install
npm run dev

Open http://localhost:5173 in your browser.

Database Configuration ​

The demo uses PostgreSQL with these tables:

TablePurpose
t_coin_infoSupported chains and coins (displayed in frontend)
t_hashnut_api_keySplitter address + API credentials per chain
productsDemo products (price only, no chain binding)
ordersOrders with user-selected chain + coin

Edit migrate.sql before running to configure your supported chains:

sql
-- Which chains and coins to display in the frontend
INSERT INTO t_coin_info (chain_code, coin_code, chain_label, coin_label, contract_address, decimals) VALUES
    ('erc20', 'usdt', 'Ethereum', 'USDT', '0xdAC17F958D2ee523a2206206994597C13D831ec7', 6),
    ('trc20', 'usdt', 'Tron',     'USDT', 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',         6);

-- Your API credentials per chain (each chain has its own splitter)
INSERT INTO t_hashnut_api_key (chain_code, splitter, access_key_id, secret_key) VALUES
    ('erc20', '0xYourEthSplitter',  'your-access-key-id', 'your-secret-key'),
    ('trc20', 'TYourTronSplitter',  'your-access-key-id', 'your-secret-key');

Local Development with ngrok ​

For HashNut to send payment notifications to your local machine:

bash
ngrok http 1800

Then configure your HashNut API Key:

FieldLocal DevelopmentProduction
notifyURLhttps://xxxxx.ngrok-free.dev/api/notifyhttps://your-domain.com/api/notify
callbackURLhttp://localhost:5173/payment-resulthttps://your-domain.com/payment-result

TIP

notifyURL is a server-to-server webhook — it must be publicly accessible (use ngrok).

callbackURL is a browser redirect — use localhost:5173 for local dev since the browser redirects locally.

Key Implementation Details ​

Multi-chain Support ​

Products are not bound to a specific chain. The frontend lets users choose which chain and coin to pay with, and passes chainCode + coinCode in the order request. The backend looks up the corresponding splitter and API key from the database.

Webhook Handling ​

The /api/notify endpoint receives payment notifications from HashNut. Your handler must:

  1. Parse the JSON payload (payOrderId, state, payTxId)
  2. Update the order status in your database
  3. Return the string "success" (HTTP 200) to acknowledge receipt

If you don't return "success", HashNut will retry the notification.

Payment Page Redirect ​

When an order is created, the backend returns a payUrl pointing to the HashNut payment page. The frontend redirects the user there. After payment, the user is redirected back to your callbackURL with query parameters including state and merchantOrderId.