Sale / Auth transaction
Charge a card, authorize funds for later capture, verify a card, or issue a credit. The workhorse transaction endpoint.
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
amountis the final amount you want charged, inclusive of any surcharges, convenience fees, and taxes you have calculated.base_amountlets 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.
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.
| Field | Type | Required | Description |
|---|---|---|---|
type | string | required | One of sale, authorize, verification, credit |
amount | integer | required | Amount in cents. 1299 = $12.99. Should include any fees and taxes. |
currency | string | optional | ISO 4217 currency code. Defaults to USD. |
processor_id | string | conditional | Required if you have no default processor set. |
payment_method | object | required | Exactly 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.
| Field | Type | Description |
|---|---|---|
order_id | string | Up to 17 alphanumeric characters. Required for Level 3 processing. Populated automatically when paid through an invoice. |
po_number | string | Purchase order number, up to 17 alphanumeric characters. |
description | string | Free-text, up to 255 characters. Useful for internal notes. |
ip_address | string | End-user IPv4 or IPv6. Do not include port. |
vendor_id | string | Vendor 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.
| Field | Type | Description |
|---|---|---|
idempotency_key | string (UUID) | A client-generated UUID. Five-minute default TTL. |
idempotency_time | integer | TTL 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.
| Field | Type | Required | Description |
|---|---|---|---|
card.number | string | required | Card number, digits only. |
card.expiration_date | string | required | Format MM/YY. |
card.cvc | string | conditional | Required when your account has the CVV rule enabled. |
card.entry_type | string | optional | keyed or swiped. |
card.track_1 / track_2 | string | optional | Decrypted track data for swipe. |
card.encrypted_track_1 / encrypted_track_2 / ksn | string | optional | Encrypted track data plus the key serial number used to encrypt. |
card.cardholder_authentication | object | optional | 3DS data (eci, cavv, xid, cryptogram, version, ds_transaction_id, acs_transaction_id). If present, all values must be valid. |
emv.tlv_data | map | optional | EMV TLV packets, hex-encoded strings. |
emv.device_serial_number | string | optional | Device 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.
| Field | Required | Description |
|---|---|---|
customer.id | required | Vaulted customer ID. |
customer.payment_method_id | optional | Specific payment method on the customer; defaults to the customer's default. |
customer.payment_method_type | optional | Filter by type when the customer has multiple methods. |
customer.billing_address_id / shipping_address_id | optional | Use 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.
| Field | Required | Description |
|---|---|---|
token | required | Token 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.
| Field | Required | Description |
|---|---|---|
apple_pay_token.key_id | required | ID of your registered Apple Pay credential in moat. Not the Apple Merchant ID. |
apple_pay_token.temporary_token | conditional | Present only for the Wallet.js path. |
apple_pay_token.pkpaymenttoken | conditional | The full Apple payment token object from ApplePay.js or the Payment Request API. |
ACH
Bank account debit via Automated Clearing House.
| Field | Required | Description |
|---|---|---|
ach.routing_number | required | Routing number, 9 digits. |
ach.account_number | required | Account number. |
ach.sec_code | required | One of web, ccd, ppd, tel. |
ach.account_type | required | checking or savings. |
ach.check_number | conditional | Required when sec_code is tel. |
ach.funding_speed | optional | standard (default) or sameday, where supported. |
ach.accountholder_authentication.dl_state / dl_number | conditional | Driver'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.
| Field | Required | Description |
|---|---|---|
terminal.id | required | Registered terminal ID. |
terminal.print_receipt | required | no, customer, merchant, or both. |
terminal.signature_required | required | true requests signature capture on the device, if supported. |
terminal.expiration_date / cvc | optional | Optional values passed to the device. |
APM (alternative payment methods)
Alternative payment methods like Klarna, OXXO, Alipay, WeChat Pay, SEPA, and DragonPay.
| Field | Required | Description |
|---|---|---|
apm.type | required | APM type (see the supported list below). |
apm.merchant_redirect_url | required | Where to send the customer after the payment page completes. |
apm.locale | required | Payment page locale, e.g. en-US. |
apm.mobile_view | required | true renders a mobile-optimized payment page when supported. |
apm.national_id / consumer_ref | optional | Required by some APMs (see APM Requirements below). |
Supported APMs
| Type | Countries | Currencies |
|---|---|---|
alipay | CN | EUR, USD, GBP |
dragonpay | PH | PHP |
wechatpay | CN | EUR, USD |
oxxo | MX | USD, MXN |
klarna | AT, DK, FI, DE, NL, NO, SE, GB | EUR, DKK, GBP, NOK, SEK |
sepa | DE | EUR |
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
| Field | Description |
|---|---|
billing_address.first_name / last_name | Up to 50 characters each. |
billing_address.company | Up to 100 characters. |
billing_address.address_line_1 / address_line_2 | Up to 100 characters each. |
billing_address.city | Up to 50 characters. |
billing_address.state | State abbreviation. |
billing_address.postal_code | If a card is present, defaults to the postal code associated with the card. |
billing_address.country | Defaults to US. |
billing_address.email | Valid email format. |
billing_address.phone / fax | Digits 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.
| Field | Description |
|---|---|
line_items[].name | Up to 50 alpha characters. |
line_items[].description | Up to 50 alpha characters. |
line_items[].product_code | SKU, up to 50 alpha characters. |
line_items[].quantity | Decimal. |
line_items[].unit_price | Unit price in cents. |
line_items[].amount | Total amount for the line in cents. |
line_items[].tax_amount / discount_amount | Per-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_fieldsare custom field IDs. - Values are arrays of strings, even for single values.
- If your custom fields use a non-default group, include
group_nameon 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.
| Field | Max length |
|---|---|
descriptor.name | 38 |
descriptor.address | 38 |
descriptor.city | 21 |
descriptor.state | 2 |
descriptor.postal_code | 5 |
Customer Vault from a transaction
Save the payment method from a successful transaction directly into the vault, without a second API call.
| Field | Description |
|---|---|
create_vault_record | true creates a new customer record with this payment method after success. |
create_vault_record_for | Adds the payment method to an existing customer ID instead of creating a new one. |
Email receipts
| Field | Description |
|---|---|
email_receipt | true sends an email receipt. Requires email_address. |
email_address | Valid 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_idsummary_commodity_code(4 alphanumeric characters)ship_from_postal_code- Billing and shipping
postal_codes - Fully populated
line_items[]includingcommodity_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.
| Field | Values | Notes |
|---|---|---|
initiated_by | customer or merchant | Who kicked off this specific transaction. |
card_on_file_indicator | C or R | C = general storage, R = recurring. |
stored_credential_indicator | used or stored | Whether a stored credential was used or stored on this run. |
initial_transaction_id | string | Original transaction ID, if not using moat tokenization. |
billing_method | straight, initial_recurring, recurring | Tag for recurring-pattern reporting and downstream indicators. |
HSA / FSA
Health Savings Account and Flexible Spending Account splits.
| Field | Description |
|---|---|
iias_status | verified or exempt. Required for HSA/FSA. |
additional_amounts.hsa.total | Total HSA-eligible amount in cents. Required. |
additional_amounts.hsa.rx_amount / vision_amount / clinic_amount / dental_amount | Category-specific amounts in cents. |