Use APIs to integrate ACH direct debit payments

DocsLimited

Last updated: Apr 24th, 11:10pm

ACH, or Automated Clearing House, is a network that allows for electronic funds transfers between banks in the United States. PayPal now allows merchants to use ACH direct debit payments to accept payments from a payer by debiting directly from their bank account. For example, government agencies may use this feature for one-time payments for taxes, citations, or permit fees.

ACH direct debit can be used for one-time and recurring payments. ACH can only be transacted in USD.

How it works

The Pay by Bank button shows up on your website when a customer uses a browser for checkout.

image


When your payer selects the Pay by Bank button and if bank verification is required:

  1. Payer is connected to PayPal's bank verification system
  2. Payer is presented with an option to select their banking institution.
  3. Upon selection, payer can login and choose the appropriate debit account.
  4. The payer confirms purchase details, including bank information, recipient, transaction amount, and transaction date.
  5. The payer finalizes the sales transaction.

Know before you code

  • You must be an approved partner to integrate the ACH offering.
  • The instructions in Get Started will help you get your access token.
  • This server-side integration uses the Orders REST API.
  • Set intent: capture in the create order call for this feature to work.
  • Review the Nacha rules and other risks associated with ACH direct debit payments.

Review the liabilities

If an ACH payment is returned by your payer's bank, you are liable for the transaction amount PayPal might have already moved to your account and the return fees. These charges are reflected in the PayPal account set up during onboarding.

Understand the differences between unauthorized returns and the remaining type of returns to evaluate and control your exposure to any losses and manage your refund process. At a high level, the differences are as follows:

  • Unauthorized returns: Your payer can raise an unauthorized dispute anytime after the funds move out of their bank account to yours, within a timeframe of 60 days for consumer accounts and two days for business accounts. In unauthorized dispute cases, PayPal will charge your account in the amount of the original transaction amount plus a $5 dispute fee.
  • Other types of returns: Any non-unauthorized type of return, such as insufficient funds, invalid or closed account, or other reasons will not result in funds clearance. With these types of returns, you have less exposure to losses, unless you had requested PayPal to process the transaction as instant ACH. In the case you receive a non-unauthorized return and submitted the payment as standard ACH, then you will be liable for only the return fee. However, if you submitted the transaction as an instant ACH payment, then you will be liable for both the original transaction amount PayPal couldn't debit from your payer's bank account and the return fee.

You might be unnecessarily crediting your payer if you are issuing a refund to your payer, but the transaction gets returned from your payer's bank as a result of insufficient funds. To prevent any fraud or double-crediting your payers we recommend you:

  • Don't issue a refund until after the funds settle in your account.
  • Communicate to your payer immediately that you have started the refund process, and it will take at least 5 calendar days for them to receive the funds back in their bank account.
  • Don't ship your product or service if you haven't received the funds from your payer, which should happen after 5 calendar days for funds clearance.

Review SEC options

This integration requires a standard entry class (SEC) code. The following codes are available:

  • Default: Internet Initiated Entry (WEB)
  • Corporate Credit or Debit (CCD)
  • Telephone Initiated Entry (TEL)
  • Prearranged Payment and Deposit Entry (PPD)

Select a tab for more information about each SEC option:

WEB entries are direct debit payments initiated online. You must collect the authorization from your customer online. Refer to section on Authorization for a sample authorization you can use for WEB transactions. To remain in compliance with NACHA regulations, we recommend you store the full text of the authorization and following information as proof of consent:

  • Amount of transaction and bank details
  • Timestamp that indicates what date and time the consumer authorized the debit

Partner and merchant experience

Partners and merchants follow different steps to integrate with ACH using API integration on the PayPal Commerce Platform.

Partner integration overview

Setting up Company ID

Company ID is a 10-digit identifier used by banks and NACHA (governing and processing entity for ACH transactions), which uniquely identifies the entity collecting payments (aka Originator) via ACH.

Company ID is responsible for ensuring unique identification for entities and isolating transaction processing for these entities. These are in place to avoid any incorrect / fraudulent transactions and to isolate processing for each entity and which may be used to monitor and filter debits to unknown entities.

Details needed for Company ID creation:

  • Partner Name
  • Street Address
  • City
  • State
  • Zip Code
  • Country
  • Proposed Company ID (10 character alphanumeric)
  • Partner ID
  • ACH-IN (does partner need unbranded ACH-IN)
  • ACH-OUT

Onboarding

