ACH Payments

Rail: ACH (NACHA) Processing: Batch (Standard + Same-Day) Reversible: Yes (within 5 banking days)

The ACH endpoint initiates ACH credit transfers (PPD, CCD, CTX) and direct debits. Payments are submitted to FedACH at the next applicable processing window. Use Same-Day ACH ("processingSpeed": "same_day") for same-business-day settlement when urgency is required.

ACH is Batch, Not Real-Time ACH payments are not settled at the time of API response. A successful 201 Created response means the payment has been accepted by PayPlus and queued for the next processing window. Settlement occurs at T+1 (standard) or same-day (SDA). Use webhooks to receive settlement confirmation.

Initiate an ACH Payment

POST /v2/payments/ach

Creates a new ACH payment instruction. The payment enters the PayPlus workflow for validation, compliance screening, and approval before submission to the ACH network.

Request Body Parameters

FieldTypeDescription
secCodestringRequiredNACHA Standard Entry Class code. Accepted values: PPD, CCD, CTX, WEB, TEL, IAT.
transactionTypestringRequiredDirection of fund movement: credit (push funds to beneficiary) or debit (pull funds from consumer โ€” requires authorization).
amountintegerRequiredPayment amount in cents (USD). Example: 150000 = $1,500.00. Maximum: 100000000 ($1,000,000) for standard ACH.
effectiveDatestring (date)OptionalRequested effective entry date in YYYY-MM-DD format. If omitted, PayPlus uses the next available settlement date based on the processing window. Must be a business day.
processingSpeedstringOptionalProcessing urgency: standard (default, T+1 settlement) or same_day (Same-Day ACH, requires SDA eligibility โ€” see NACHA rules). SDA adds a $0.052 per-transaction fee.
originatorobjectRequiredOriginating account details. See Originator Object below.
beneficiaryobjectRequiredReceiving account details. See Beneficiary Object below.
addendastringOptionalAddenda record content (up to 80 characters for PPD/CCD; full structured addenda for CTX). Used for remittance information.
referenceIdstringOptionalYour system's reference identifier for this payment. Stored in PayPlus and returned in all payment status responses and webhook events. Maximum 35 characters.

Originator Object

