Merchant Module API Reference
API reference for dolphinpay::merchant (contract/sources/core/merchant.move).
The module handles merchant registration, receiving addresses, and active/inactive status. Merchants have no fee configuration — the platform fee is global and admin-governed (see the Admin API); it is currently 0 bps by policy.
Data structures
Merchant
Shared object created at registration.
public struct Merchant has key, store {
id: UID,
owner: address,
name: String, // 1–100 chars
description: String, // ≤ 500 chars
receiving_addresses: VecMap<TypeName, address>,
settings: MerchantSettings,
created_at: u64, // ms
is_active: bool,
supported_currencies: VecSet<TypeName>,
}
MerchantCap
Capability transferred to the registering sender; required for all merchant mutations.
public struct MerchantCap has key {
id: UID,
merchant_id: ID,
}
MerchantSettings
public struct MerchantSettings has store {
auto_settlement: bool,
settlement_threshold: u64,
webhook_url: String,
api_keys: vector<String>,
require_confirmation: bool,
}
Defaults are all-off/empty at registration. There is no fee config and no refund policy in the merchant object.
Constants
const MAX_NAME_LENGTH: u64 = 100;
const MAX_DESCRIPTION_LENGTH: u64 = 500;
Error codes
const E_NOT_AUTHORIZED: u64 = 1;
const E_INVALID_FEE: u64 = 200; // declared; unused
const E_MERCHANT_NOT_FOUND: u64 = 201; // declared; unused
const E_MERCHANT_INACTIVE: u64 = 202;
const E_INVALID_NAME: u64 = 203;
const E_FEE_TOO_HIGH: u64 = 204; // declared; unused
const E_CURRENCY_ALREADY_SUPPORTED: u64 = 205;
const E_CURRENCY_NOT_SUPPORTED: u64 = 206;
const E_INVALID_ADDRESS: u64 = 207;
Entry functions
register_merchant
public entry fun register_merchant(
name: String,
description: String,
ctx: &mut TxContext
)
Creates and shares a Merchant object (active by default) and transfers
a MerchantCap to the sender.
Emits: MerchantRegistered
Aborts: E_INVALID_NAME — name empty or > 100 chars, or description
500 chars
update_merchant_info
public entry fun update_merchant_info(
merchant: &mut Merchant,
cap: &MerchantCap,
name: String,
description: String,
ctx: &TxContext,
)
Updates name and/or description. An empty string keeps the current value.
Emits: MerchantSettingsUpdated
Aborts: E_NOT_AUTHORIZED (cap doesn't match merchant),
E_INVALID_NAME (length limits)
add_supported_currency
public entry fun add_supported_currency<T>(
merchant: &mut Merchant,
cap: &MerchantCap,
receiving_address: address,
)
Registers coin type T with a receiving address for this merchant. Note:
the platform accepts only native Circle USDC, so registering any other type
has no effect on payments — only the USDC entry is ever used by
payment::execute_payment_with_merchant.
Aborts: E_NOT_AUTHORIZED, E_INVALID_ADDRESS (address is @0x0),
E_CURRENCY_ALREADY_SUPPORTED
remove_supported_currency
public entry fun remove_supported_currency<T>(
merchant: &mut Merchant,
cap: &MerchantCap,
)
Removes T from the supported set and drops its receiving address.
Aborts: E_NOT_AUTHORIZED, E_CURRENCY_NOT_SUPPORTED
set_receiving_address
public entry fun set_receiving_address<T>(
merchant: &mut Merchant,
cap: &MerchantCap,
receiving_address: address,
)
Updates the receiving address for an already-supported currency T.
Aborts: E_NOT_AUTHORIZED, E_INVALID_ADDRESS,
E_CURRENCY_NOT_SUPPORTED
toggle_merchant_status
public entry fun toggle_merchant_status(
merchant: &mut Merchant,
cap: &MerchantCap,
active: bool,
ctx: &TxContext,
)
Sets is_active to the given value. Inactive merchants cannot be used with
create_payment_with_merchant / execute_payment_with_merchant.
Emits: MerchantStatusChanged
Aborts: E_NOT_AUTHORIZED
Query functions
public fun is_merchant_active(merchant: &Merchant): bool
public fun is_currency_supported<T>(merchant: &Merchant): bool
public fun get_receiving_address<T>(merchant: &Merchant): address
// aborts with E_CURRENCY_NOT_SUPPORTED if T isn't supported
public fun get_owner(merchant: &Merchant): address
public fun get_name(merchant: &Merchant): String
public fun get_description(merchant: &Merchant): String
public fun get_created_at(merchant: &Merchant): u64
Admin override (package-private)
public(package) fun admin_set_active_status(merchant: &mut Merchant, active: bool)
Callable only from within the package — used by
admin::force_activate_merchant / admin::force_deactivate_merchant
(AdminCap-gated). See the Admin API.
Usage example
# Register a merchant
sui client call \
--package <PACKAGE_ID> --module merchant --function register_merchant \
--args "Acme Store" "Digital goods"
# Set a dedicated USDC receiving address
sui client call \
--package <PACKAGE_ID> --module merchant --function add_supported_currency \
--type-args <USDC_TYPE> \
--args <MERCHANT_ID> <MERCHANT_CAP_ID> <RECEIVING_ADDRESS>
<USDC_TYPE> on testnet:
0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC.
Package and object IDs come from DEPLOYMENT.md — never hard-code stale IDs.
Security notes
- All mutations verify
cap.merchant_id == object::id(merchant). - Receiving addresses cannot be
@0x0. - Fees are outside merchant control entirely; there is no merchant fee field to configure or manipulate.
- Keep the
MerchantCapobject secure — whoever holds it controls the merchant record.