ACH as a payment method will be available to turn on for merchants on their PayPal Payment Settings page. Merchants will then be redirected to complete the remainder of the onboarding process. Depending on whether a merchant has previously onboarded for PPCP Advanced, merchants will experience a simplified one-click onboarding process. For new merchants, the onboarding process will require input of a series of short questions about a merchant's business information.

Onboard merchants

  • You'll need to onboard your merchants so they can use this product.
  • Modify your Partner Referral API call to include ACH in the products array for merchant onboarding.
  • Additionally, you can select PayPal Complete Payments Full Stack Offering Including ACH using the PPCP Onboarding API.
  • See Onboard merchants before payment for more information.

Set up your sandbox account to accept ACH

Before you can accept ACH on your website, verify that your sandbox business account supports ACH. Merchants can use the PayPal Developer Dashboard to set up their sandbox accounts to accept ACH. The integration for partner accounts includes creating a sandbox business account through sandbox.paypal.com. If the ACH status for the account shows as disabled, complete the sandbox onboarding steps to enable ACH.

  1. Log into the PayPal Developer Dashboard and go to your sandbox account.
  2. Go to Apps & Credentials.
  3. Click on My Apps & Credentials, and switch to Sandbox mode.
  4. Click on the Sandbox app you want to use.
  5. Scroll down to the Features section and locate Pay by Bank: ACH under Accept Payments.
  6. If the check box is not enabled, select it and click on Save Changes to enable it.

If you created a sandbox business account through sandbox.paypal.com, and the ACH status for the account shows as disabled, complete the sandbox onboarding steps to enable ACH.

Integrate ACH

Follow this integration process to add ACH as a checkout option, customize the payment experience, and process payments.

1

Create an order

