Stellar-based smart contracts for FacilPay. Secure, auditable, and transparent payment infrastructure.
FacilPay uses Soroban smart contracts on Stellar for:
- Payment Processing: Accept and lock crypto payments
- Settlement: Convert and transfer to merchants in USDC
- Escrow: Hold funds during dispute periods
- Refunds: Process customer refunds
- Rust 1.74.0 or later
- Stellar CLI (
stellarcommand) - Soroban SDK
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Stellar CLI
cargo install --locked stellar-cli --features opt
# Add wasm target
rustup target add wasm32-unknown-unknown# From root directory
make# Test all contracts in workspace
cargo test --workspace
# Test specific contract
cargo test -p escrow
cargo test -p payment
cargo test -p refund
# Test a single test file or function within a contract
cargo test -p refund test_arbitration_fees
cargo test -p escrow test_dispute_resolution
# Run tests matching a pattern
cargo test -p payment test_feeHandles payment creation and processing:
create_payment()- Customer initiates paymentcomplete_payment()- Admin releases to merchantrefund_payment()- Admin refunds to customerget_payment()- Query payment details
Manages fund holding and disputes:
create_escrow()- Lock fundsrelease_escrow()- Release to merchantdispute_escrow()- Handle disputes
Processes refund requests:
request_refund()- Merchant initiatesapprove_refund()- Admin approvesprocess_refund()- Execute refundget_refunds_by_reason_code()- Filter refunds by structured reason code with paginationget_reason_code_analytics()- Count refunds by reason code (sorted by frequency)
request_refund() now requires a reason_code: RefundReasonCode argument in addition to free-text reason.
- Old call shape:
request_refund(..., reason, payment_created_at) - New call shape:
request_refund(..., reason, reason_code, payment_created_at)
Recommended migration path:
- Update all callers to pass a concrete enum value (
ProductDefect,NonDelivery,DuplicateCharge,Unauthorized,CustomerRequest,Other). - For unknown/legacy flows, pass
Otherfirst and backfill specific codes in your upstream app logic. - If upgrading a deployed instance with existing data, plan a storage/data migration for historical refunds before reading them as the new
Refundshape.
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
cargo test --workspace) - Commit your changes (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Storage Versioning Guide
- Audit Summary
- Telegram: https://t.me/+afM9uh7GGtVkYmZk
- API Repository
- SDK Repository
This project is licensed under the MIT License.
- #558: [Enhancement] resume_subscription publishes the SubscriptionResumed event twice on every call
- #567: [Enhancement] sweep_platform_fees can sweep tokens that are already owed to merchants as unclaimed fee rebates
- #576: [Enhancement] Pause enforcement covers only 5 of the refund contract's state-changing entry points — arbitration, vouchers, batch ops, and admin override bypass it entirely
- #440: [Docs] Document RefundReasonCode enum values and when to use each
- #595: [Enhancement] 12 of the escrow crate's test modules are commented out of the build — cargo test silently skips 231 of ~330 tests including all of test.rs
- #633: [Docs] Document escrow templates (create_template, create_escrow_from_template)