A Farcaster Frame that lets users pay with U.CASH Pay (crypto + cards). Non-custodial.
When a user opens the frame and taps the button, they are sent to a U.CASH Pay checkout where they can pay with crypto (BTC, ETH, USDC, and many more) or a fiat card. Funds settle directly to your own receive addresses. The frame itself never holds funds or private keys.
- A cast embeds this frame (the deployed
https://YOUR_HOST/URL). - Farcaster renders the frame image and the Pay with U.CASH button.
- Tapping the button POSTs to
/(the framepost_url). - The server builds a U.CASH Pay embed link from your publishable Store Cloud Token and returns a frame whose button opens that checkout (
fc:frame:button:1:action = link). - The user completes payment on pay.u.cash. Funds go to your configured receive addresses.
The store Cloud Token is publishable (designed to be used straight from the browser), so no server secret is required. This is non-custodial: the frame only constructs a link, it never moves funds.
index.js- Express app that serves the frame (GET /) and the button handler (POST /).package.json- npm manifest, depends only onexpress..env.example- all supported environment variables.
-
Clone and install:
git clone https://github.com/UdotCASH/farcaster-ucashpay.git cd farcaster-ucashpay npm install -
Copy the env template and fill in your details:
cp .env.example .env
At minimum set
CLOUD_TOKEN(your U.CASH Pay Store Cloud Token). Then setAMOUNT,CURRENCY, andTITLE. -
Run locally:
npm start # listening on http://localhost:3000 -
For Farcaster to render the frame, the server must be reachable over HTTPS at a public URL. Use a tunnel for local testing (e.g.
cloudflared,ngrok) or deploy to a host (see below).
- Sign up at pay.u.cash, then click the verification link in the email.
- Set receive addresses under Settings -> Addresses (raw address, ENS, Unstoppable Domains, or FIO).
- Create a store under Account -> Stores and copy its Store Cloud Token (use the store-level token, not the account-wide one).
- For fiat cards, connect your own Stripe under Settings -> Payment processors.
| Variable | Required | Default | Description |
|---|---|---|---|
CLOUD_TOKEN |
yes | U.CASH Pay store Cloud Token (publishable). | |
AMOUNT |
no | 1 |
Payment amount. |
CURRENCY |
no | USD |
ISO currency code. |
TITLE |
no | Pay with U.CASH |
Payment title shown on the checkout. |
EXTERNAL_REF |
no | random id | External reference used for idempotent tracking. |
REDIRECT_URL |
no | URL to redirect to after payment. | |
FRAME_IMAGE_URL |
no | /frame-image.png |
Public 1.91:1 image used as the frame image. |
PORT |
no | 3000 |
Port the server listens on. |
Any host that runs Node 18+ and serves HTTPS works. Examples:
- Create a new service from this repo.
- Set the environment variables (
CLOUD_TOKENetc.) in the host dashboard. - Build command:
npm install. Start command:npm start. - The host gives you a public HTTPS URL (e.g.
https://farcaster-ucashpay.onrender.com).
This Express app runs on Node hosts. For a pure serverless deploy, port index.js into a serverless function that returns the same frame HTML. The logic in GET / and POST / is the contract to preserve.
-
Point a domain (with HTTPS, e.g. via Caddy or nginx + Let's Encrypt) at the Node process.
-
Run it behind a process manager (
pm2,systemd):npm install --omit=dev CLOUD_TOKEN=st_xxx AMOUNT=5 CURRENCY=USD npm start
Once your frame is live at https://YOUR_HOST/:
- Open a Farcaster client (e.g. Warpcast).
- Compose a new cast and paste
https://YOUR_HOST/into the body. - The client fetches the page, reads the
fc:framemeta tags, and renders the frame preview with the Pay with U.CASH button. - Publish the cast. Anyone who sees it can tap the button and pay.
You can also validate the frame first with the Farcaster Frame playground or the open-source frame validators.
This frame uses two U.CASH Pay entry points:
Client-side hosted pay link (publishable cloud token, usable straight from the browser, no server secret):
GET https://pay.u.cash/embed.php
?cloud=<store cloud token>
&amount=<amount>
¤cy=<USD>
&title=<title>
&external_reference=<ref>
&redirect=<url>
Server-side tracked checkout (call from a server route; idempotent per external_reference):
POST https://pay.u.cash/payment/ajax.php
Content-Type: application/x-www-form-urlencoded
function=create-transaction
&amount=<amount>
¤cy_code=<USD>
&cryptocurrency_code=
&external_reference=<ref>
&title=<title>
&redirect=<url>
&cloud=<store cloud token>
&idempotent=1
Response JSON { success: true, response: [paymentUrl, transactionId, ...] }. The payment URL is the array element that starts with http(s)://.
POST / tries the server-side checkout first (for tracking) and falls back to the plain embed link if it fails, so the frame keeps working even if the AJAX route is unavailable.
- The frame creates a single payment for a fixed
AMOUNTper server configuration. Dynamic per-user amounts would require theexternal_referenceandamountto be derived per request (not implemented here to keep the frame stateless). - Automatic recurring crypto billing is not supported by U.CASH Pay. Fiat recurring billing via your own Stripe is outside this frame's scope.
- The frame image is served at
/frame-image.pngifFRAME_IMAGE_URLis unset. Provide your own 1.91:1 image for best results.
MIT. See LICENSE.