To create an order for standard ACH direct debit payments, copy the following code and modify it:

    1curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders
    2 -H 'Content-Type: application/json'
    3 -H 'Authorization: Bearer ACCESS-TOKEN'
    4 -d '{
    5 "intent": "CAPTURE",
    6 "purchase_units": [
    7 {
    8 "amount": {
    9 "currency_code": "USD",
    10 "value": "100.00"
    11 },
    12 "payee": {
    13 "email_address": "[email protected]"
    14 }
    15 }
    16 ]
    17 }'

    Modify the code

    After you copy the code in the sample request, modify the following:

    • Change ACCESS-TOKEN to your access token.
    • Set intent to capture.
    • Change the standard_entry_class_code. Options are WEB,CCD, TEL, and PPD.
    • Optional: Change the purchase_unit/payment_instruction/platform_fees array to specify fees for the order.

    Step result

    A successful request results in the following:

    • A return status code of HTTP 201 Created.
    • A JSON response body that contains the order ID. You'll use the order ID to capture the order.

    Create an order and initiate bank account verification

    1. Sample request
    2. Sample response
    1curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders
    2 -H 'Content-Type: application/json'
    3 -H 'PayPal-Request-Id: REQUEST-ID' -H 'Authorization: Bearer ACCESS-TOKEN'
    4 -d '{
    5 "intent": "CAPTURE",
    6 "purchase_units": [
    7 {
    8 "amount": {
    9 "currency_code": "USD",
    10 "value": "100.00"
    11 },
    12 "payee": {
    13 "email_address": "[email protected]"
    14 }
    15 }
    16 ],
    17 "payment_source": {
    18 "bank": {
    19 "ach_debit": {
    20 "billing_address": {
    21 "country_code": "US"
    22 },
    23 "attributes": {
    24 "verification": {
    25 "paypal": {
    26 "method": "INSTANT_ACCOUNT_VERIFICATION"
    27 }
    28 }
    29 },
    30 "experience_context": {
    31 "locale": "en-US",
    32 "return_url": "https://example.com/return",
    33 "cancel_url": "https://example.com/cancel"
    34 }
    35 }
    36 }
    37 }
    38 }'

    Modify the code

    • Change ACCESS-TOKEN to your access token.
    • Specify the preferred language and set return_url and cancel_url. This is required to redirect the payer back to your site.
    2

    Confirm payment source

    This allows you to verify the user bank account through PayPal offered Instant Account Verification service or you can provide the customer bank account details as a payment source and call confirm payment source. The response result guides you next steps with regards to account verification.

    • The bank account must be verified before you can collect any money from that account.
    • The payer must authorize the direct debit. See Authorization section for more information.
    • Standard Entry Classification (SEC) codes are used to define how your payer has authorized the payment. PayPal accepts WEB, TEL, CCD, and PPD SEC codes. The default is WEB.
    • If you have an externally verified bank account to use, you shall set verification.external.status as VERIFIED and PayPal will acknowledge this status.
    • It is recommended to provide a unique merchant_customer_id. The id is used to track accounts and their verification status for the customer.

    Step 2A: Use PayPal instant verification service

    To verify the payer bank account through PayPal instant account verification service, copy the following code and modify it:

    1. Sample request
    2. Sample response
    1curl -v -k -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN36475T/confirm-payment-source
    2 -H 'Content-Type: application/json'
    3 -H 'Authorization: Bearer ACCESS-TOKEN'
    4 -d '{
    5 "payment_source": {
    6 "bank": {
    7 "ach_debit": {
    8 "billing_address": {
    9 "country_code": "US"
    10 },
    11 "attributes": {
    12 "verification": {
    13 "paypal": {
    14 "method": "INSTANT_ACCOUNT_VERIFICATION"
    15 }
    16 }
    17 },
    18 "payment_context": {
    19 "standard_entry_class_code": "WEB"
    20 },
    21 "experience_context": {
    22 "locale": "en-US",
    23 "return_url": "https://example.com/return",
    24 "cancel_url": "https://example.com/cancel"
    25 }
    26 }
    27 }
    28 }
    29 }'

    Modify the code

    • Change ACCESS-TOKEN to your access token.
    • Specify the preferred language and set return_url and cancel_url. This is required to redirect the payer back to your site.

    Step result

    • A return status code of HTTP 200 OK.
    • PayPal generates and returns rel: payer-action HATEOAS link. This is the link to which you will need to redirect your customer to PayPal Instant Account Verification page.
    • Redirect the customer to the bank account verification flow using the HATEOAS link.
    • PayPal will redirect customer to the SUCCESS endpoint (RETURN URL) with the results of the verification. A SUCCESS will mean the bank account was verified successfully.
    • A FAIL will imply the customer was not able to complete the bank account verification. Since transaction cannot be processed on an unverified bank account, prompt the customer to provide a different payment instrument.
    • In case of verification error or customer cancellation, PayPal will redirect to the CANCEL URL. In case of retry-able errors, reinitiate the transaction from Confirm Payment Source onwards. For other situations, prompt the customer to provide a different payment instrument - transaction can only be processed on verified bank account.

    Step 2B: Accounts are externally verified

    • If you have bank accounts verified via external party and wish to skip PayPal's verification system, you may indicate the verification status using the verification.external.status field.
    • Providing a unique a unique merchant_customer_id is recommended.
    • Change the standard_entry_class_code. Options are WEB, CCD, TEL, and PPD.
      1curl -v -k -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN36475T/confirm-payment-source
      2 -H 'Content-Type: application/json'
      3 -H 'Authorization: Bearer ACCESS-TOKEN'
      4 -d '{
      5 "payment_source": {
      6 "bank": {
      7 "ach_debit": {
      8 "account_number": "ACCOUNT-NUMBER",
      9 "routing_number": "ROUTING-NUMBER",
      10 "account_holder_name": "ACCOUNT-HOLDER-NAME",
      11 "account_type": "ACCOUNT-TYPE",
      12 "ownership_type": "OWNERSHIP-TYPE",
      13 "billing_address": {
      14 "country_code": "US"
      15 },
      16 "attributes": {
      17 "verification": {
      18 "external": {
      19 "status": "VERIFIED"
      20 }
      21 }
      22 },
      23 "payment_context": {
      24 "standard_entry_class_code": "WEB"
      25 }
      26 }
      27 }
      28 }
      29 }'

      Modify the code

      After you copy the code in the sample request, modify the following:

      • Change Access-Token to your access token.
      • Change following placeholders with the customer bank account information.
        • ACCOUNT-NUMBER
        • ROUTING-NUMBER
        • ACCOUNT-HOLDER-NAME
        • ACCOUNT-TYPE- (CHECKING or SAVINGS)
        • OWNERSHIP-TYPE - (PERSONAL or BUSINESS)
      • For CCD transactions, always set "standard_entry_class_code": "CCD" and "ownership_type": "BUSINESS" in the body of ach_debit.

      Step result

      A successful request results:

      • A return status code of HTTP 200 OK.
      • Order status will be APPROVED.
      3

      Get order

      Confirmation is required by the payer on the finalization of the transaction before the order can be captured.

      1. Sample request
      2. Sample response
      1curl -v -X GET https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T
      2 -H 'Content-Type: application/json'
      3 -H 'Authorization: Bearer ACCESS-TOKEN'

      Authorization

      For all ACH transactions, you are required to collect an authorization from the customer indicating that you have their explicit permission to debit their bank account. To remain in compliance with NACHA regulations, we recommend you store the full text of the authorization with amount of transaction, bank details and timestamp of authorization. You may be required to provide proof of the authorization when requested by PayPal, customer’s bank or by NACHA.

      A reference authorization text is provided below. Include this text or a variation in your checkout flow, at or near the final "buy" (checkout, complete, submit etc.) button.

      Use Case 1: ONE TIME PURCHASE ("Single Entry")

      "I authorize [Merchant business name] to initiate a one-time ACH/electronic debit to my account as follows: Amount: [insert amount], Authorization Date: [insert date], Account holder: [insert full name], Bank: [insert bank name], [Checking / Savings] Account Number: [insert account number], Routing Number: [insert routing number]. I agree that ACH transactions I authorize comply with all applicable laws." [CTA: Agree and Continue]

      image

      4

      Capture an order

      Before you can capture an order using ACH direct debit, the status of the order must be APPROVED. The order status is set to APPROVED when the payer successfully completes the checkout flow.

      After the bank account is verified and the payer authorizes the direct debit, you can call capture order to capture the payer's funds.

      Copy the following code and modify it:

        1curl -v -X GET https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T/capture
        2 -H 'Content-Type: application/json'
        3 -H 'Authorization: Bearer ACCESS-TOKEN'
        4 -d '{}'

        Modify the code

        • Change Access-Token to your access token.

        Step result

        A successful result for a standard ACH direct debit returns the following:

        • If the transaction is not declined, the response is PAYMENT.CAPTURE.PENDING. This status changes in 5 calendar days to either PAYMENT.CAPTURE.COMPLETED or PAYMENT.CAPTURE.DECLINED.
        • If the payment is completed, the response is PAYMENT.CAPTURE.COMPLETED. This payment can be returned in certain situations, such as with an unauthorized return.
        • If the payment is declined, the response is PAYMENT.CAPTURE.DECLINED. A payment may be declined for incorrect routing or account numbers or for other reasons.

        Capture an order by passing order ID

        1. Sample request
        2. Sample response
        1curl -v -X GET https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T
        2 -H 'Content-Type: application/json'
        3 -H 'Authorization: Bearer ACCESS-TOKEN'

        Go Live

        Make ACH available to payers using your website or app.

        Test your live environment

        When testing a purchase in production, consider:

        • The business account receiving money can't also make the purchase.
        • If you create a personal account with the same information as the business account, those accounts might experience restrictions.

        How to test ACH payments in a live environment

        1. Open your test page with on a web browser.
        2. Select the ACH button to trigger the ACH payment experience.
        3. Proceed with the ACH bank verification.
        4. Continue to confirm the transaction.
        5. On the confirmation page on your merchant website, confirm the payment.
        6. Log in to your seller account and confirm that the money has moved into that account.

        Review daily reports

        Refer to the daily reports to reconcile all returns you received on that day. Then, you can work with any payer on the steps they should take to resubmit the payment. Use the following reports:

        Decline Analysis Report

        The Decline Analysis Report contains all returned/declined standard ACH debit transactions including the reason codes received from the ACH network.

        Financial Summary Report

        The Financial Summary Report contains the liability charges posted on your account as a result of returned ACH debit transactions. Instant ACH transactions that resulted in bank returns are also included in this daily report. The report includes the original transaction that was returned and what fees you incurred from returned transactions.

        Review reason codes

        If an ACH transaction is returned by your payer's bank, a reason code for the returned transaction is included. Depending on the reason code, the transaction can be corrected and re-submitted for processing.

        The table below provides return reason codes and explains what steps you can take if an ACH transaction was not processed and returned to you:

        Reason Code Description What it means What you should do
        R01 Insufficient Funds The bank account you submitted to PayPal for payment does not have sufficient balance to cover the amount on the transaction. Contact your payer immediately to avoid any disruption in the service or the delivery of your product, and let them know you were not able to charge their bank account as a result of insufficient funds. You can ask them to add funds to their bank account and have them go through the payment experience again, or present them an option to pay with a different bank account or a different payment method and submit a new transaction.
        R02 Account Closed The bank account you submitted for payment has been closed. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R03 No Account/Unable to Locate Account The bank account you submitted for payment is invalid. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R04 Invalid Account Number Structure The bank account you submitted for payment is invalid. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R05 Unauthorized Debit to Consumer Account Using Corporate SEC Code Payment has been submitted on a corporate account using a consumer SEC code. Correct the payment SEC code and resubmit.
        R06 Returned per ODFI’s Request Payment stopped as required by PayPal. Resubmit the transaction. If PayPal has stopped payment on your behalf, contact PayPal.
        R07 Authorization Revoked by Customer Payment has been marked as unauthorized by payer. Payment has been reversed by payer by revoking authorization. Contact payer to resolve the issue.
        R08 Payment Stopped Stop payment issued by payer on account for PayPal Payment has been stopped by payer. Contact payer to resolve the issue.
        R09 Uncollected Funds Collected funds are not sufficient for payment of the debit entry Contact the payer to inform them of insufficient funds. As per your procedures you may resubmit the transaction or request the payer to update payment method or payment account.
        R10 Customer Advises Unauthorized, Improper, Ineligible, or part of an Incomplete Transaction Payment has been marked as unauthorized by payer. Payment has been reversed by payer by revoking authorization. Contact payer to resolve the issue.
        R12 Account Sold to another DFI RDFI is unable to post entry destined for a bank account maintained at a branch sold to another financial institution. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R13 Invalid ACH Routing Number Financial institution does not receive commercial ACH entries. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R14 Representative Payee Deceased or Unable to Continue in that capacity The representative payee authorized to accept entries on behalf of a beneficiary is either deceased or unable to continue in that capacity. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R15 Beneficiary of Account Holder Deceased The beneficiary entitled to payments is deceased and/or the bank account holder other than a representative payee is deceased. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R16 Account Frozen/Entry Returned per OFAC Instruction Funds in bank account are unavailable due to action by RDFI or legal order. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R17 File Record Edit Criteria Certain payment fields rejected by RDFI processing (identified in return addenda) Correct the payment fields and resubmit.
        R20 Non Transaction Account The ACH entry is sent to a non-transaction account. Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.
        R24 Duplicate Entry RDFI has received a duplicate entry. Check if this transaction was a duplicate or has already completed, before resending the payment.
        R29 Corporate Customer Advises not authorized Payment has been marked as unauthorized by payer. Payment has been reversed by payer by revoking authorization. Contact payer to resolve the issue.
        R34 Limited Participation DFI RDFI participation has been limited by a federal or state supervisor Contact the payer to update payment method or payment account. Stop any recurring payments from this account. If the transaction you received this code on is a prenote, don't process any further transactions on this account.

        Appendix: Test accounts for bank verification

        Usecase Login Credential (Sandbox) Bank Name
        Single CHECKING Account pyplopenbankingubsb.site16441.1 site16441.1 DEMO BANK
        Multiple CHECKING/SAVINGS Account pyplopenbankingubsb.site16441.2 site16441.2 DEMO BANK
        One Checking and One CD pyplopenbankingubsb.site16441.5 site16441.5 DEMO BANK
        No CHECKING/SAVING Account pyplopenbankingub.site16441.4 site16441.4 DEMO BANK
        Multiple Holders pyplopenbankingubsb.site16441.3 site16441.3 DEMO BANK
        Business Account pyplopenbankingubsb.site16441.2 site16441.2 Account last 4: 7753
        Oauth Bank pyplopenbankingubsb.site19335.1 site19335.1 DEMO BANK - Dag Oauth Site
        ACCOUNT_LOCKED Username: error_407 Password: error_407
        INCORRECT_CREDENTIALS Username: error_402 Password: error_402
        INVALID_ADDL_INFO_PROVIDED Site: Dag Site Multilevel Username: agg.site16442.1 Password: site16442.1
        Note: Enter Security Token answer incorrectly
        ADDL_AUTHENTICATION_REQUIRED Username: error_518 Password: error_518
        CREDENTIALS_UPDATE_NEEDED Username: error_410 Password: error_410
        NEW_AUTHENTICATION_REQUIRED Username: error_506 Password: error_506
        SITE_UNAVAILABLE Username: error_409 Password: error_409
        SITE_BLOCKING_ERROR Username: error_426 Password: error_426
        USER_ACTION_NEEDED_AT_SITE Username: error_406 Password: error_406
        TECH_ERROR Username: error_403 Password: error_403