Link

Best Practices

Throttling - Rate Limiting

All api routes are throttled to 150 requests per minute per IP.

You are only allowed 10 failed transactions per minute.

Fattmerchant.js routes are different. When you call the .pay() or the .tokenize() method, Fattmerchant.js hits the Fattmerchant API with the defined Webpayments token. This resource is throttled to 10 requests per minute per IP.

Note if you need to process a higher number of requests, please reach out to us to have your IP whitelisted


Verification Checks

Address Verification (AVS)

AVS checks are used to verify that the address information provided matches the billing address on file with the card issuer. There are different levels and combinations of AVS:

  • Based on zip code
  • Based on the street address

Whether you use Fattmerchant.js or a direct POST to create a payment method and based on your preferred AVS configuration, you need to pass in the appropriate address fields: address_zip and/or address_1

If you wish to add AVS support to your live account or for more information, please reach out to your account manager.

NOTE: AVS checks can only be tested on a live account.


ACH Transactions

Using Fattmerchant, you can accept ACH payments similarly to how you accept credit card payments using Fattmerchant.js and the Omni API. However, it is important to understand that ACH follows a different payment flow once the transaction is made in Omni. ACH transactions may take up to 5 business days to recieve the ultimate status of success or failure of payment.

An ACH transaction will always show as successful ("success": true) as long as the transaction passes the initial checks in Omni. Successful ACH transactions will then batch each day at 8pm EST at which point they go into a settling state ("is_settling": true). During the next 5 business days the payment will take one of the two possible paths:

  1. The payment will succeed and make it into a settlement. When the payment succeeds, the settled_at date will populate with the DATETIME of settlement. When this happens, you can typically expect that the funds will be deposited in the merchant bank account within roughly 1-2 business days. (Although rare, if the funding instructions fail, it is possible that the funds would not be paid out on this timeline.)
  2. The ACH rejects, and the payment will fail, resulting in an associated void transaction. When an ACH rejects, the Transaction.child_transactions array will be populated with a void transaction(Transaction.child_transactions[0].type will be "void"). The Transaction.is_voided boolean will also be true and there will be no value in the Transaction.settled_at field.

ACH Rejections

ACH rejections can happen for many different reasons such as a frozen account or insufficient funds. When these rejections occur, you may want to display the rejection information to the customer so that they know if they need to reach out to their bank to resolve an issue, or if they made a user error when entering their account information. Remember, this Rejection may happen between 1-5 business days after the transaction occurred. Omni provides ACH rejection information in a transaction which was voided due to Rejection. When the Transaction.method is "bank" and the Transaction.child_transactions[0].type is "void", the Transaction.child_transactions[0].meta object will contain an achDescription and an achStatus field which you can use to directly display to your customer if you wish.

  • achStatus will indicate the status of the ACH transaction. (ex. “FAILED”)
  • achDescription will include both the NACHA reason code as well as the reason’s description as a single string. (ex. “ReasonCode: R03.ReasonDescription: No Account/Unale to Locate Account”)

Testing ACH

You can mimic a successful ACH transaction with the following routing and account number. Any other combination will trigger a fail.

Routing Number: 021000021 Account Number: 9876543210

Testing Deposit reporting

If you plan to implement deposit reporting in your software to understand when deposits are made and to connect them back to the initial transaction, you will use our Deposit Reporting API resource to pull this information from Omni. When you are in a sandbox account and testing this functionality, you must mock the settlement process for a payment in order to have data to work with. To generate mock data, you can utilize our Simulate Settlements feature, available in the API Keys App from within Omni. Clicking on Simulate Settlements here will look for any transactions that were made in the sandbox account and will simulate a settlement on those transactions creating the deposit reporting data.

NOTE: Using the Simulate Settlements feature does not fire the update_transaction_settled webhook event.

Risks of double-crediting when performing ACH refunds

If you initiate a refund to your customer for an ACH payment when the transaction has not yet settled, you run the risk that the initial transaction may not ever settle, in which case, you would have credited the customer for an amount they never paid to you, resulting in a situation of double-crediting. To eliminate this risk, it is recommended to disable refunds until the transaction has officially settled. Once settled, you may refund an ACH transaction using the Refund Transaction API resource with no issue.

ACH Specific Webhooks

create_transaction - This webhook event fires for both ACH and CC transactions when they are created. In the case where the transaction’s method is "bank", even if the transaction’s success flag is true, you may want to display these transactions differently, since they cannot be refunded or voided for risks of double-crediting, and because they still run the risk of failing at some point before funds are disbursed (See section on ACH Transactions above for more information).

update_transaction_settled - This webhook event fires at the point when an ACH transaction either settles, or fails. The response will include information on the entire transaction object as well as a boolean (is_transaction_settled) which you can use to easily determine whether the transaction ultimately succceeded or failed.

Go to the Webhooks API documentation to set up these webhooks.

Sample POST body response to your target url for update_transaction_settled event

