eChecks
You can add bank accounts as payment methods in Spreedly to be used with a gateway’s eCheck service. We currently support eChecks at the following gateways:
- Adyen
- Authorize.Net
- BluePay
- BlueSnap
- Braintree
- BridgePay
- CardConnect
- CyberSource
- CyberSource REST
- Diamond Mind
- Vantiv Express (formerly Element)
- Forte
- Heartland Payment Systems
- iATS Payments
- Vantiv eCommerce (formerly Litle)
- NMI
- Orbital (Chase Paymentech)
- PayConex
- PayTrace
- Payeezy
- Payflow Pro
- Rapyd
- Sage Payment Solutions
- Stripe
- Stripe Payment Intents
- Spreedly Test
- TransFirst
- TransFirst Transaction Express
- TrustCommerce
- USA ePay
- Vanco
- Worldpay US
A custom transparent redirect form can be used like so:
<form accept-charset="UTF-8" action="https://core.spreedly.com/v1/payment_methods" method="POST">
<fieldset>
<input name="redirect_url" type="hidden" value="http://example.com/transparent_redirect_complete" />
<input name="environment_key" type="hidden" value="C7cRfNJGODKh4Iu5Ox3PToKjniY" />
<input name="utf8" type="hidden" value="✓" />
<input name="payment_method_type" type="hidden" value="bank_account" />
<label for="full_name">Name</label>
<input id="full_name" name="full_name" type="text" />
<label for="bank_name">Bank Name</label>
<input id="bank_name" name="bank_name" type="text" />
<label for="bank_routing_number">Bank Routing Number</label>
<input id="bank_routing_number" name="bank_routing_number" type="text" />
<label for="bank_account_number">Account Number</label>
<input id="bank_account_number" name="bank_account_number" type="text" />
<label for="bank_account_type">Account Type</label>
<select id="bank_account_type" name="bank_account_type">
<options value="checking" />
<options value="savings" />
</select>
<label for="bank_account_holder_type">Account Holder</label>
<select id="bank_account_holder_type" name="bank_account_holder_type">
<options value="personal" />
<options value="business" />
</select>
<button type='submit'>Submit Payment</button>
</fieldset>
</form>
http://example.com/transparent_redirect_complete?token=OpUmh75ttxO1TxEg7nPhEMeiqZ6
The only required fields for a bank account are full_name
(or
first_name
/last_name
), bank_routing_number
, and bank_account_number
. The
rest are optional at the Spreedly level, and whether you want to collect them
will depend on what your gateway requires.
Currently only US and Canadian bank accounts are supported. For accounts issued
by US banks, the bank_routing_number
must be a valid US ABA Number. For accounts issued
by Canadian banks, the bank_routing_number
should be the nine-digit electronic
routing number, beginning with a zero and followed by a valid financial
institution number.
Valid values for bank_account_type
are checking
and savings
, and valid
values for bank_account_holder_type
are personal
and business
.
A bank account looks like this when you pull it back out:
curl https://core.spreedly.com/v1/payment_methods/OpUmh75ttxO1TxEg7nPhEMeiqZ6.xml \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/xml'
<payment_method>
<token>VX0ackf05WGJwvjkl0epp1852CL</token>
<created_at type="dateTime">2017-07-27T17:51:37Z</created_at>
<updated_at type="dateTime">2017-07-27T17:51:37Z</updated_at>
<email nil="true"/>
<data nil="true"/>
<storage_state>cached</storage_state>
<test type="boolean">true</test>
<full_name>Bob Smith</full_name>
<bank_name>First Bank of Elbonia</bank_name>
<account_type>checking</account_type>
<account_holder_type>personal</account_holder_type>
<routing_number_display_digits>021</routing_number_display_digits>
<account_number_display_digits>3210</account_number_display_digits>
<first_name>Bob</first_name>
<last_name>Smith</last_name>
<address1 nil="true"/>
<address2 nil="true"/>
<city nil="true"/>
<state nil="true"/>
<zip nil="true"/>
<country nil="true"/>
<phone_number nil="true"/>
<company nil="true"/>
<payment_method_type>bank_account</payment_method_type>
<errors>
</errors>
<routing_number>021*</routing_number>
<account_number>*3210</account_number>
</payment_method>
env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.find_payment_method('OpUmh75ttxO1TxEg7nPhEMeiqZ6')
#<Spreedly::BankAccount:0x007fe33394da90
@token="RLKWLhDu8zWhjNfGkgNVqK2TDk8",
@created_at="2017-07-27T17:51:38Z",
@updated_at="2017-07-27T17:51:38Z",
@email="",
@storage_state="cached",
@data="",
@first_name="Bob",
@last_name="Smith",
@full_name="Bob Smith",
@bank_name="First Bank of Elbonia",
@account_type="checking",
@account_holder_type="personal",
@routing_number_display_digits="021",
@account_number_display_digits="3210",
@routing_number="021*",
@account_number="*3210",
@errors=[]>
Once you have a bank account payment method, you can run a purchase like so:
curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/xml' \
-d '<transaction>
<payment_method_token>VX0ackf05WGJwvjkl0epp1852CL</payment_method_token>
<amount>100</amount>
<currency_code>USD</currency_code>
</transaction>'
<transaction>
<on_test_gateway type="boolean">true</on_test_gateway>
<created_at type="dateTime">2017-07-27T17:53:07Z</created_at>
<updated_at type="dateTime">2017-07-27T17:53:07Z</updated_at>
<succeeded type="boolean">true</succeeded>
<state>succeeded</state>
<token>Bsj7WKWGvkADanTqndkDTZbYW76</token>
<transaction_type>Purchase</transaction_type>
<order_id nil="true"/>
<ip nil="true"/>
<description nil="true"/>
<email nil="true"/>
<merchant_name_descriptor nil="true"/>
<merchant_location_descriptor nil="true"/>
<gateway_specific_fields nil="true"/>
<gateway_specific_response_fields>
</gateway_specific_response_fields>
<gateway_transaction_id>45</gateway_transaction_id>
<gateway_latency_ms type="integer">0</gateway_latency_ms>
<amount type="integer">100</amount>
<currency_code>USD</currency_code>
<retain_on_success type="boolean">false</retain_on_success>
<payment_method_added type="boolean">false</payment_method_added>
<message key="messages.transaction_succeeded">Succeeded!</message>
<gateway_token>T11bJAANtTWnxl36GYjKWvbNK0g</gateway_token>
<shipping_address>
<name nil="true"/>
<address1 nil="true"/>
<address2 nil="true"/>
<city nil="true"/>
<state nil="true"/>
<zip nil="true"/>
<country nil="true"/>
<phone_number nil="true"/>
</shipping_address>
<response>
<success type="boolean">true</success>
<message>Successful purchase</message>
<avs_code nil="true"/>
<avs_message nil="true"/>
<cvv_code nil="true"/>
<cvv_message nil="true"/>
<pending type="boolean">false</pending>
<result_unknown type="boolean">false</result_unknown>
<error_code></error_code>
<error_detail nil="true"/>
<cancelled type="boolean">false</cancelled>
<fraud_review nil="true"/>
<created_at type="dateTime">2017-07-27T17:53:07Z</created_at>
<updated_at type="dateTime">2017-07-27T17:53:07Z</updated_at>
</response>
<api_urls>
</api_urls>
<payment_method>
<token>FUbGgOeOdo1mT7j7Tndmz6zfdRg</token>
<created_at type="dateTime">2017-07-27T17:53:06Z</created_at>
<updated_at type="dateTime">2017-07-27T17:53:06Z</updated_at>
<email nil="true"/>
<data nil="true"/>
<storage_state>cached</storage_state>
<test type="boolean">true</test>
<full_name>Bob Smith</full_name>
<bank_name>First Bank of Elbonia</bank_name>
<account_type>checking</account_type>
<account_holder_type>personal</account_holder_type>
<routing_number_display_digits>021</routing_number_display_digits>
<account_number_display_digits>3210</account_number_display_digits>
<first_name>Bob</first_name>
<last_name>Smith</last_name>
<address1 nil="true"/>
<address2 nil="true"/>
<city nil="true"/>
<state nil="true"/>
<zip nil="true"/>
<country nil="true"/>
<phone_number nil="true"/>
<company nil="true"/>
<payment_method_type>bank_account</payment_method_type>
<errors>
</errors>
<routing_number>021*</routing_number>
<account_number>*3210</account_number>
</payment_method>
</transaction>
env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.purchase_on_gateway("LlkjmEk0xNkcWrNixXa1fvNoTP4", "VX0ackf05WGJwvjkl0epp1852CL", 4432)
#<Spreedly::Purchase:0x007fe3328c20b8
@token="OPD8mGu7i3yh5Ol1AO12ADs3M90",
@created_at="2017-07-27T17:53:08Z",
@updated_at="2017-07-27T17:53:09Z",
@state="succeeded",
@message="Succeeded!",
@succeeded="true",
@order_id="",
@ip="",
@description="",
@gateway_token="T11bJAANtTWnxl36GYjKWvbNK0g",
@gateway_transaction_id="58",
@email="",
@merchant_name_descriptor="",
@merchant_location_descriptor="",
@on_test_gateway="true",
@currency_code="USD",
@amount="4432",
@response,=
#<Spreedly::Response:0x007fe33286b358
@success="true",
@pending="false",
@cancelled="false",
@fraud_review="",
@created_at="2017-07-27T17:53:09Z",
@updated_at="2017-07-27T17:53:09Z",
@message="Successful purchase",
@avs_code="",
@avs_message="",
@cvv_code="",
@cvv_message="",
@error_code="",
@error_detail="">,
@shipping_address,=
#<Spreedly::ShippingAddress:0x007fe3328099f0
@name="",
@address1="",
@address2="",
@city="",
@state="",
@zip="",
@country="",
@phone_number="">,
@gateway_specific_fields={},
@payment_method,=
#<Spreedly::BankAccount:0x007fe33209fca0
@token="V64F4zaCSgfbFkvsTt7ylnrGFkX",
@created_at="2017-07-27T17:53:08Z",
@updated_at="2017-07-27T17:53:08Z",
@email="",
@storage_state="cached",
@data="",
@first_name="Bob",
@last_name="Smith",
@full_name="Bob Smith",
@bank_name="First Bank of Elbonia",
@account_type="checking",
@account_holder_type="personal",
@routing_number_display_digits="021",
@account_number_display_digits="3210",
@routing_number="021*",
@account_number="*3210",
@errors=[]>>
The settlement process for echecks is different from credit card transaction settlements. The docs on the Authorize.net site can help to explain. Authorize.net notifies you via email if an eCheck transaction eventually fails to settle, whether it be for insufficient funds, chargebacks, etc.