Core Modules 🏗️
DolphinPay's core functionality is implemented in two main modules: Payment and Merchant. These modules work together to provide a complete payment infrastructure.
Payment Module
The Payment module (payment.move) handles all payment-related operations from creation to completion.
Key Data Structures
Payment Object
struct Payment has key, store {
id: UID,
merchant: address, // Merchant receiving payment
payer: Option<address>, // Address that paid (if completed)
amount: u64, // Payment amount in smallest unit
currency: TypeName, // Currency type (e.g., SUI)
description: String, // Payment description
metadata: VecMap<String, String>, // Custom key-value data
status: u8, // Payment status (0-4)
expiry_timestamp: u64, // When payment expires
platform_fee: u64, // Platform fee amount
merchant_fee: u64, // Merchant fee amount
created_at: u64, // Creation timestamp
completed_at: Option<u64>, // Completion timestamp
}
Payment Status Values
0- PENDING: Payment created but not yet executed1- COMPLETED: Payment successfully executed2- CANCELLED: Payment cancelled by merchant3- EXPIRED: Payment expired without execution4- FAILED: Payment execution failed
Core Functions
Create Payment
public fun create_payment(
merchant: address,
amount: u64,
currency: TypeName,
description: String,
metadata: VecMap<String, String>,
expiry_seconds: u64,
ctx: &mut TxContext
): Payment
Creates a new payment request with the specified parameters.
Parameters:
merchant: Address that will receive the paymentamount: Payment amount (in smallest currency unit)currency: Currency type namedescription: Human-readable payment descriptionmetadata: Additional key-value dataexpiry_seconds: How long payment is valid forctx: Transaction context
Execute Payment
public fun execute_payment<T>(
payment: &mut Payment,
coin: Coin<T>,
ctx: &mut TxContext
)
Executes a pending payment by transferring the specified coin.
Requirements:
- Payment must be in PENDING state
- Payment must not be expired
- Coin amount must be exactly equal to payment amount
- Currency must match payment currency
Cancel Payment
public fun cancel_payment(
payment: &mut Payment,
merchant_cap: &MerchantCap,
ctx: &mut TxContext
)
Cancels a pending payment. Only the merchant can cancel their own payments.
Query Functions
public fun get_payment_status(payment: &Payment): u8
public fun get_payment_amount(payment: &Payment): u64
public fun get_payment_merchant(payment: &Payment): address
public fun is_payment_expired(payment: &Payment): bool
Fee Calculation
Fees are calculated automatically based on merchant configuration:
// Platform fee: 0.3% (30 basis points)
const PLATFORM_FEE_BPS: u64 = 30;
// Merchant fee: configurable (0-1000 basis points)
let merchant_fee_bps = get_merchant_fee_config(merchant);
let total_fee_bps = PLATFORM_FEE_BPS + merchant_fee_bps;
// Calculate fees
let platform_fee = (amount * PLATFORM_FEE_BPS) / BPS_DIVISOR;
let merchant_fee = (amount * merchant_fee_bps) / BPS_DIVISOR;
let net_amount = amount - platform_fee - merchant_fee;
Merchant Module
The Merchant module (merchant.move) manages merchant accounts and their configurations.
Key Data Structures
Merchant Object
struct Merchant has key, store {
id: UID,
owner: address, // Merchant owner address
name: String, // Business name
description: String, // Business description
receiving_addresses: VecMap<TypeName, address>, // Currency -> address mapping
fee_config: FeeConfig, // Fee configuration
supported_currencies: VecSet<TypeName>, // Supported currency types
settings: MerchantSettings, // Additional settings
status: u8, // Active/Inactive status
created_at: u64, // Registration timestamp
}
Fee Configuration
struct FeeConfig has store {
platform_fee_bps: u64, // Platform fee (fixed at 30)
custom_fee_bps: u64, // Merchant's custom fee (0-1000)
min_fee: u64, // Minimum fee amount
max_fee: u64, // Maximum fee amount
}
Core Functions
Register Merchant
public fun register_merchant(
name: String,
description: String,
ctx: &mut TxContext
): (Merchant, MerchantCap)
Registers a new merchant and returns the merchant object and capability.
Returns:
Merchant: Merchant object (stored at merchant address)MerchantCap: Capability object allowing merchant operations
Configure Fees
public fun configure_merchant_fees(
merchant: &mut Merchant,
merchant_cap: &MerchantCap,
custom_fee_bps: u64,
min_fee: u64,
max_fee: u64,
ctx: &mut TxContext
)
Configures the merchant's custom fee structure.
Parameters:
custom_fee_bps: Custom fee in basis points (0-1000 = 0-10%)min_fee: Minimum fee amount in smallest currency unitmax_fee: Maximum fee amount in smallest currency unit
Add Currency Support
public fun add_supported_currency<T>(
merchant: &mut Merchant,
merchant_cap: &MerchantCap,
receiving_address: address,
ctx: &mut TxContext
)
Adds support for a new currency with the specified receiving address.
Set Receiving Address
public fun set_receiving_address<T>(
merchant: &mut Merchant,
merchant_cap: &MerchantCap,
currency: TypeName,
address: address,
ctx: &mut TxContext
)
Updates the receiving address for a specific currency.
Merchant Capabilities
The MerchantCap object is crucial for security:
struct MerchantCap has key {
id: UID,
merchant_id: ID, // Links to specific merchant
permissions: u64, // Permission bitmask
}
Permission Types:
REGISTER_MERCHANT: Register new merchantsCONFIGURE_FEES: Modify fee settingsADD_CURRENCY: Add new currency supportSET_ADDRESSES: Update receiving addressesCANCEL_PAYMENTS: Cancel merchant's payments
Events
Both modules emit comprehensive events for all operations:
Payment Events
struct PaymentCreated has copy, drop {
payment_id: ID,
merchant: address,
amount: u64,
currency: TypeName,
description: String,
expiry_timestamp: u64,
}
struct PaymentCompleted has copy, drop {
payment_id: ID,
payer: address,
amount: u64,
net_amount: u64,
platform_fee: u64,
merchant_fee: u64,
tx_hash: vector<u8>,
}
Merchant Events
struct MerchantRegistered has copy, drop {
merchant_id: ID,
owner: address,
name: String,
}
struct MerchantFeesUpdated has copy, drop {
merchant_id: ID,
custom_fee_bps: u64,
min_fee: u64,
max_fee: u64,
}
Integration Example
Here's how the modules work together:
// 1. Register merchant
let (merchant, merchant_cap) = merchant::register_merchant(
"My Store",
"E-commerce platform",
ctx
);
// 2. Configure merchant
merchant::configure_merchant_fees(
&mut merchant,
&merchant_cap,
50, // 0.5% custom fee
1000000, // 0.001 SUI min fee
1000000000, // 1 SUI max fee
ctx
);
// 3. Add currency support
merchant::add_supported_currency<SUI>(
&mut merchant,
&merchant_cap,
merchant_address, // Receiving address
ctx
);
// 4. Create payment
let payment = payment::create_payment(
merchant_address,
10000000000, // 10 SUI
sui::SUI,
"Order #12345",
metadata,
3600, // 1 hour expiry
ctx
);
// 5. Execute payment (by customer)
payment::execute_payment(
&mut payment,
coin, // Customer's coin
ctx
);
Security Features
Input Validation
- Amount Validation: Enforces minimum (0.0001 SUI) and maximum (1000 SUI) amounts
- Address Validation: Checks for zero addresses and malformed addresses
- String Validation: Enforces length limits on descriptions and metadata
- Time Validation: Ensures expiry times are reasonable (1 hour to 1 week)
Access Control
- Capability System: Uses Sui's object capability model for secure access
- Owner Verification: Merchants can only modify their own configurations
- Admin Controls: Separate admin capabilities for platform management
Overflow Protection
- Safe Arithmetic: All calculations use checked operations
- u128 Usage: Fee calculations use u128 to prevent overflow
- Percentage Bounds: Fee percentages are strictly bounded (0-10%)
Testing
Unit Tests
# Run payment module tests
sui move test payment_tests
# Run merchant module tests
sui move test merchant_tests
# Run all tests
sui move test
Test Coverage
- ✅ Payment creation and validation
- ✅ Payment execution with various amounts
- ✅ Payment cancellation by merchants
- ✅ Merchant registration and configuration
- ✅ Fee calculation accuracy
- ✅ Event emission verification
- ✅ Error condition handling
- ✅ Access control enforcement
Gas Optimization
Efficient Patterns
- Object Reuse: Minimize creation of new objects
- Batch Operations: Combine operations where possible
- Event Optimization: Structured events for minimal gas usage
- Validation Ordering: Fail fast on invalid inputs
Typical Gas Costs (Testnet)
| Operation | Gas Cost | Description |
|---|---|---|
| Create Payment | ~0.01 SUI | Standard payment creation |
| Execute Payment | ~0.015 SUI | Payment completion |
| Register Merchant | ~0.015 SUI | New merchant setup |
| Configure Fees | ~0.01 SUI | Update fee settings |
| Cancel Payment | ~0.008 SUI | Payment cancellation |
Next Steps
- Payment API Reference - Complete payment module API documentation
- Merchant API Reference - Full merchant module API reference
- Admin API Reference - Admin operations and configuration
- SDK Integration - Start building with the SDK
Ready to build? Check out the SDK documentation to start integrating with these modules!