Skip to main content

Developer Payouts

Overview​

Extension developers earn a revenue share that is credited to their balance. A payout moves the whole balance to the developer, with a self-billed credit note in the same transaction (see Developer Credit Notes). Only developers with a verified identity are paid.

A payout is created in one of three ways, always as pending, with the balance debited:

SourceWhen
RequestThe developer clicks Request payout (requestPayout / POST /v1/developer/payouts/request). The balance must reach the minimum of the payout method.
Closing payoutThe developer schedules a profile deletion with a grace period; the remaining balance is paid out even below the minimum.
Payout cycleOnce per calendar month (Europe/Berlin) Lumio pays out every balance that reaches the method's minimum.

A developer has at most one pending or processing payout at a time. While one is open, a profile deletion waits for it (409 DEVELOPER_FUNDS_OUTSTANDING).

Payout cycle​

The API runs the payout cycle every 15 minutes on every replica; running it on several replicas at once is safe. Each run has two steps.

  1. Monthly scheduling. Every verified developer whose balance reaches the minimum of their method (min_payout_stripe, min_payout_paypal, min_payout_bank) gets a payout, unless they already had a payout this calendar month (requested, closing, failed or scheduled). Stripe and PayPal developers are only scheduled while that provider's credentials are configured, so no balance is booked that Lumio cannot send. SEPA payouts are always scheduled; an operator transfers them.

  2. Sending. Every pending Stripe or PayPal payout that was never sent, whether scheduled, requested or a closing payout, is sent:

    MethodCallResult
    StripeTransfer to the developer's Connect accountcompleted; a transfer is final when it is created
    PayPalBatch payout to the developer's PayPal e-mailprocessing, then completed or failed from the PayPal payouts webhook
    SEPA (bank)nonestays pending until an operator records the transfer

A payout is sent at most once. Before calling the provider the cycle marks it (execution_started_at) and saves the mark. Then:

Provider answerWhat happens
Acceptedcompleted (Stripe) or processing (PayPal)
Refused (for example an invalid destination, or insufficient platform funds)failed: the balance is credited back and the credit note cancelled. The developer can request again
Not reached (connection refused, rate limited, no PayPal token)The mark is removed; the next run sends it
Unknown (timeout, provider error 5xx, duplicate request)Stays pending with the mark and is never sent again. An operator checks with the provider and settles it

Operator settlement​

Operators settle what the cycle cannot: SEPA transfers and payouts whose answer is unknown. Such a payout is listed with needs_operator: true. In the admin app they are settled on the Developer Payouts page; the API:

ActionGraphQLRESTPermission
List payouts (newest first, optional status filter)adminDeveloperPayoutsGET /v1/admin/developer-payoutsbilling:read
Mark paidcompleteDeveloperPayoutPOST /v1/admin/developer-payouts/{id}/completebilling:edit
Mark failed (balance credited back, credit note cancelled)failDeveloperPayoutPOST /v1/admin/developer-payouts/{id}/failbilling:edit

Only a pending or processing payout can be settled (409 PAYOUT_NOT_IN_FLIGHT otherwise). A payout the cycle marked less than 15 minutes ago cannot be marked failed (409 PAYOUT_BEING_SENT): the provider call may still be running, and marking it failed could pay it twice. Mark it failed only after you confirmed with Stripe or PayPal that nothing arrived.

Configuration​

[payments] in the API config:

KeyENVDefaultMeaning
payout_cycle_enabledLUMIO__PAYMENTS__PAYOUT_CYCLE_ENABLEDtrueRun the cycle. With false nothing is scheduled or sent; requested payouts wait for an operator
stripe_secret_keyLUMIO__PAYMENTS__STRIPE_SECRET_KEYemptyWithout it Stripe payouts are neither scheduled nor sent
paypal_client_id, paypal_client_secretLUMIO__PAYMENTS__PAYPAL_CLIENT_ID, …_SECRETemptyWithout both, PayPal payouts are neither scheduled nor sent
paypal_environmentLUMIO__PAYMENTS__PAYPAL_ENVIRONMENTsandboxlive for real payouts
min_payout_stripe, min_payout_paypal, min_payout_bankLUMIO__PAYMENTS__MIN_PAYOUT_*100, 2500, 5000Minimum balance in cents

Without a complete [billing.issuer] no credit note and so no payout can be issued; the cycle then schedules nothing.

Audit events​

EventScopeWhen
developer:payout_requesteduserThe developer requested a payout, or the closing payout of a profile deletion was created (source: request, closing)
system:developer_payout_scheduledsystemThe monthly cycle created a payout
system:developer_payout_sentsystemThe cycle handed a payout to Stripe or PayPal
system:developer_payout_completedsystemAn operator marked a payout paid, or the PayPal webhook confirmed it (source: operator, webhook)
system:developer_payout_failedsystemThe provider refused it, an operator marked it failed, or the PayPal webhook reported it (source: cycle, operator, webhook)

Metadata: payout_id, developer_id, method, amount, currency, status, the masked destination payout_reference, the provider ids, and for a failure the refunded amount and the cancellation note's number. It never contains the full PayPal e-mail, IBAN, or the payee's name and address.