Transaction Science open standards monorepo. Each subdirectory is a self-contained reference protocol with its own README and licence. - openpay/ Apache-2.0 payment-acceptance stack (Rust, 26 crates) - smart-byte/ CC-BY-4.0 content-addressed value carrier (spec) - eoc/ CC-BY-4.0 energy-optimised compute (spec) The wire format and the right to fork are public. The optional hosted services are the offer; the protocols are not.
64 lines
2.5 KiB
Rust
64 lines
2.5 KiB
Rust
//! # `op-settlement` — When does the vendor actually see the money?
|
|
//!
|
|
//! Posted ledger transactions are an accounting fact, not a bank
|
|
//! deposit. Between "we recorded a payment" and "funds landed in the
|
|
//! vendor's bank account" sits the **settlement layer**:
|
|
//!
|
|
//! 1. Batch posted transactions by **cutoff window** (daily,
|
|
//! multi-daily, manual).
|
|
//! 2. Subtract **holdbacks** — operator-configured reserve plus an
|
|
//! optional risk-driven adjustment for open disputes.
|
|
//! 3. Generate the **payout file** for the chosen rail (NACHA for
|
|
//! US ACH, `pacs.008` for SEPA / RTP / `FedNow` via
|
|
//! [`op_iso20022`]).
|
|
//! 4. Track the batch lifecycle: `Open → Closed → Paying → Paid`
|
|
//! (or `Failed`), with retries on the rail side.
|
|
//!
|
|
//! ## Architectural place
|
|
//!
|
|
//! `op-settlement` sits *downstream* of [`op_ledger`] (it consumes
|
|
//! posted transactions) and *upstream* of the rail payout mechanism
|
|
//! (NACHA file, ISO 20022 customer credit transfer). It does NOT
|
|
//! itself talk to a bank — that's the operator's payout adapter,
|
|
//! which the trait surface admits.
|
|
//!
|
|
//! ```text
|
|
//! op-ledger ──posted tx──► op-settlement ──batch──► op-iso20022
|
|
//! │ (pacs.008)
|
|
//! └─────────────► NACHA writer
|
|
//! ```
|
|
//!
|
|
//! ## What this crate does NOT do
|
|
//!
|
|
//! - **No bank connectivity.** We emit payout *files*; an operator
|
|
//! adapter SFTPs the NACHA to their ODFI or POSTs the pacs.008.
|
|
//! - **No FX.** A batch is single-currency. Multi-currency
|
|
//! operators run one batch per currency.
|
|
//! - **No persistence by default.** [`InMemorySettlementStore`] for
|
|
//! tests / single-process kiosks; production deployments plug in
|
|
//! their own [`SettlementStore`].
|
|
//! - **No clock.** All timestamps are caller-supplied unix epoch
|
|
//! seconds so tests and replay are deterministic.
|
|
|
|
#![deny(unsafe_code)]
|
|
#![warn(missing_docs)]
|
|
#![warn(clippy::pedantic)]
|
|
#![allow(clippy::module_name_repetitions)]
|
|
|
|
pub mod batch;
|
|
pub mod cutoff;
|
|
pub mod engine;
|
|
pub mod error;
|
|
pub mod holdback;
|
|
pub mod nacha;
|
|
pub mod payout;
|
|
pub mod store;
|
|
|
|
pub use batch::{Batch, BatchId, Status};
|
|
pub use cutoff::Cutoff;
|
|
pub use engine::SettlementEngine;
|
|
pub use error::{Error, Result};
|
|
pub use holdback::{Holdback, HoldbackPolicy};
|
|
pub use nacha::{NachaCredit, nacha_file};
|
|
pub use payout::PayoutRail;
|
|
pub use store::{InMemorySettlementStore, SettlementStore};
|