logo
Documentation

Get paid on Robinhood Chain

Everything the dashboard does, you can do from code. One contract, two stablecoins, receipts for every payment.

Quickstart

PUSHIN is one contract on Robinhood Chain (chain id 4663). There is nothing to sign up for: a wallet address is a merchant the moment it creates its first link.

  1. Open the dashboard and connect a wallet. The dashboard adds Robinhood Chain to the wallet if it is missing.
  2. Create a payment link: pick USDG or USDC, an amount (or leave it open), a memo, an optional expiry, and whether the link is reusable.
  3. Share https://pushin.cc/pay?id=<id>. The payer approves the token once and pays; the stablecoins move straight to your wallet.
  4. Read the receipt in Transactions, or export every receipt as CSV.

The contract

The ledger is PushinPay.sol, a single non-custodial contract. It never holds tokens: pay() moves the amount from the payer to the merchant and the fee from the payer to the treasury in the same transaction, using transferFrom on an allow-listed stablecoin.

Address on Robinhood Chain: not deployed yet

FunctionWhat it does
createLink(token, amount, memo, expiry, reusable)Registers a link owned by msg.sender. amount = 0 makes an open-amount link. expiry = 0 never expires. Returns the link id.
pay(id, amount, memo)Pays a link. For fixed links pass 0 (or the exact amount). Charges feeBps to the treasury and writes a receipt.
push(token, to, amount, memo)Pays any address directly without a link. Same fee, same receipt.
setLinkActive(id, active)Merchant switches a link off or on.
getLink(id), linksOf(merchant), linkCount()Read links.
getReceipt(i), receiptsOf(merchant), receiptsBy(payer), receiptCount()Read receipts.
stats()(merchants, links, payments, feeBps), what the site shows live.
feeBps(), MAX_FEE_BPS()The fee, and its hard cap of 30 (0.30%). The owner can lower the fee, never raise it above the cap.

Events: LinkCreated, LinkUpdated, Paid, FeeUpdated, TreasuryUpdated, TokenAllowed. Tokens allowed at deploy: USDG 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 and USDC 0x80e0e24718dbFcad49ECAA6F1e6C89A190586cA8, both 6 decimals.

Integrate from code

Any EVM library works. With cast:

cast call $PUSHIN "stats()(uint256,uint256,uint256,uint256)" --rpc-url https://rpc.mainnet.chain.robinhood.com
cast send $PUSHIN "createLink(address,uint256,string,uint40,bool)" $USDG 250000000 "INV-001" 0 false --account my-wallet
cast send $USDG "approve(address,uint256)" $PUSHIN 250000000 --account payer
cast send $PUSHIN "pay(uint256,uint256,string)" 0 0 "paid" --account payer

Browser code can read through the site's CORS-friendly proxy: POST https://pushin.cc/api/rpc with a JSON-RPC body. It forwards read methods only, in batches of up to five.

Webhooks: subscribe to the Paid event with your indexer of choice, or poll receiptsOf(merchant). Every receipt carries the memo you set on the link, so invoice numbers survive the round trip.

Fees

Flat 0.30% per payment, taken from the payer in the same transaction and sent to the treasury. No FX markup: links priced in EUR, GBP, AED and other currencies convert to a stablecoin amount at the reference rate when the link is created, and that amount is what the payer pays. Gas is paid by whoever sends the transaction and is usually under a cent on Robinhood Chain.

Security

  • Non-custodial: the contract has no balance to lose and no admin function that can move user funds.
  • Fee cap: MAX_FEE_BPS = 30 is a constant.
  • Allow-listed tokens only, so an impostor "USDC" cannot be used to pay a link.
  • Reentrancy guard on pay and push; tokens that return no boolean are handled.
  • Source verified on Sourcify after deploy; tests in contracts/test.