Skip to main content

Auto-charge

Auto-charge is OrcaRail's recurring pull model: the payer grants the hot wallet permission to pull tokens each billing cycle. Supported networks for auto-charge are EVM and Solana (Bitcoin is not supported for subscription pulls). On EVM, the payer sets an ERC-20 allowance and OrcaRail uses transferFrom for each period. On Solana, the payer delegates SPL token authority; OrcaRail pulls via the hot wallet using that delegation.

:::note Non-custodial subscriptions

OrcaRail is transitioning auto-charge to a fully non-custodial model: the approve spender moves from an OrcaRail-owned hot wallet to a public SubscriptionHub contract (EVM) or Anchor subscription program (Solana). The payer flow on this page — approve once, revoke anytime — stays the same; only the spender address changes. See Non-custodial overview and Phase 2: Allowance-pull subscriptions.

:::

For payers: how you approve and how you revoke

This section is for people paying a subscription (customers), not for developers integrating the API.

What you are agreeing to

With auto-charge, you sign once in your wallet to let OrcaRail pull the subscription amount each billing period (for example every month), up to the limit you approved. You do not need to open a checkout link every time, as long as the allowance or delegation is still valid and you have enough of the token in your wallet.

How to approve auto-charge

  1. Open the link the business sent you (email, website, or app). It should take you to OrcaRail’s hosted pay or subscription experience.
  2. Connect your wallet on the correct network and choose the token shown (for example USDC).
  3. Read the summary: price per period, how often you are charged, and any total or number of cycles covered by the approval.
  4. When you click to enable auto-charge, your wallet asks you to approve the token permission. Confirm only if you agree with the amounts and the business.
  5. After the transaction confirms on-chain, you should see a success message. OrcaRail then records the approval; future periods are charged automatically until the approval runs out, fails (for example low balance), or you revoke.

If something fails, check that you are on the right network and token, then try again or pay with a payment link for that period if the merchant offers it.

How to revoke auto-charge (stop automatic pulls)

  1. Revoke on-chain so the spender can no longer pull your tokens:
    • EVM: Submit a transaction that removes the allowance—typically approve(spender, 0) on the token contract for OrcaRail’s spender address (your wallet’s “token approvals” or revoke tools may offer this).
    • Solana: Revoke the SPL token delegation you granted for that subscription.
  2. Complete the merchant’s flow if offered (for example “Manage subscription” → stop auto-charge). That tells OrcaRail to switch you to payment links each period instead of pulls, and you may get an email with next steps.
  3. If you only revoke on-chain and never notify OrcaRail, the next automatic charge may fail and the subscription can become overdue until you pay a link or fix the approval.

Merchants and custom apps use the Revoke auto-charge (API) after the on-chain revoke.

How it works

  1. Merchant creates a subscription with collection_method: "auto_charge".
  2. Payer opens the subscription link or the first cycle's payment link (or chooses auto-charge via set collection method when applicable).
  3. Payer completes the on-chain approval: EVM approve(spender, amount) to OrcaRail's spender address, or the equivalent SPL delegation for Solana. Use approval_spender_address on the subscription's auto_charge object (when present) as the spender/delegate the wallet must approve.
  4. Payer submits the approval to OrcaRail: POST /api/v1/subscriptions/:id/approve-auto-charge with allowance_tx_hash, payer_wallet_address, payer_network_id, payer_token_id, and optional approved_amount / approved_iterations.
  5. OrcaRail records the allowance and marks auto_charge as approved. Each billing cycle, the billing job uses the hot wallet to pull the period amount. On success the cycle is marked paid and the billing period advances; on failure the subscription can move to past_due and the payer is notified.

Approve auto-charge (payer)

POST /api/v1/subscriptions/:id/approve-auto-charge

This endpoint is public (payer-facing). No merchant API key; the payer proves intent by having signed the on-chain approval transaction.

Request body

