Documentation

Payment methods

Customer-side payout destinations — bank, PayPal, Venmo, Cash App, debit card, crypto.

A payout method is a saved destination on a wallet — where the wallet's available balance gets sent when a payout completes. The customer manages their own list through /client/finance/payout-methods. The first method added is the default; the customer can change defaults at any time.

Despite the name overlap, "payment methods" in Finance are payout destinations (money out). The customer-side cards used to take payment in are managed separately — Stripe tokens stored against the customer record. See the Storefront checkout docs for inbound payment flows.

Supported types

The type field on a payout method picks the schema branch:

typeRequired fields
bankroutingNumber, accountNumber, accountType (checking/savings), accountHolderName, accountHolderType
paypalemail
venmohandle or phoneNumber
cashappcashtag or phoneNumber
debit_cardtoken (Stripe-tokenised), last4, expirationMonth, expirationYear, cardholderName, cardBrand
cryptoaddress, currency, network

Sensitive fields — full account numbers, raw card data — never sit on AppEngine. Cards are tokenised through Stripe before being saved; the only thing AppEngine stores is the token plus display metadata (last4, cardBrand, expiry).

Listing methods

GET/client/finance/payout-methodsJWT

Returns the customer's payout methods. Default method has isDefault: true.

curl https://appengine.appmint.io/client/finance/payout-methods \
  -H "orgid: $ORG" \
  -H "Authorization: Bearer $JWT"

Adding a method

POST/client/finance/payout-methodsJWT
FieldTypeDescription
type*'bank' | 'paypal' | 'venmo' | 'cashapp' | 'debit_card' | 'crypto'

Destination kind. Determines which sub-object is read.

labelstring

Display name — "Chase checking", "Personal PayPal".

isDefaultboolean

Set true to make this the default. The previous default is automatically demoted.

bankobject

Bank fields when type = "bank".

debitCardobject

Card fields when type = "debit_card". Pass token from Stripe Elements; never raw PAN.

paypalobject

{ email } when type = "paypal".

venmoobject

{ handle?, phoneNumber? } — at least one required.

cashappobject

{ cashtag?, phoneNumber? } — at least one required.

cryptoobject

{ currency, address, network } — for example BTC on bitcoin, or USDC on polygon.

{
  "type": "bank",
  "label": "Primary checking",
  "isDefault": true,
  "bank": {
    "bankName": "Chase",
    "accountType": "checking",
    "routingNumber": "021000021",
    "accountNumber": "9876543210",
    "accountHolderName": "Alice Doe",
    "accountHolderType": "individual"
  }
}

A debit_card example using a Stripe token:

{
  "type": "debit_card",
  "label": "Visa debit",
  "debitCard": {
    "token": "tok_visa_debit",
    "cardBrand": "visa",
    "last4": "4242",
    "expirationMonth": 12,
    "expirationYear": 2028,
    "cardholderName": "Alice Doe"
  }
}

Updating a method

PUT/client/finance/payout-methods/{methodId}JWT

Limited update — you can change label, isDefault, and status. Changing routing/account numbers requires deleting the method and re-adding.

{ "label": "New label", "status": "verified" }

status is one of pending | verified | disabled. Verification status is set by an out-of-band check (a microdeposit confirmation, a PayPal handshake, a card verification charge) — not by this endpoint directly. Setting status: "disabled" removes a method from default-selection without deleting it.

Setting the default

PUT/client/finance/payout-methods/{methodId}/defaultJWT

Promotes a method to default and demotes any previous default. No body required.

Removing a method

DELETE/client/finance/payout-methods/{methodId}JWT

Returns { success: true }. If the deleted method was the default and other methods exist, no automatic re-promotion happens — the customer's next payout will need a methodId until they set a new default.

Tokenisation flow

For debit_card, the customer-side flow looks like this:

  1. 1

    Mount Stripe Elements

    Render Stripe Elements (or Stripe.js card form) on your dashboard.

  2. 2

    Create a token

    Call stripe.createToken(cardElement) from the browser. You receive tok_... plus card.last4, card.brand, card.exp_month, card.exp_year.

  3. 3

    POST to AppEngine

    Send the token plus display metadata to /client/finance/payout-methods with type: "debit_card". Never send raw card numbers.

For bank, you can either accept routing+account directly (PCI-safe — bank data is not card data, but treat it carefully), or integrate a Plaid micro-deposit flow upstream and store only a Plaid token in the bank object.

Validation and limits

  • An owner can have many methods of the same type — for example, multiple bank accounts.
  • Exactly one method is isDefault: true at a time.
  • verified status is enforced before a payout will run; pending methods can be saved but not used.
  • A wallet's payout-settings defaultMethodId overrides the per-method isDefault flag if both are set.