Gumroad’s payout system allows sellers to configure when and how they receive earnings from their sales.
Payout Schedule Options
Sellers can choose from four payout frequencies:
Weekly
Monthly
Quarterly
Daily
Default payout schedule
Payouts sent every Friday
Includes sales from 7+ days ago
Most popular option for steady income
User :: PayoutSchedule :: WEEKLY = "weekly"
End-of-month payouts
Payouts sent on the last Friday of each month
Good for sellers who prefer less frequent transfers
Reduces bank transfer fees
User :: PayoutSchedule :: MONTHLY = "monthly"
Quarterly payouts
Payouts sent on the last Friday of each quarter
March 31, June 30, September 30, December 31
Useful for tax planning
User :: PayoutSchedule :: QUARTERLY = "quarterly"
Instant payouts (requires eligibility)
Payouts sent daily for eligible sellers
Requires debit card connected
Higher fees may apply
User :: PayoutSchedule :: DAILY = "daily"
Daily payouts are only available to sellers who meet instant payout eligibility requirements.
Payout Timing
Gumroad uses a delay system to protect against chargebacks:
module User::PayoutSchedule
PAYOUT_STARTING_DATE = Date . new ( 2012 , 12 , 21 )
PAYOUT_RECURRENCE_DAYS = 7
PAYOUT_DELAY_DAYS = 7
end
Delay Period : 7 days from sale to payout eligibility
Processing Time : 2-5 business days for bank transfer
Total Time : ~2 weeks from sale to bank account
The 7-day delay helps protect sellers and Gumroad from fraudulent chargebacks and payment disputes.
Payout Thresholds
Set a minimum balance before payouts are sent:
# User model
attr_json_data_accessor :payout_threshold_cents ,
default: -> { minimum_payout_threshold_cents }
def minimum_payout_amount_cents
[payout_threshold_cents, minimum_payout_threshold_cents]. max
end
Default Threshold
Minimum : $10 USD (1000 cents)
Configurable : Sellers can set higher thresholds
Currency-specific : Adjusted for local currency
Why Use Thresholds?
Reduce bank transfer fees
Accumulate larger payouts
Simplify accounting
If your balance is below the threshold on payout day, the payout is skipped and funds roll over to the next payout date.
Configuring Payout Settings
Sellers configure payouts at /settings/payments:
# app/controllers/settings/payments_controller.rb
def update
# Validate threshold
if params[ :payout_threshold_cents ]. present? &&
params[ :payout_threshold_cents ]. to_i < current_seller. minimum_payout_threshold_cents
return redirect_with_error (
"Your payout threshold must be greater than the minimum payout amount"
)
end
# Update payout settings
current_seller. update (
params. permit (
:payouts_paused_by_user ,
:payout_threshold_cents ,
:payout_frequency
)
)
end
Validation
# User model
validate :payout_frequency_is_valid
def payout_frequency_is_valid
unless [ WEEKLY , MONTHLY , QUARTERLY , DAILY ]. include? (payout_frequency)
errors. add ( :payout_frequency , "is not a valid frequency" )
end
end
Balance Management
View your balance at /balance:
# app/controllers/balance_controller.rb
def index
payouts_presenter = PayoutsPresenter . new (
seller: current_seller,
params: params
)
render inertia: "Payouts/Index" ,
props: {
next_payout_period_data: payouts_presenter. next_payout_period_data ,
processing_payout_periods_data: payouts_presenter. processing_payout_periods_data ,
payouts_status: current_seller. payouts_status ,
payouts_paused_by: current_seller. payouts_paused_by_source ,
past_payout_period_data: payouts_presenter. past_payout_period_data
}
end
Balance Types
Unpaid Balance : Funds available for payout
def unpaid_balance_cents
balances. unpaid . sum ( :amount_cents )
end
Instantly Payable Balance : Available for instant payout
def instantly_payable_unpaid_balance_cents_up_to_date ( date )
# Balances eligible for instant payout
end
Processing Balance : Payouts in transit
payments. where ( state: "in_progress" )
Upcoming Payouts
View projected payouts:
def upcoming_payouts
upcoming_payout_date = next_payout_date
upcoming_payouts = []
while upcoming_payout_date
payout_amount = payout_amount_for_payout_date (upcoming_payout_date)
break if payout_amount < minimum_payout_amount_cents
payout_period_end_date = payout_period_end_date_for_payout_date (
upcoming_payout_date
)
payout_balances = unpaid_balances_up_to_date (payout_period_end_date)
upcoming_payout = Payment . new (
user: self ,
amount_cents: payout_amount,
payout_period_end_date: payout_period_end_date,
currency: Currency :: USD ,
state: payouts_status,
created_at: upcoming_payout_date,
processor: current_payout_processor,
bank_account: active_bank_account,
payment_address: paypal_payout_email
)
upcoming_payouts << upcoming_payout
upcoming_payout_date = advance_payout_date (upcoming_payout_date)
end
upcoming_payouts
end
The balance page shows up to 3 upcoming payouts, helping you plan your cash flow.
Payout Processors
Gumroad automatically selects the payout processor:
def current_payout_processor
if (paypal_payout_email. present? && active_bank_account. blank? ) ||
! native_payouts_supported?
PayoutProcessorType :: PAYPAL
else
PayoutProcessorType :: STRIPE
end
end
Stripe : Default for bank account payouts
PayPal : Fallback for unsupported countries or when only PayPal is connected
Instant Payouts
Eligible sellers can receive daily payouts:
Eligibility
def eligible_for_instant_payouts?
# Must meet minimum sales threshold
# Must have good standing (no fraud flags)
# Must be in supported country
end
def instant_payouts_supported?
# Must have debit card connected
active_bank_account &. supports_instant_payouts?
end
Initiating Instant Payout
# app/controllers/instant_payouts_controller.rb
def create
result = InstantPayoutsService . new (
current_seller,
date: Date . parse (params. require ( :date ))
). perform
if result[ :success ]
redirect_to balance_path, notice: "Instant payout initiated successfully"
else
redirect_to balance_path, alert: result[ :error ]
end
end
Instant payouts may have higher fees than standard payouts. Check the fee schedule before enabling daily payouts.
Pausing Payouts
Payouts can be paused by multiple sources:
User-Initiated Pause
# In Settings > Payments
current_seller. update ( payouts_paused_by_user: true )
System-Initiated Pause
def payouts_paused_by_source
return nil unless payouts_paused_internally?
payouts_paused_by || PAYOUT_PAUSE_SOURCE_GUMROAD
end
Pause sources:
PAYOUT_PAUSE_SOURCE_STRIPE: Stripe verification required
PAYOUT_PAUSE_SOURCE_GUMROAD: Fraud prevention or policy violation
user: Manually paused by seller
Checking Payout Status
def payouts_paused?
payouts_paused_by_user? || payouts_paused_internally?
end
def payouts_paused_for_reason
# Returns human-readable reason for pause
end
When payouts are paused, your balance continues to accumulate. Payouts resume automatically once verification is complete.
Payout History API
Access payout history via API:
# app/controllers/api/v2/payouts_controller.rb
GET / api / v2 / payouts
# Query parameters:
# - before: YYYY-MM-DD (end date)
# - after: YYYY-MM-DD (start date)
# - page_key: pagination token
# - include_upcoming: true/false
# - include_sales: true/false (requires view_sales scope)
# - include_transactions: true/false
{
"payouts" : [
{
"id" : "payout_abc123" ,
"amount_cents" : 50000 ,
"currency" : "USD" ,
"status" : "paid" ,
"payout_date" : "2024-03-15" ,
"payout_period_end_date" : "2024-03-08" ,
"processor" : "stripe" ,
"bank_account_last4" : "1234"
}
],
"next_page_key" : "encoded_pagination_token"
}
Failed Payouts
When payouts fail:
Email Notification : Seller receives email with error details
def send_payout_failure_email
# Sent when payout fails
end
Balance Restoration : Funds return to unpaid balance
Retry : Automatic retry on next payout date
Common Failure Reasons
Invalid bank account details
Closed bank account
Bank rejected transfer
Insufficient permissions (PayPal)
Account verification required (Stripe)
After 3 failed payout attempts, payouts may be automatically paused. Update your payment information in Settings > Payments.
Cross-Border Payouts
For international sellers receiving USD payouts:
def supports_stripe_cross_border_payouts?
# Returns true for countries that support USD payouts
# but may not support local currency processing
end
def min_cross_border_payout_amount_usd_cents
# Minimum amount for cross-border USD payouts
end
Cross-border payouts:
Sent in USD via Stripe
Converted by seller’s bank
May have currency conversion fees
Higher minimum thresholds may apply
Best Practices
Set Appropriate Thresholds Balance transfer fees against cash flow needs. Higher thresholds reduce fees but delay access to funds.
Keep Payment Info Updated Outdated bank account or PayPal information causes payout failures. Verify details regularly.
Monitor Balance Page Check upcoming payouts and balance regularly. Address any issues before payout day.
Respond to Verification Requests Complete Stripe verification promptly to avoid payout delays or suspension.