Receive via ACH

Share your account's ACH coordinates so a payer can send an ACH credit into your Passport Account.

Receive via ACH is how you get paid by ACH without initiating anything: you share your Passport Account's ACH routable details with a payer, and they send an ACH credit from their bank. The funds arrive as an External Credit, which posts automatically when it matches your account or waits for review when it can't.

Use this when the sender controls timing — payroll funding, marketplace or partner disbursements into your account, or one-time inbound bank transfers.

Before you share details

  • The receiving Passport Account exists and is ACTIVE — routable details may be generated earlier, but funds only apply once the account is ACTIVE. See Account Lifecycle.
  • Your webhook endpoint is subscribed to external-transaction events so you're notified when a credit arrives.

The details you share

Read your account's routable details from the GET /v1/customer/id/{id}/account/id/{id} response, under the routableAccount object, and share the ACH fields with the payer:

FieldShare for ACHDescription
accountNumberAccount number for ACH credits
routingNumberRouting number for ACH transfers
memoOptionalReference the sender includes on the ACH credit to help it match cleanly

ACH and wire details are different

Use accountNumber + routingNumber for ACH. The wire fields (wireAccountNumber, wireRoutingNumber) are for Receive via Wire — don't share them for an ACH credit.


How it works

You don't call an API to receive — you share details, the payer sends, and PCE records the inbound credit for matching.

sequenceDiagram
    participant You as Your application
    participant PCE as PCE
    participant Payer as Payer's bank

    You->>PCE: GET account → read routableAccount (ACH fields)
    You->>Payer: Share accountNumber + routingNumber (+ memo)
    Payer->>PCE: ACH credit arrives on your routable details
    PCE->>PCE: Record External Credit, attempt rule-based matching
    alt Matched
        PCE->>PCE: Post funds to your account
        PCE-->>You: Webhook — credit posted
    else Unmatched
        PCE-->>You: Webhook — credit in review
        Note over PCE: Accept/reject on the External Credits page
    end

Scenarios

Scenario 1: Fund an account from an external payroll provider (auto-matched)

A payroll provider sends a recurring ACH credit to top up your operating account. You shared the correct accountNumber, routingNumber, and a consistent memo, so PCE matches the credit and posts it automatically — no action needed.

You'll also need: the receiving account ACTIVE, and the sender using the exact routable details and memo you provided.

Scenario 2: Receive a one-off credit that needs review

A new business partner sends an ACH credit but omits the memo, so PCE can't confidently match it. The credit is recorded as an External Credit and waits for review; you (or your Program Manager) identify the destination account and accept it. See External Credits for the accept/reject calls and the automatching-training option.


After the credit arrives

Inbound ACH credits are handled as External Credits — that page owns the matching, review, accept/reject, and lifecycle. From here:

  • Track inbound credits by webhook (production) or by listing/retrieving External Credits (reconciliation fallback).
  • Don't show funds as available until the credit is accepted and posted to the account.

For the status model and tracking mechanics shared across money movement, see Transaction lifecycle.


Best practices

PracticeDescription
Share only the ACH fieldsGive the payer accountNumber + routingNumber, not the wire fields
Provide the memo exactlyA consistent memo helps credits auto-match and reduces manual review
Confirm the account is ACTIVE firstFunds only apply to an ACTIVE account
Use webhooks, poll as fallbackSubscribe to external-transaction events; use list/retrieve for reconciliation
Don't release funds earlyTreat funds as available only after the credit posts

Related

See also


Did this page help you?
.readme-logo { display: none !important; }