FPSF-SS-001 — Reference
Layer: Reference · Audience: developers (daily reference) For normative requirements, see the Formal Specification.
Glossary
| Term | Definition |
|---|---|
| Acquirer | A registered third-party participant entitled to a share of the processing fee on payments they referred. Identified on-chain by an Acquirer ID. |
| Acquirer ID | A 16-byte (bytes16) UUID identifying a registered Acquirer within the Settlement Contract. |
| Acquiring Fee | A percentage-based fee charged on behalf of a registered Acquirer. Applied only when the payment includes a non-zero Acquirer ID. Per-token. |
| Administrator | The privileged account that controls Settlement Contract operational parameters. MUST NOT have the ability to move user funds. |
| Base Fee | The absolute minimum fee component of the Operator Fee, charged on every transfer, in token units. Per-token. |
| Basis Points Fee | The percentage component of the Operator Fee, expressed in basis points of the principal. Per-token. |
| Binding Signature | An EIP-712 signature over the full operation parameters, authorizing the processor to submit the operation. Field name: payWithPermitSig. |
| Broadcast Layer | The off-chain subsystem receiving, validating, queuing, and broadcasting signed payment payloads. |
| Charge | A processor-issued record representing an expected payment. |
| Checkout Engine | The merchant-facing subsystem managing payment session lifecycle. |
| Client Wallet | A conformant application that constructs and submits signed payment payloads on behalf of a payer. |
| Ephemeral Token | A short-lived, single-use token authorizing a wallet to retrieve session parameters. Confers no signing authority. |
| Operator Fee | The combined fee earned by the Payment Processor on every transfer: baseFeeAmount[token] + floor(principal * operatorFeeBps[token] / 10000). |
| Order Reference | A 16-byte (bytes16) reference created by the merchant for tracking. Embedded in PermittedTransfer events. Always a separate field from acquirerId. |
| Payload ID | A client-generated UUID for idempotency. |
| Payer | The individual who holds the stablecoin and signs the payment commitment. |
| Payment Processor | An operator that deploys and runs a conformant instance of the Stablecoin Stack. |
| Permit Signature | An ERC-2612 off-chain signature authorizing the Settlement Contract to call permit(). Field name: permitSig. |
| Principal Amount | The token amount intended to reach the beneficiary before fee deduction. |
| Relayer | The account that submits signed transactions on-chain, absorbing gas costs. Operated by the Payment Processor. |
| Service Provider | An Acquirer who has opted in to public discovery via the Basic Data Service. |
| Settlement Contract | The on-chain Solidity smart contract that verifies signatures, executes transfers, and distributes fees. |
| Total With Fees | principal + operatorFee + acquiringFee. The value in PermitParams.value. |
| Zero-UUID | 0x00000000000000000000000000000000. Used as acquirerId when no Acquirer is involved. Suppresses Acquiring Fee without reverting. |
Payload Fields Reference
ERC20RelayerSig
| Field | Format | Required | Constraints |
|---|---|---|---|
hash | bytes32 — 66-char hex | REQUIRED | 0x + 64 lowercase hex. The EIP-712 digest signed. |
v | integer | REQUIRED | 27 or 28. Normalize 0→27, 1→28. Reject all other values. |
r | bytes32 — 66-char hex | REQUIRED | Full 32 bytes, zero-padded. |
s | bytes32 — 66-char hex | REQUIRED | Full 32 bytes, zero-padded. |
PermitParams
| Field | Format | Required | Constraints |
|---|---|---|---|
owner | EVM address | REQUIRED | MUST match signer recovered from payWithPermitSig. |
spender | EVM address | REQUIRED | Typically the Settlement Contract address. |
value | uint256 | REQUIRED | Total with fees (principal + operatorFee + acquiringFee). |
nonce | uint256 | REQUIRED | MUST match current on-chain ERC-2612 nonce of owner. |
deadline | uint256 | REQUIRED | MUST be strictly greater than processor clock at submission. |
PayWithPermitParams
| Field | Format | Required | Description |
|---|---|---|---|
token | EVM address | REQUIRED | ERC-2612-compliant stablecoin. |
beneficiary | EVM address | REQUIRED | Merchant receiving address. |
orderReference | bytes16 — 34-char hex | REQUIRED | 16-byte order reference. 0x + 32 hex chars. Zero if absent. |
acquirerId | bytes16 — 34-char hex | REQUIRED | 16-byte Acquirer ID. Use Zero-UUID if no acquirer. Always present. |
permitParams | PermitParams | REQUIRED | owner MUST match recovered signer of payWithPermitSig. |
BuyAcquiringPackPermitParams
| Field | Format | Required | Constraints |
|---|---|---|---|
token | EVM address | REQUIRED | Must be in acquiringAllowedTokens. |
feeValue | uint256 | REQUIRED | MUST equal permitParams.value and acquiringPrice[token]. |
acquiring | EVM address | REQUIRED | Must not already be registered. |
acquiringFeeBps_ | uint256 | REQUIRED | Must not exceed maxAcquiringFeeBps[token]. |
permitParams | PermitParams | REQUIRED | value MUST equal feeValue. |
TransferRequest
| Field | Required | Description |
|---|---|---|
payWithPermitParams | REQUIRED | Payment parameters. |
payWithPermitSig | REQUIRED | Binding Signature over payWithPermitParams. |
permitSig | REQUIRED | Permit Signature. Forwarded to Settlement Contract. |
payloadId | REQUIRED | Client-generated UUID- Idempotency key |
BuyAcquiringPackRequest
| Field | Required | Description |
|---|---|---|
buyAcquiringPackParams | REQUIRED | Registration parameters. |
payWithPermitSig | REQUIRED | Binding Signature over buyAcquiringPackParams. |
permitSig | REQUIRED | Permit Signature. Signed value MUST equal feeValue. |
Contract Interface Reference
State Variables
| Variable | Type | Description |
|---|---|---|
baseFeeAmount | mapping(address => uint256) | Absolute base fee per token. |
operatorFeeBps | mapping(address => uint256) | Operator fee in basis points per token. |
maxAcquiringFeeBps | mapping(address => uint256) | Maximum acquiring fee in basis points per token. |
acquiringFeeBps | mapping(address => mapping(address => uint256)) | Acquiring fee per acquirer wallet per token. |
balances | mapping(address => mapping(address => uint256)) | Internal balances: token → participant → amount. |
usedHashes | mapping(bytes32 => bool) | Consumed Binding Signature digests. true = reverts. |
acquirerWallets | mapping(bytes16 => address) | Acquirer ID → wallet address. |
acquiringAllowedTokens | mapping(IERC20Permit => bool) | Tokens accepted for Acquirer registration. |
acquiringPrice | mapping(address => uint256) | Registration fee per token. |
Functions
transferWithPermit
function transferWithPermit(
IERC20Permit token,
address tokenOwner,
uint256 amount,
uint256 deadline,
uint8 v1, bytes32 r1, bytes32 s1,
uint8 v2, bytes32 r2, bytes32 s2,
address beneficiary,
bytes16 orderReference,
bytes16 acquirerId
) external
buyAcquiringPack
function buyAcquiringPack(
IERC20Permit token,
address payer,
address acquiring,
uint256 acquiringFeeBps_,
uint256 price,
uint256 deadline,
uint8 v1, bytes32 r1, bytes32 s1,
uint8 v2, bytes32 r2, bytes32 s2
) public
calculateFees
function calculateFees(
address token,
uint256 principal,
bytes16 acquirerId
) public view returns (
uint256 operatorFee,
uint256 acquiringFee,
uint256 totalWithFees
)
breakdownTransferAmount
function breakdownTransferAmount(
address token,
uint256 totalWithFees,
bytes16 acquirerId
) public view returns (
uint256 principal,
uint256 operatorFee,
uint256 acquiringFee
)
getBalances (single token)
function getBalances(
address token,
address[] calldata users
) external view returns (uint256[] memory)
getBalances (multi-token)
function getBalances(
address[] calldata tokens,
address[] calldata users
) external view returns (uint256[][] memory)
getAcquiringWallet
function getAcquiringWallet(
bytes16 acquirerId
) public view returns (address)
Events
PermittedTransfer
event PermittedTransfer(
bytes32 indexed domainSeparator,
address indexed token,
address indexed payer,
address beneficiary,
uint256 value,
uint256 operatorFee,
uint256 acquiringFee,
bytes16 orderReference,
bytes16 acquirerId
)
Note: orderReference and acquirerId are separate bytes16 fields in the event.
AcquirerCreated
event AcquirerCreated(
bytes16 indexed acquirerId,
address indexed wallet,
address indexed token,
uint256 feeBps
)
CommissionGenerated
event CommissionGenerated(
bytes16 indexed acquirerId,
address indexed token,
uint256 amount
)
AcquiringFeeUpdated
event AcquiringFeeUpdated(
address indexed acquiring,
address indexed token,
uint256 feeBps
)
Withdrawal
event Withdrawal(
address indexed owner,
address indexed beneficiary,
address indexed token,
uint256 amount
)
Error Categories
| Code | Trigger |
|---|---|
STRUCTURAL_ERROR | Missing field, wrong type, encoding violation |
SEMANTIC_ERROR | Expired deadline, nonce mismatch, repeated payloadId, feeValue mismatch |
CRYPTOGRAPHIC_ERROR | Signature recovery failure, signer ≠ owner, hash field mismatch |
BROADCAST_ERROR | On-chain revert or submission failure after successful validation |
Component Index
| Component | Subsystem | Spec Section |
|---|---|---|
| Settlement Contract | On-chain | §§11–14 |
| core-checkout-engine | Checkout Engine | §6.2 |
| checkout-public-widget | Checkout Engine | §6.2 |
| ca-server | Checkout Engine | §6.2 |
| login-server | Checkout Engine | §6.2 |
| credentials-manager | Checkout Engine | §6.2 |
| merchant-dashboard | Checkout Engine | §6.2 |
| wallet-gateway | Broadcast Layer | §6.3, FPSF-SS-002 |
| broadcast-service | Broadcast Layer | §6.3 |
| broadcast-submitter | Broadcast Layer | §6.3 |
| balance-and-history | Broadcast Layer | §6.3 |
| transfer-history | Event Indexing | §6.4 |
| basic-data-server | Shared Infrastructure | §6.5 |
| Client Wallet | Client | §6.6 |
FPSF-SS-001 v1.0.0 · Draft · Fabric Payment Standards Foundation · Apache-2.0