true if the charge succeeded, false if it did not.
Parameters
Authorization
None. This function has norequire_auth(). Anyone can call it.
Return value
bool - true if the charge was processed successfully, false if it was not charged (e.g., not yet due, insufficient funds).
Pre-charge validation
Before attempting thetransfer_from, the contract checks the subscriber’s balance and allowance. This is a deliberate design decision:
The contract checks, in order:
- Does the subscription exist and is it
Active? - Has the
next_billing_timepassed? - Is this a trial period? (If so, advance the period counter without transferring funds.)
- Has
max_periodsbeen reached? (If so, expire the subscription.) - Does the subscriber have sufficient balance?
- Does the subscriber have sufficient allowance?
- Execute
transfer_from()to move funds from subscriber to merchant.
Events emitted
Error cases
charge() is designed to fail gracefully rather than revert. It returns false for most failure conditions rather than throwing an error. However, the following will cause a revert:
Examples
- SDK
- Soroban CLI
Who should call charge()?
Who should call charge()?
Since
charge() is permissionless, there are several options:- Keeper bots - automated services that monitor
next_billing_timeand callcharge()on schedule. - The merchant - can call
charge()directly from their backend. - The Vowena Dashboard - includes a built-in keeper service.
- Third-party networks - any service can integrate charge calling.
What happens when a charge fails?
What happens when a charge fails?
If the subscriber has insufficient balance or allowance:
- The
charge_failevent is emitted. failed_atis set to the current timestamp.- On the next
charge()call, ifnow > failed_at + grace_period, the subscription is paused. - A paused subscription can be reactivated by the subscriber via
reactivate().