FieldTypeDescription
namestringRequiredAccount holder name. Maximum 22 characters (NACHA field limit).
accountNumberstringRequiredODFI account number (your institution's originating account). Maximum 17 characters.
accountTypestringRequiredchecking or savings.
routingNumberstringRequiredODFI ABA routing transit number. 9 digits.
idstringOptionalCompany ID (for CCD/CTX). Appears in NACHA Batch Header record field 5.

Beneficiary Object

FieldTypeDescription
namestringRequiredReceiver name. Maximum 22 characters.
accountNumberstringRequiredReceiving account number at the RDFI. Maximum 17 characters.
accountTypestringRequiredchecking or savings.
routingNumberstringRequiredRDFI ABA routing transit number. 9 digits. Must be a valid, active ACH-participating institution.

Example Request

POST /v2/payments/ach HTTP/1.1
Host: api.payplus.yourbank.internal
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Content-Type: application/json
Idempotency-Key: f7a2b3c4-d5e6-7f8a-9b0c-d1e2f3a4b5c6

{
  "secCode": "CCD",
  "transactionType": "credit",
  "amount": 350000,
  "processingSpeed": "same_day",
  "originator": {
    "name": "FIRST NATIONAL BANK",
    "accountNumber": "100020003000",
    "accountType": "checking",
    "routingNumber": "021000021",
    "id": "1234567890"
  },
  "beneficiary": {
    "name": "ACME CORP",
    "accountNumber": "987654321",
    "accountType": "checking",
    "routingNumber": "071000013"
  },
  "addenda": "INV-2026-03-001 PAYMENT",
  "referenceId": "VENDOR-PMT-20260315-001"
}

Response

201 Created

{
  "data": {
    "paymentId": "pmt_ach_a3k9f2m8x7p4r1q0",
    "rail": "ach",
    "secCode": "CCD",
    "status": "validated",
    "amount": 350000,
    "processingSpeed": "same_day",
    "effectiveDate": "2026-03-15",
    "submissionWindow": "SDA_WINDOW_2",
    "submissionCutoff": "2026-03-15T14:30:00Z",
    "referenceId": "VENDOR-PMT-20260315-001",
    "createdAt": "2026-03-15T11:05:22Z"
  },
  "meta": { "requestId": "req_9e7c4f2a1b3d", "timestamp": "2026-03-15T11:05:22Z" }
}

Submit an ACH Batch

POST /v2/payments/ach/batch

Submits a multi-record ACH batch (e.g., payroll) as a single API call. PayPlus generates the NACHA file. Maximum 50,000 records per batch submission.

Request Body Parameters

FieldTypeDescription
batchNamestringRequiredDescriptive batch name for operational tracking. Maximum 10 characters (appears in NACHA Company Entry Description).
secCodestringRequiredSEC code for all records in the batch. All records in a NACHA batch must share the same SEC code.
processingSpeedstringOptionalstandard (default) or same_day. All records in the batch use the same processing speed.
effectiveDatestring (date)OptionalRequested effective date for all records. Must be a business day. If omitted, PayPlus assigns the next available settlement date.
originatorobjectRequiredODFI details applied to all records in the batch.
recordsarrayRequiredArray of payment records. Each record contains: transactionType, amount, beneficiary (name, accountNumber, accountType, routingNumber), and optionally addenda and referenceId.
referenceIdstringOptionalYour batch reference identifier. Stored in PayPlus and returned in batch status responses.

Example Request (truncated)

POST /v2/payments/ach/batch HTTP/1.1
...

{
  "batchName": "PAYROLL",
  "secCode": "PPD",
  "processingSpeed": "standard",
  "effectiveDate": "2026-03-17",
  "originator": {
    "name": "FIRST NATIONAL BANK",
    "accountNumber": "100020003000",
    "accountType": "checking",
    "routingNumber": "021000021",
    "id": "1234567890"
  },
  "records": [
    {
      "transactionType": "credit",
      "amount": 225000,
      "beneficiary": {
        "name": "JANE SMITH",
        "accountNumber": "112233445",
        "accountType": "checking",
        "routingNumber": "071000013"
      },
      "addenda": "PAYROLL 2026-03-15",
      "referenceId": "EMP-10042"
    }
    // ... additional records
  ],
  "referenceId": "PAYROLL-20260315"
}

Response

202 Accepted

{
  "data": {
    "batchId": "batch_ach_7c3d1f9e2b4a",
    "status": "processing",
    "recordCount": 842,
    "totalAmount": 198475200,
    "effectiveDate": "2026-03-17",
    "referenceId": "PAYROLL-20260315",
    "validationSummary": {
      "valid": 840,
      "invalid": 2,
      "invalidDetails": [
        { "recordIndex": 7, "referenceId": "EMP-10049", "error": "INVALID_ROUTING_NUMBER" },
        { "recordIndex": 412, "referenceId": "EMP-10461", "error": "ACCOUNT_NUMBER_TOO_LONG" }
      ]
    }
  }
}

Get ACH Payment Status

GET /v2/payments/ach/{paymentId}

Returns the current status and details of an ACH payment. Use the paymentId returned when the payment was created.

Payment Status Values

StatusDescription
validatedPassed format validation; awaiting approval or STP processing
pending_approvalAwaiting human approval in PayPlus workflow (dual-control configured)
compliance_holdFlagged by OFAC screening; awaiting Compliance Officer review
approvedApproved; queued for next ACH processing window submission
submittedNACHA file submitted to FedACH; awaiting settlement
settledSettled; effective date passed and funds moved
returnedACH return received from RDFI; see returnCode field
rejectedRejected by PayPlus validation, compliance, or FedACH file rejection
reversedReversal submitted (reversal itself may still be pending settlement)

Get Return Details

GET /v2/payments/ach/{paymentId}/return

Returns ACH return details when a payment has status: "returned". Returns 404 if the payment has not been returned.

Example Response

{
  "data": {
    "paymentId": "pmt_ach_a3k9f2m8x7p4r1q0",
    "returnCode": "R01",
    "returnReason": "Insufficient Funds",
    "returnSettlementDate": "2026-03-17",
    "rdfiName": "CHASE BANK NA",
    "rdfiRoutingNumber": "071000013",
    "returnedAt": "2026-03-16T22:15:00Z",
    "representmentEligible": true,
    "representmentDeadline": "2026-09-12"
  }
}

Reverse an ACH Payment

POST /v2/payments/ach/{paymentId}/reverse

Initiates an ACH reversal for a settled payment. Reversals must be initiated within 5 banking days of the original payment's settlement date.

Reversal Eligibility Window ACH reversals are not guaranteed to succeed โ€” the RDFI is not obligated to accept a reversal if the funds have already been withdrawn by the receiver. Reversals are limited to: incorrect amount (only the difference may be reversed), duplicate entry, or incorrect account/routing number. Customer-initiated returns for authorized payments cannot use the reversal mechanism โ€” file as a return exception instead.

Request Body

{
  "reason": "incorrect_amount",
  "reversalAmount": 350000,
  "reasonDetail": "Original payment amount was $3,500.00 โ€” should have been $1,500.00. Reversing full amount."
}

ACH Payment Object Reference

FieldTypeDescription
paymentIdstringUnique PayPlus payment identifier. Format: pmt_ach_{16 chars}
railstringAlways "ach"
secCodestringNACHA Standard Entry Class code
transactionTypestring"credit" or "debit"
statusstringCurrent payment status (see status values above)
amountintegerAmount in cents (USD)
effectiveDatestringRequested effective entry date (YYYY-MM-DD)
processingSpeedstring"standard" or "same_day"
submissionWindowstringACH processing window used: STANDARD, SDA_WINDOW_1, SDA_WINDOW_2, SDA_WINDOW_3
traceNumberstringNACHA trace number assigned at submission. Available after status = "submitted".
returnCodestringACH return code (R01โ€“R85). Present only when status = "returned".
referenceIdstringYour system's reference identifier
createdAtstringISO 8601 timestamp of payment creation
updatedAtstringISO 8601 timestamp of last status update
โ† Overview Next: Instant Payments โ†’