# Authorize.net (/docs/workflows/integrations/authorize-net)

> For the complete documentation index, see [llms.txt](https://docs.tandemcx.ai/llms.txt). Any page on this site can be fetched as Markdown by appending `.md` to its URL.

The Authorize.net integration lets a workflow take a card payment during a call. The caller keys
their card in on the phone keypad, Tandem charges it through your Authorize.net account, and the
workflow gets back the result. The card number, expiry, and security code never reach the
workflow, its variables, or the transcript. For call recordings, see [Taking a
payment](#taking-a-payment).

The **Capture Payment Information** node does the work. An AI agent cannot take a payment itself:
hand the call to a workflow that contains the node.

## Setup

### 1. Get your API credentials

In your Authorize.net account, open **API Credentials & Keys** and copy the **API Login ID**.
Generate a **Transaction Key** on the same page. For testing, use a sandbox account from the
[Authorize.net developer center](https://developer.authorize.net/).

### 2. Connect it in Tandem

On the **Integrations** page, click **Add Integration** and pick **Authorize.net**. Fill in:

| Field           | What to enter                                                         |
| --------------- | --------------------------------------------------------------------- |
| Name            | A name you will recognize in the node's **Payment Integration** list. |
| Description     | Optional.                                                             |
| Environment     | **Sandbox** for a sandbox account, **Production** for real charges.   |
| API Login ID    | From step 1.                                                          |
| Transaction Key | From step 1.                                                          |

Tandem does not test the credentials when you save them. The first charge does: wrong or inactive
credentials send the node to its `fallback` exit with Authorize.net's reason in the
`_message` variable (see [Troubleshooting](#troubleshooting)).

An org can connect more than one Authorize.net account, for example a sandbox and a production
one. To replace saved credentials, open the integration and enter the API Login ID and the
Transaction Key together.

## Taking a payment

Add a **Capture Payment Information** node and pick the integration under **Payment Integration**.
The node's other fields:

- **Transaction Type**: `authCapture` charges the card now. `authOnly` authorizes it, and you
  capture it later in Authorize.net. `tokenize` stores the card as an Authorize.net customer
  profile and charges nothing.
- **Amount**: a decimal with up to two places and no currency symbol, such as `10.00`. It can be
  a `$(variable)`.
- **Invoice Reference**: optional, up to 20 characters. Sent as the Authorize.net invoice number.
- **Description**: optional, up to 255 characters.
- **Capture CVV** and **Capture Billing ZIP**: ask the caller for the security code and the
  billing ZIP. Each needs its own prompt.
- **Invalid Entry Retries**: how many times to ask again after an entry that is empty or
  incomplete, from 0 to 5. The default is 2.
- **Card Number Prompt**, **Expiry Prompt**, **CVV Prompt**, **Billing ZIP Prompt**: the
  recorded prompts the caller hears.
- **Result Variable Prefix**: the prefix for the result variables below.

The caller keys each field and can press `#` to finish it early. A field also ends after six
seconds with no key pressed. The expiry is four digits, month then year (`MMYY`).

An amount, invoice reference, or description that breaks these rules takes the `fallback` exit
before the caller is asked for anything.

If the call is being recorded, the recording is paused for the card entry and resumed after it.
When the pause can't be confirmed, Tandem tries to stop and delete the call's recording, and the
capture goes ahead. If neither the pause nor the delete can be confirmed, the capture still goes
ahead and the card entry may be in the recording.

## Exits

- **default**: the charge was approved. For `tokenize`, the card was stored.
- **declined**: the card issuer or Authorize.net declined the card.
- **invalidInput**: the caller did not key a complete entry (a card number of 12 to 19 digits, a
  four-digit expiry) after the retries ran out. No charge was attempted.
- **fallback**: anything else, including an Authorize.net error, wrong credentials, a node field
  that can't be charged, or a charge whose outcome is unknown. Wire this exit to tell the caller
  what happened. Left unwired, the workflow ends there and the caller hears nothing more.

## Result variables

With a prefix of `pay`, the node writes these after every capture:

| Variable                | Value                                                                      |
| ----------------------- | -------------------------------------------------------------------------- |
| `pay_result`            | `approved`, `declined`, `invalidInput`, or `error`.                        |
| `pay_last4`             | The last four digits of the card.                                          |
| `pay_brand`             | `Visa`, `Mastercard`, `American Express`, `Discover`, or `Unknown`.        |
| `pay_transId`           | The Authorize.net transaction ID.                                          |
| `pay_authCode`          | The authorization code.                                                    |
| `pay_avsResult`         | The address verification result code.                                      |
| `pay_message`           | Authorize.net's reason for the result, or Tandem's when the charge failed. |
| `pay_outcomeUnknown`    | `true` when the card may have been charged despite an `error` result.      |
| `pay_customerProfileId` | The stored customer profile, for `tokenize`. Empty otherwise.              |
| `pay_paymentProfileId`  | The stored payment profile, for `tokenize`. Empty otherwise.               |

### When the outcome is unknown

`pay_outcomeUnknown` is `true` when Tandem could not confirm whether Authorize.net charged the
card: the request timed out, the connection dropped, Authorize.net answered with a server error
or a response Tandem could not read, or it held the transaction for review, which charges the
card if you approve it. The node takes `fallback`.

<Callout type="warn">
    Do not charge the card again from `fallback` when `pay_outcomeUnknown` is `true`. The first
    charge may have gone through. Check the transaction in Authorize.net first.
</Callout>

## Troubleshooting

| What you see                                                                                 | What it means                                                                                      |
| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `fallback`, `_message` is `User authentication failed. The account or API user is inactive.` | Authorize.net rejected the API Login ID. Reactivate the account or enter new credentials.          |
| `fallback`, `_message` is `The payment integration is not connected.`                        | The integration the node points at was deleted. Pick another under **Payment Integration**.        |
| `fallback` before the caller hears a prompt                                                  | A node field breaks the rules under [Taking a payment](#taking-a-payment), or a prompt is missing. |
| `declined` on a sandbox test card                                                            | Authorize.net's sandbox declines some amounts and cards on purpose. Check its testing guide.       |
