Docs/API/Sale / Auth transaction

Sale / Auth transaction

Charge a card, authorize funds for later capture, verify a card, or issue a credit. The workhorse transaction endpoint.

POST /api/transaction
No default processor?

If you have not set a default processor on your account, you must include processor_id in the request body, or the transaction will fail.

Amount vs. base amount

  • amount is the final amount you want charged, inclusive of any surcharges, convenience fees, and taxes you have calculated.
  • base_amount lets moat calculate surcharge-style adjustments for you. Pass the pre-fee base and the system adds the surcharge at processing time using your configured fee program.
Set a longer HTTP timeout

Authorizations can occasionally take well over a minute to complete — in rare cases more than two. The default client timeout in most HTTP libraries (30–60 seconds) is too short. Set your client timeout to at least 3 minutes (180 seconds) so long-running authorizations can complete without the client closing the connection.

Basic fields

The minimum viable request has a type, an amount, and one payment_method.

FieldTypeRequiredDescription
typestringrequiredOne of sale, authorize, verification, credit
amountintegerrequiredAmount in cents. 1299 = $12.99. Should include any fees and taxes.
currencystringoptionalISO 4217 currency code. Defaults to USD.
processor_idstringconditionalRequired if you have no default processor set.
payment_methodobjectrequiredExactly one of: card, ach, customer, terminal, token, apm, apple_pay_token.
fetch("https://sandbox.fluidpay.com/api/transaction", {
  method: "POST",
  headers: {
    "Authorization": "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    type: "sale",
    amount: 1299,
    payment_method: {
      card: {
        number: "4111111111111111",
        expiration_date: "12/30",
        cvc: "123"
      }
    }
  })
})

Details & metadata

Optional fields that travel with the transaction and show up in reporting.

FieldTypeDescription
order_idstringUp to 17 alphanumeric characters. Required for Level 3 processing. Populated automatically when paid through an invoice.
po_numberstringPurchase order number, up to 17 alphanumeric characters.
descriptionstringFree-text, up to 255 characters. Useful for internal notes.
ip_addressstringEnd-user IPv4 or IPv6. Do not include port.
vendor_idstringVendor ID passed through to certain processors. Only set this if support tells you to.

Idempotency

Optionally include an idempotency key to make retries safe. Replaying the same key within its TTL returns the result of the original attempt rather than charging a second time.

FieldTypeDescription
idempotency_keystring (UUID)A client-generated UUID. Five-minute default TTL.
idempotency_timeintegerTTL in seconds. Default 300.
{
  "type": "sale",
  "amount": 1299,
  "idempotency_key": "7df4d862-1a3d-44c4-b3df-536aadf307b0",
  "payment_method": { "card": { ... } }
}

Payment methods

Exactly one of the following keys must appear under payment_method.

Card

Debit or credit card with keyed or swiped entry.

FieldTypeRequiredDescription
card.numberstringrequiredCard number, digits only.
card.expiration_datestringrequiredFormat MM/YY.
card.cvcstringconditionalRequired when your account has the CVV rule enabled.
card.entry_typestringoptionalkeyed or swiped.
card.track_1 / track_2stringoptionalDecrypted track data for swipe.
card.encrypted_track_1 / encrypted_track_2 / ksnstringoptionalEncrypted track data plus the key serial number used to encrypt.
card.cardholder_authenticationobjectoptional3DS data (eci, cavv, xid, cryptogram, version, ds_transaction_id, acs_transaction_id). If present, all values must be valid.
emv.tlv_datamapoptionalEMV TLV packets, hex-encoded strings.
emv.device_serial_numberstringoptionalDevice serial from the reader.
{
  "type": "sale",
  "amount": 1299,
  "payment_method": {
    "card": {
      "number": "4111111111111111",
      "expiration_date": "12/30",
      "cvc": "123"
    }
  }
}

Card with 3DS data