ParameterTypeRequiredDescription
payer_wallet_addressstringYesPayer's wallet address (EVM or Solana, depending on network)
payer_network_idstring (UUID)YesNetwork ID where the allowance or delegation was set
payer_token_idstring (UUID)YesToken ID (e.g. USDC)
allowance_tx_hashstringYesTransaction hash of the approval (EVM approve or Solana SPL setup as applicable)
approved_amountstringNoTotal approved amount (e.g. "120.00" for twelve monthly charges)
approved_iterationsintegerNoNumber of billing cycles covered by that total (e.g. 12). When both approved_amount and approved_iterations are set, OrcaRail can derive the per-period pull amount.

Flow in the pay app

  1. Show the subscription summary: description, amount per period, interval, total cycles, and total amount to approve.
  2. Read approval_spender_address from the subscription's auto_charge (or subscription payload) so the wallet approves the correct spender/delegate.
  3. "Approve" triggers the wallet to sign the chain-appropriate approval (e.g. wagmi/viem on EVM).
  4. On confirmation, call POST .../approve-auto-charge with the tx hash and payer/network/token info (and optional approved_amount / approved_iterations).
  5. On success, show: "Auto-charge approved. You'll be charged [amount] [interval] automatically."

Revoke auto-charge (payer)

After revoking on-chain (EVM: approve(spender, 0); Solana: revoke SPL delegation), the payer can confirm with OrcaRail:

POST /api/v1/subscriptions/:id/revoke-auto-charge

This endpoint is public (payer-facing), same as approve.

Request body

ParameterTypeRequiredDescription
payer_wallet_addressstringYesWallet that held the allowance or delegation
revocation_tx_hashstringYesTransaction hash of the on-chain revoke

On success, OrcaRail switches the subscription to send_payment_link and emails the payer with links to manage subscriptions and open the latest payment page.

Set collection method (payer)

Payers can choose how they pay (payment link each cycle vs auto-charge) from the hosted flow:

POST /api/v1/subscriptions/:id/set-collection-method

Public (payer-facing). No merchant API key.

Request body

ParameterTypeRequiredDescription
collection_methodstringYessend_payment_link or auto_charge
payer_wallet_idstring (UUID)When auto_chargeID of the payer's verified wallet to use for pulls
payer_network_idstring (UUID)NoPayer-selected network for auto-charge; defaults to the subscription's network if omitted
payer_token_idstring (UUID)NoPayer-selected token for auto-charge; defaults to the subscription's token if omitted

Returns the full subscription object (same shape as retrieve).

Auto_charge object on the subscription

When collection_method is auto_charge, the subscription response includes:

{
"auto_charge": {
"payer_wallet_address": "0x...",
"payer_network_id": "...",
"payer_token_id": "...",
"allowance_tx_hash": "0x...",
"approved_amount": "120.00",
"approved_iterations": 12,
"approval_spender_address": "0x...",
"status": "approved"
}
}
  • approval_spender_address — Address (EVM) or equivalent identifier the payer must approve as spender/delegate for pulls on that network.
  • approved_iterations — When set with approved_amount, defines how many cycles that lump approval covers.

status can be: pending, approved, revoked, failed. If the payer revokes on-chain, you may see revoked; if a pull fails repeatedly, failed or subscription past_due.

Failure handling

  • Pull fails (e.g. insufficient balance, allowance or delegation revoked): subscription can move to past_due, payer receives an email (e.g. auto-charge failed notification). You can listen for subscription.payment_link.payment_failed or subscription.past_due webhooks.
  • Payer revokes on-chain without calling the API: Subsequent pulls will fail; subscription can become past_due until you ask the payer to re-approve or switch collection method.
  • Payer confirms revoke via API (Revoke auto-charge): OrcaRail switches the subscription to send_payment_link and emails the payer.

Security and UX

  • Only the wallet that completed approval can be charged; the backend verifies allowance or delegation on-chain.
  • Show the total approval amount and number of charges clearly so the payer knows what they are approving.
  • For very long or infinite subscriptions, consider capping the approved amount (e.g. 12 months) and asking for re-approval later, or use send_payment_link instead.

Next steps