{
    "transaction_id": "6f49149d-69a1-48e6-bec5-d63eb5816118",
    "is_transaction_settled" true,
    "settled_at": "202-07-10T04:00:00:00Z",
    "transaction": {
        "id": "6f49149d-69a1-48e6-bec5-d63eb5816118",
        "child_transactions": [],
        "is_voided": false
        ...
     }
}

Fattmerchant.js Validation

If the validate flag is passed into the tokenize or pay methods, FattJs will attempt to validate the details with the following rules:

  • method - required, must be ‘bank’ or ‘card’
  • firstname - required if customer_id is not passed into details, max of 50 characters
  • lastname - required if customer_id is not passed into details, max of 50 characters
  • phone - required if customer_id is not passed into details, must be at least 10 characters
  • email - not required, must be a valid email
  • address_1: required if customer_id is not passed into details, max of 255 characters
  • address_2: not required, max of 255 characters
  • address_city: required if customer_id is not passed into details, max of 255 characters
  • address_state: required if customer_id is not passed into details, max of 2 characters (e.g. FL)
  • card_exp: required if method === ‘card’,
  • bank_account: required if method === ‘bank’
  • bank_routing: required if method === ‘bank’
  • bank_type: required if method === ‘bank’, must be ‘checking’ or ‘savings’
  • bank_holder_type: required if method === ‘bank’, must be ‘personal’ or ‘business’
  • total: not required, must be a number
  • customer_id: not required, must be a string matching a valid customer_id which belongs to your merchant account. If supplied, a new customer will not be created or matched based on values. Instead, the supplied ID will be assigned this new payment method (and transaciton if using .pay())

Fattmerchant.js Important Notes

Trigger a Success/Failure

Do you want to trigger a success or failure in your Sandbox account? If so, please see the table of test cards and bank accounts in the payment methods section.

Throttling

Fattmerchant.js routes are different. When you call the .pay() or the .tokenize() method, Fattmerchant.js hits the Fattmerchant API with the defined Webpayments token. This resource is throttled to 10 requests per minute per IP.

Status Column

The .pay() returns an Invoice object with a status of either PAID or ATTEMPTED depending on whether the charge was successful. Please learn more about statuses in the Invoice section of our Documentation.

Automated Receipt

This method will automatically send a receipt to the email provided (which is the customer’s email). This receipt will also show whether the charge was a success or a fail.

Customer Matching

When you use .tokenize() OR .pay() the API will attempt to find matching customer information according to these groups of demographics:

  • customer_id
  • email
  • company, address_1, address_city
  • firstname, phone
  • firstname, lastname, address_1, address_zip
  • lastname, phone

A match is found when each field exists is passed and an exact match is found. For example: Bob Smith at 123 North Way 32801 would not match to Bobby Smith at 123 Noth. Way 32801 If a match is found based on the provided demographics, the existing customer will be linked to the new payment method and transaction and any additional demographics will not be stored.

For example: if a Match is found for Bob.Smith@test.com but you also passed data like Address Line 1 and the existing Bob Smith didn’t have an address, then the new address will not be saved.

If the matched customer has an email, that email address will receive the receipt.

to disable matching pass match_customer: false (as boolean false) with the rest of the fields when calling .pay() _or_.tokenize()`

Using an existing customer_id

You are welcome to create a customer first using POST customer and then use the resuling customer_id in your Fattmerchant.js integration.

Both .pay() and .tokenize() accept a customer_id. When this value is passed, the customer will not be created, but instead the existing customer with the specified id will be used for the new payment method (and invoice, payment if using .pay())

This also provides you with the ability to implement your own customer matching and then specify the exact id.

Use a Billing Address

The address fields available in Fattmerchant.js are stored on the customer and not sent to the payment gateway. There is no way to add a billing address with Fattmerchant.js alone. However, once you have the payment_method_id you can do a PUT payment-method call to add a billing address using your api key.

Please see the PUT payment-method for detailed information.

Billing addresses are sent along with the payment if supplied.

Test Payment Methods

When using a sandbox account on a test gateway, you may want to trigger a success or fail based on the card or bank number you pass in. Once you create a payment method with one of these card numbers or bank account numbers it will always trigger the success or a generic failure thereafter when used in a charge. These test payment methods can only be used for Card Not Present/ Keyed-in transactions. For Card Present testing, please reach out to support.fattmerchant.com to set up your account for testing devices with your merchant account.

NOTE: In an account with a live gateway - none of these numbers will work, all card and bank numbers will be treated as real.

Test Credit Cards

TYPE TRIGGER SUCCESS TRIGGER FAILURE
Visa 4111111111111111 4012888888881881
MasterCard 5555555555554444 5105105105105100
American Express 378282246310005 371449635398431
Discover 6011111111111117 6011000990139424

Test ACH/Bank

The following numbers will cause a charge to succeed. Any other combination of Routing and Account numbers will trigger a failure.

Routing Number: 021000021

Account Number: 9876543210