{
  "type": "sale",
  "amount": 1299,
  "payment_method": {
    "card": {
      "number": "4111111111111111",
      "expiration_date": "12/30",
      "cvc": "123",
      "cardholder_authentication": {
        "eci": "05",
        "cavv": "AAABBIcJImlkEh0gHUiCUgAAAAA=",
        "version": "2"
      }
    }
  }
}

Customer (vaulted)

Charge a payment method stored in the Customer Vault.

FieldRequiredDescription
customer.idrequiredVaulted customer ID.
customer.payment_method_idoptionalSpecific payment method on the customer; defaults to the customer's default.
customer.payment_method_typeoptionalFilter by type when the customer has multiple methods.
customer.billing_address_id / shipping_address_idoptionalUse a specific saved address instead of the customer's default.
{
  "type": "sale",
  "amount": 1299,
  "payment_method": {
    "customer": {
      "id": "cust_abc123",
      "payment_method_id": "pm_xyz789"
    }
  }
}

Token

Charge a tokenized payment method produced by Tokenizer.

FieldRequiredDescription
tokenrequiredToken value returned from Tokenizer.
{
  "type": "sale",
  "amount": 1299,
  "payment_method": { "token": "tok_V1StGXR8_Z5jdHi6B-myT" }
}

Apple Pay

Two entry points: native ApplePay.js / Payment Request API, or the simpler Wallet.js temporary token path.

FieldRequiredDescription
apple_pay_token.key_idrequiredID of your registered Apple Pay credential in moat. Not the Apple Merchant ID.
apple_pay_token.temporary_tokenconditionalPresent only for the Wallet.js path.
apple_pay_token.pkpaymenttokenconditionalThe full Apple payment token object from ApplePay.js or the Payment Request API.

ACH

Bank account debit via Automated Clearing House.

FieldRequiredDescription
ach.routing_numberrequiredRouting number, 9 digits.
ach.account_numberrequiredAccount number.
ach.sec_coderequiredOne of web, ccd, ppd, tel.
ach.account_typerequiredchecking or savings.
ach.check_numberconditionalRequired when sec_code is tel.
ach.funding_speedoptionalstandard (default) or sameday, where supported.
ach.accountholder_authentication.dl_state / dl_numberconditionalDriver's license state + number when the processor requires it.
{
  "type": "sale",
  "amount": 1299,
  "payment_method": {
    "ach": {
      "routing_number": "110000000",
      "account_number": "000123456789",
      "sec_code": "web",
      "account_type": "checking"
    }
  }
}

Terminal

Run a transaction against a physical card-present terminal you have registered on the account.

FieldRequiredDescription
terminal.idrequiredRegistered terminal ID.
terminal.print_receiptrequiredno, customer, merchant, or both.
terminal.signature_requiredrequiredtrue requests signature capture on the device, if supported.
terminal.expiration_date / cvcoptionalOptional values passed to the device.

APM (alternative payment methods)

Alternative payment methods like Klarna, OXXO, Alipay, WeChat Pay, SEPA, and DragonPay.

FieldRequiredDescription
apm.typerequiredAPM type (see the supported list below).
apm.merchant_redirect_urlrequiredWhere to send the customer after the payment page completes.
apm.localerequiredPayment page locale, e.g. en-US.
apm.mobile_viewrequiredtrue renders a mobile-optimized payment page when supported.
apm.national_id / consumer_refoptionalRequired by some APMs (see APM Requirements below).

Supported APMs

TypeCountriesCurrencies
alipayCNEUR, USD, GBP
dragonpayPHPHP
wechatpayCNEUR, USD
oxxoMXUSD, MXN
klarnaAT, DK, FI, DE, NL, NO, SE, GBEUR, DKK, GBP, NOK, SEK
sepaDEEUR

Amounts

See the dedicated Amounts page for the full breakdown of amount vs. base_amount, tax, shipping, discount, tip, and payment_adjustment handling.

Addresses

Billing addresses drive AVS (Address Verification System) and fraud scoring. Shipping addresses are required for Level 3 data.

