x4 Pay

ESP32 SDK + iOS/Android/Web3 app for tap-to-pay on Microcontrollers via BLE — one-time or auto-pay.

x4 Pay

Created At

ETHOnline 2025

Project Description

x4Pay lets physical devices (ESP32 microcontrollers with ~520KB RAM) accept on-chain payments over Bluetooth Low Energy (BLE) with tap-to-pay. No WiFi or server infra is required after setup — a phone connects over BLE, the device advertises available options (“Switch 1”, “Switch 2”, “Latte”, “Bike unlock”), returns a dynamic price, and the user signs/pays from x4Pay (mobile or web with WalletConnect/MetaMask).

On success, the signed transaction is chunked over BLE (200–500 byte MTU), reassembled on the ESP32, verified, and settled using our x402 protocol implementation. The device then triggers real-world actions (turn on motors, unlock relays, power a bike) via callbacks.

Core pieces:

X402Arduino C++ lib: build/verify/settle x402 payment requirements.

x4Pay-core C++ lib: Bluetooth x402 server with setDynamicPriceCallback, setOnPay, enableRecurring(frequencySec), enableOptions([...]), getStatusAndReset(), begin().

x4Pay app (iOS/Android/Web): tap-to-pay over BLE, multi-account wallet, PIN-secured keys, anti-overcharge checks.

Typical flows include vending machines, pay-per-minute bike rentals, and pay-as-you-go devices in Airbnb.

How it's Made

The firmware runs on ESP32 and uses our X402Ble + X402Arduino libraries to expose a standard x402 Bluetooth service UUID. In setup(), the microcontroller:

advertises a device profile (name, logo, banner, description, payout address, network),

registers selectable options (enableOptions(["Switch 1", "Switch 2"])),

enables recurring “pay-as-you-go” billing (enableRecuring(15) → request payment every 15s),

installs callbacks:

setOnPay(...) so the device can generate a dynamic price per user selection (e.g. Switch 1 costs 20000 wei, Switch 2 costs 10000 wei),

setDynamicPriceCallback(...) so after payment settles we get the tx hash, payer address, and user context.

In the loop(), we call getStatusAndReset(). When a new payment is detected, we read:

getLastTransactionhash()

getLastPayer()

getUserSelectedOptions() and then physically actuate hardware. In our demo we drive servos on GPIO pins 12/13/14/27 to flip mechanical switches (turn_S1_ON(), turn_S2_ON(), etc.). If the user stops paying (recurring payment times out), we cut power by calling the OFF routines.

On the client side, the x4Pay mobile app (React Native) / web app (React + Web Bluetooth + WalletConnect) discovers the BLE peripheral, shows branding (logo/banner/description), shows the available items, requests a dynamic quote, signs the transaction from the user’s wallet, and streams the signature back to the ESP32 in chunks.

This creates a fully local, serverless payment loop: phone ↔ BLE ↔ ESP32 ↔ relays/servos. Perfect for vending, rentals, and offline IoT commerce.

background image mobile

Join the mailing list

Get the latest news and updates