> ## Documentation Index
> Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Payout Methods

> Add, view, and remove the destination where developer earnings are paid out.

A **payout method** is the destination where a developer's accrued earnings
are wired by the platform. LaunchMyStore is the merchant of record for all
app charges, so the payout method is just a payment **destination** — the
developer does not need their own Stripe Connect account or a payment
processor of their own.

Two destination types are supported:

* **`bank`** (SWIFT international wire) — account holder name, bank name,
  SWIFT/BIC, country, account number or IBAN. Account number + IBAN are
  encrypted at the application layer before storage; only the last 4
  digits are kept in cleartext for display.
* **`paypal`** — PayPal email address.

Each developer can have **one** active payout method at a time. Adding a
second overwrites the first; to switch types, just call `POST` again with
the new payload.

**Auth:** developer JWT. The `developerId` is read from the token.

<Note>
  Stripe Connect (Express / Standard) onboarding — which would let
  developers receive payouts directly to a connected Stripe account on a
  faster cadence — is on the roadmap. The current API uses the SWIFT /
  PayPal destination model below.
</Note>

***

## Get current payout method (masked)

`GET /apps/developer/payout-method`

Returns the saved destination with sensitive fields masked. Returns
`{ data: null }` when no method is configured.

```bash theme={null}
curl -X GET "https://api.launchmystore.io/apps/developer/payout-method" \
  -H "Authorization: Bearer <DEVELOPER_JWT>"
```

<ResponseField name="data.payoutMethodId" type="string">UUID of the row.</ResponseField>
<ResponseField name="data.type" type="string">`bank` or `paypal`.</ResponseField>
<ResponseField name="data.status" type="string">`pending`, `active`, `restricted`, or `disabled`.</ResponseField>
<ResponseField name="data.verifiedAt" type="string">ISO timestamp when ops verified the destination, or `null`.</ResponseField>

Bank-only fields (`type: bank`):

<ResponseField name="data.accountHolderName" type="string" />

<ResponseField name="data.bankName" type="string" />

<ResponseField name="data.swiftCode" type="string" />

<ResponseField name="data.country" type="string">ISO 3166-1 alpha-2.</ResponseField>

<ResponseField name="data.bankAddress" type="string" />

<ResponseField name="data.last4" type="string">Last 4 of account number or IBAN. Full number is never returned.</ResponseField>

PayPal-only fields (`type: paypal`):

<ResponseField name="data.paypalEmail" type="string" />

### Example response (bank)

```json theme={null}
{
  "status": 200,
  "data": {
    "payoutMethodId": "8d4f1c10-3b6e-4e76-9b6a-1a17a5be58a0",
    "type": "bank",
    "status": "active",
    "accountHolderName": "Jane Doe",
    "bankName": "HDFC Bank",
    "swiftCode": "HDFCINBB",
    "country": "IN",
    "bankAddress": "Sector 16, Gurugram, 122001",
    "last4": "4729",
    "paypalEmail": null,
    "verifiedAt": "2026-04-15T03:12:47.881Z"
  }
}
```

### Example response (paypal)

```json theme={null}
{
  "status": 200,
  "data": {
    "payoutMethodId": "0c8d2a1d-…",
    "type": "paypal",
    "status": "active",
    "paypalEmail": "jane@example.com",
    "verifiedAt": "2026-03-02T14:21:09.012Z"
  }
}
```

### No method configured

```json theme={null}
{ "status": 200, "data": null }
```

***

## Save a payout method

`POST /apps/developer/payout-method`

Saves or overwrites the destination. The request fields depend on `type`:

### Bank (SWIFT)

<ParamField body="type" type="string" required>Must be `bank`.</ParamField>
<ParamField body="accountHolderName" type="string" required>Name on the account.</ParamField>
<ParamField body="bankName" type="string" required>Receiving bank.</ParamField>
<ParamField body="swiftCode" type="string" required>8 or 11 character SWIFT/BIC.</ParamField>
<ParamField body="country" type="string" required>ISO 3166-1 alpha-2 country code.</ParamField>
<ParamField body="accountNumber" type="string">Account number. Required when `iban` is not supplied. Encrypted before storage; only `last4` is recoverable.</ParamField>
<ParamField body="iban" type="string">IBAN. Required when `accountNumber` is not supplied. Encrypted before storage.</ParamField>
<ParamField body="bankAddress" type="string">Free-form bank address (recommended for international wires).</ParamField>

```bash theme={null}
curl -X POST "https://api.launchmystore.io/apps/developer/payout-method" \
  -H "Authorization: Bearer <DEVELOPER_JWT>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "bank",
    "accountHolderName": "Jane Doe",
    "bankName": "HDFC Bank",
    "swiftCode": "HDFCINBB",
    "country": "IN",
    "accountNumber": "50100123454729",
    "bankAddress": "Sector 16, Gurugram, 122001"
  }'
```

### PayPal

<ParamField body="type" type="string" required>Must be `paypal`.</ParamField>
<ParamField body="paypalEmail" type="string" required>The PayPal account email.</ParamField>

```bash theme={null}
curl -X POST "https://api.launchmystore.io/apps/developer/payout-method" \
  -H "Authorization: Bearer <DEVELOPER_JWT>" \
  -H "Content-Type: application/json" \
  -d '{ "type": "paypal", "paypalEmail": "jane@example.com" }'
```

### Response

Returns the saved row in the same masked shape as `GET`. The row starts in
`status: pending` and transitions to `active` after platform ops verifies
the destination (typically within one business day).

```json theme={null}
{
  "status": 201,
  "data": {
    "payoutMethodId": "8d4f1c10-…",
    "type": "bank",
    "status": "pending",
    "accountHolderName": "Jane Doe",
    "bankName": "HDFC Bank",
    "swiftCode": "HDFCINBB",
    "country": "IN",
    "last4": "4729",
    "verifiedAt": null
  }
}
```

***

## Remove the current method

`DELETE /apps/developer/payout-method`

Removes the saved destination. The developer's balance is **not** affected
— it just sits on the ledger until a new method is added. Scheduled
payouts pause while no method is configured.

```bash theme={null}
curl -X DELETE "https://api.launchmystore.io/apps/developer/payout-method" \
  -H "Authorization: Bearer <DEVELOPER_JWT>"
```

```json theme={null}
{ "status": 200, "state": "success", "message": "Payout method removed" }
```

***

## Default / multiple methods

The current implementation enforces **one** payout method per
developer. There is no `setDefault` operation because there is no "list" — saving a
new method overwrites the existing one.

Multi-destination support (split payouts between bank + PayPal, or one
destination per app) is on the roadmap.

## Encryption

`accountNumber` and `iban` are encrypted (AES-256-GCM) before being
stored and are **never** returned in API responses. Only `last4` is
exposed for display.

## Error codes

| Code  | Description                                                                                  |
| ----- | -------------------------------------------------------------------------------------------- |
| `400` | `type` not `bank` or `paypal`.                                                               |
| `400` | `type: bank` with neither `accountNumber` nor `iban`.                                        |
| `400` | `swiftCode` not 8 or 11 chars / `country` not ISO alpha-2 / `paypalEmail` not a valid email. |
| `401` | Missing or invalid developer JWT.                                                            |
| `404` | `DELETE` called with no method on file.                                                      |
