Server-Side Bank Account Tokenization

Tokenize existing bank account data for recurring ACH payments

Server-Side Bank Account Tokenization

If you already have bank account data in your system, Preczn provides two server-side methods to tokenize that data for recurring ACH payments. Unlike credit card data (which falls under PCI scope), many businesses already store bank account information, making this a common integration path.

For collecting new bank account details directly from customers, see ACH PaymentFields Integration.

Tokens allow you to charge a customer's bank account multiple times without transmitting their account details on every request.

Tokenization Methods

Method 1: Tokenize During Transaction

Include tokenize=true as a query parameter when processing an ACH sale to automatically create a multi-use token:

POST /v1/transactions?tokenize=true
{
  "type": "sale",
  "merchantId": "mid_abc123",
  "amount": 5000,
  "currency": "USD",
  "payment": {
    "bankAccount": {
      "type": "personalChecking",
      "account": "123456789",
      "routing": "987654321",
      "bankCountry": "USA"
    }
  },
  "firstName": "John",
  "lastName": "Doe"
}

Response includes the multi-use token:

{
  "id": "txn_abc123",
  "type": "sale",
  "amount": 5000,
  "currency": "USD",
  "merchantId": "mid_abc123",
  "authorization": {
    "status": "P",
    "processorCode": "00",
    "processorMessage": "ACH transaction submitted",
    "approvedAmount": 5000
  },
  "payment": {
    "token": "tkn_xyz789",
    "type": "personalChecking",
    "last4": "6789",
    "bin": "987654321"
  },
  "processor": {
    "id": "pfmCon_xyz789",
    "name": "Payrix",
    "routingSource": "plan"
  },
  "firstName": "John",
  "lastName": "Doe",
  "createdOn": "2024-01-15T10:30:00Z"
}

Method 2: Direct Tokenization via Token Endpoint

Create a token without processing a transaction. This is useful for saving payment methods in user profiles:

POST /v1/tokens
{
  "type": "bankAccount",
  "merchantId": "mid_abc123",
  "bankAccount": {
    "type": "personalChecking",
    "account": "123456789",
    "routing": "987654321",
    "bankCountry": "USA"
  },
  "firstName": "John",
  "lastName": "Doe"
}

Response:

{
  "id": "tkn_xyz789",
  "merchantId": "mid_abc123",
  "token": "tkn_xyz789",
  "type": "bankAccount",
  "bankAccount": {
    "type": "personalChecking",
    "account": "6789",
    "routing": "987654321",
    "bankCountry": "USA"
  },
  "firstName": "John",
  "lastName": "Doe",
  "createdOn": "2024-01-15T10:30:00Z"
}

Token Request Fields

Required Fields

FieldTypeDescription
typestringMust be "bankAccount"
merchantIdstringThe merchant ID to associate the token with
bankAccount.typestringAccount type: personalChecking, personalSavings, corporateChecking, or corporateSavings
bankAccount.accountstringBank account number (4-17 digits)
bankAccount.routingstringBank routing number (9 digits)
bankAccount.bankCountrystringBank country code (currently only "USA" is supported)

Optional Fields

FieldTypeDescription
firstNamestringAccount holder's first name (recommended for personal accounts)
lastNamestringAccount holder's last name (recommended for personal accounts)
emailstringAccount holder's email address
phonestringAccount holder's phone number
billingAddressobjectAccount holder's billing address
accountBusinessNamestringBusiness name for corporate accounts
achMandatestringCustomer's authorization text for ACH debits. Required for some processors (e.g., Braintree)

Tip: Including customer information (firstName, lastName, accountBusinessName, achMandate) when creating a token means you won't need to provide them on every subsequent transaction using that token.

Using Tokens for Recurring Payments

Once you have a multi-use token, use it for subsequent transactions:

POST /v1/transactions
{
  "type": "sale",
  "merchantId": "mid_abc123",
  "amount": 5000,
  "currency": "USD",
  "payment": {
    "token": "tkn_xyz789"
  }
}

Token Types

Single-Use Tokens

Tokens created via ACH PaymentFields are single-use by default. They can only be used for one transaction.

Multi-Use Tokens

Tokens created via:

  • Direct tokenization endpoint (POST /v1/tokens)
  • Transaction with ?tokenize=true query parameter

These tokens can be used for multiple transactions (recurring payments, subscriptions, etc.).

Personal Account Requirements

For personal accounts (personalChecking, personalSavings), include the firstName and lastName fields:

{
  "type": "bankAccount",
  "merchantId": "mid_abc123",
  "bankAccount": {
    "type": "personalChecking",
    "account": "123456789",
    "routing": "987654321",
    "bankCountry": "USA"
  },
  "firstName": "John",
  "lastName": "Doe"
}

Corporate Account Requirements

For corporate/business accounts (corporateChecking, corporateSavings), include the accountBusinessName field:

{
  "type": "bankAccount",
  "merchantId": "mid_abc123",
  "bankAccount": {
    "type": "corporateChecking",
    "account": "123456789",
    "routing": "987654321",
    "bankCountry": "USA"
  },
  "accountBusinessName": "Acme Corporation"
}

ACH Mandate for Braintree

When using Braintree as your processor, you must include an ACH mandate (authorization text):

{
  "type": "bankAccount",
  "merchantId": "mid_abc123",
  "bankAccount": {
    "type": "personalChecking",
    "account": "123456789",
    "routing": "987654321",
    "bankCountry": "USA"
  },
  "achMandate": "I authorize Acme Corp to debit my bank account for the amount specified."
}

Error Messages

These are Preczn API errors returned when a request fails validation or processing. The error and message fields correspond to the API response format documented in the ACH Error Reference.

Validation Errors

ErrorMessageCauseSolution
Bad RequestRouting number is requiredMissing routing numberInclude bankAccount.routing
Bad RequestRouting number must be exactly 9 digitsInvalid routing number formatVerify the routing number is exactly 9 digits
Bad RequestAccount number is requiredMissing account numberInclude bankAccount.account
Bad RequestAccount number must be between 4 and 17 digitsInvalid account number lengthVerify account number is 4-17 digits
Bad RequestAccount type is requiredMissing account typeInclude bankAccount.type
Bad RequestBank country must be one of: USAUnsupported countryOnly US bank accounts are supported
Bad RequestACH mandate is required for Braintree ACH transactionsMissing mandate for BraintreeInclude achMandate field

For a complete list of errors, see the ACH Error Reference.

Best Practices

  1. Discard raw bank details after tokenization - Never store account or routing numbers in your system; rely solely on the token
  2. Include customer info when creating tokens - Adding firstName, lastName, or accountBusinessName during tokenization means you won't need to include them on every transaction
  3. Store tokens with customer records - Associate token IDs with customer profiles in your database for easy retrieval
  4. Use Method 2 for saved payment methods - When customers save a payment method without an immediate purchase, use the direct token endpoint
  5. Provide customer controls - Allow customers to view (masked), update, or remove their saved payment methods