Billing

FieldDescription
billing_address.first_name / last_nameUp to 50 characters each.
billing_address.companyUp to 100 characters.
billing_address.address_line_1 / address_line_2Up to 100 characters each.
billing_address.cityUp to 50 characters.
billing_address.stateState abbreviation.
billing_address.postal_codeIf a card is present, defaults to the postal code associated with the card.
billing_address.countryDefaults to US.
billing_address.emailValid email format.
billing_address.phone / faxDigits only.

Shipping

Same shape as billing, under shipping_address. Required for Level 3 data transactions; both billing and shipping postal codes must be present.

Line items

Itemize the products or services on the transaction. Improves receipts, reporting, and — when fully populated — Level 3 interchange rates.

FieldDescription
line_items[].nameUp to 50 alpha characters.
line_items[].descriptionUp to 50 alpha characters.
line_items[].product_codeSKU, up to 50 alpha characters.
line_items[].quantityDecimal.
line_items[].unit_priceUnit price in cents.
line_items[].amountTotal amount for the line in cents.
line_items[].tax_amount / discount_amountPer-line values in cents.

Custom fields

Attach merchant-defined data to the transaction. You must first create the custom fields via the Custom Fields API.

  • Keys in custom_fields are custom field IDs.
  • Values are arrays of strings, even for single values.
  • If your custom fields use a non-default group, include group_name on the transaction.
{
  "type": "sale",
  "amount": 1299,
  "payment_method": { "card": { ... } },
  "custom_fields": {
    "cf_order_source": ["mobile_app"],
    "cf_flags": ["gift", "priority"]
  }
}

Descriptor

Override the merchant descriptor that shows up on cardholder statements. Reduces chargebacks by making the charge recognizable. Support and formatting rules vary by processor.

FieldMax length
descriptor.name38
descriptor.address38
descriptor.city21
descriptor.state2
descriptor.postal_code5

Customer Vault from a transaction

Save the payment method from a successful transaction directly into the vault, without a second API call.

FieldDescription
create_vault_recordtrue creates a new customer record with this payment method after success.
create_vault_record_forAdds the payment method to an existing customer ID instead of creating a new one.

Email receipts

FieldDescription
email_receipttrue sends an email receipt. Requires email_address.
email_addressValid email format.

Partial payments

Set allow_partial_payment: true to accept partial authorizations where the processor returns less than the requested amount. See also the Response page for how to inspect amount_authorized versus amount.

Split transaction

If your account has Split Transactions enabled, passing split_transaction_amount (in cents) runs a second, independent transaction on the same card against a different processor. Common use: application fees. The response contains a split_transaction_response with its own transaction ID for refunds or voids.

Level 3 data

Level 3 unlocks lower interchange rates for B2B and government cards. It requires, at minimum:

  • order_id
  • summary_commodity_code (4 alphanumeric characters)
  • ship_from_postal_code
  • Billing and shipping postal_codes
  • Fully populated line_items[] including commodity_code, unit_of_measure, and the usual quantity / price / tax fields

CIT / MIT (card on file)

Customer-initiated and merchant-initiated transaction indicators. Required for subsequent charges against stored credentials.

FieldValuesNotes
initiated_bycustomer or merchantWho kicked off this specific transaction.
card_on_file_indicatorC or RC = general storage, R = recurring.
stored_credential_indicatorused or storedWhether a stored credential was used or stored on this run.
initial_transaction_idstringOriginal transaction ID, if not using moat tokenization.
billing_methodstraight, initial_recurring, recurringTag for recurring-pattern reporting and downstream indicators.

HSA / FSA

Health Savings Account and Flexible Spending Account splits.

FieldDescription
iias_statusverified or exempt. Required for HSA/FSA.
additional_amounts.hsa.totalTotal HSA-eligible amount in cents. Required.
additional_amounts.hsa.rx_amount / vision_amount / clinic_amount / dental_amountCategory-specific amounts in cents.