true if the charge succeeded, false if it did not.
Parameters
| Name | Type | Description |
|---|---|---|
sub_id | u64 | The subscription ID to charge. |
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
| Event | Topics | Data | Condition |
|---|---|---|---|
charge_ok | subscriber, sub_id, amount | Period number | Charge succeeded |
charge_fail | subscriber, sub_id | Failure reason | Balance or allowance insufficient |
sub_paused | subscriber, sub_id | failed_at timestamp | Grace period expired on a previously failed charge |
sub_expired | subscriber, sub_id | periods_billed | Max periods reached |
sub_cancel | subscriber, sub_id | cancelled_at timestamp | Subscription cancelled due to expiry |
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:
| Code | Name | Description |
|---|---|---|
| 8 | SubNotFound | No subscription exists with the given sub_id. |
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().