Skip to main content

Smart Contracts

Open Pay uses Solidity smart contracts deployed on BSC Testnet (Chain ID 97) to provide trustless, on-chain escrow for cryptocurrency payments. Funds are held in escrow until the merchant confirms delivery, at which point they are released automatically.

Architecture

Deployed Contracts

All contracts are deployed on BSC Testnet (Chain ID 97).
ContractAddressPurpose
OpenPayEscrow0xe50464081b781AFE101EB40bC7e68Fd017c5e8f2Payment escrow with fee splitting
OpenPayPriceFeed0x1f34e070D4BB1eD3AaF37D8E3297b0a9A12a3399Chainlink oracle price aggregation
MockUSDTTestnet tokenTest USDT (18 decimals)
MockUSDCTestnet tokenTest USDC (18 decimals)
MockPriceFeedTestnet contractSimulated Chainlink feed for testing
These are testnet deployments. For mainnet, you would deploy to BSC Mainnet (Chain ID 56) with real Chainlink price feeds and verified token addresses.

Key Features

Escrow Payments

Funds are held securely in the smart contract until the payment is confirmed, refunded, or expired. No party can unilaterally withdraw.

Multi-Currency

Accept USDT, USDC, and BNB. The price feed converts USD amounts to token amounts in real time.

Chainlink Oracles

Real-time price data from Chainlink decentralized oracles ensures accurate USD-to-token conversion with staleness protection.

Platform Fees

Automatic 2% platform fee (200 basis points) deducted on payment confirmation and sent to the fee recipient address.

Payment Lifecycle

Every payment moves through a defined state machine:
StatusValueDescription
None0Payment does not exist
Pending1Funds deposited, awaiting confirmation
Confirmed2Merchant paid, fee deducted
Refunded3Funds returned to payer
Expired4Payment timed out, funds returned

Security

The contracts use battle-tested OpenZeppelin libraries:
  • ReentrancyGuard — prevents reentrancy attacks on all payment functions
  • SafeERC20 — safe token transfer wrappers that handle non-standard ERC-20 tokens
  • Ownable — only the contract owner can confirm, refund, or expire payments

How It Works

1

Quote

The backend calls getQuote(token, usdAmount) on the escrow contract to get the exact token amount needed, including slippage bounds.
2

Deposit

The payer calls createPayment() (for ERC-20 tokens) or createNativePayment() (for BNB) with the payment ID, merchant address, and token amount. Funds are transferred to the escrow contract.
3

Verify

The Open Pay backend monitors on-chain events. Once the PaymentCreated event is detected, the payment status is updated in the database.
4

Confirm

The contract owner (Open Pay backend) calls confirmPayment(). The escrow splits the funds: 98% to the merchant, 2% platform fee to the fee recipient.

Next Steps

Escrow Contract

Deep-dive into the OpenPayEscrow contract functions and events

Price Feed

Understand the Chainlink oracle integration

Deployment Guide

Deploy your own instance or add new tokens