From 68ae7e69f1ccc54c7a4097db3e8dd2913439a31e Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 17:21:55 +0200
Subject: [PATCH 1/9] feat(docs): add AVS for MOTO feature page and TSYS
callout
Add a new "Features" section with a full AVS-for-MOTO guide (Android
SDK and Cloud API, TSYS only), plus a short "AVS" subsection under
Functionalities > TSYS > MOTO that links to it. Also updates the
acquirer-page generator template so future page regenerations produce
the same subsection.
---
data/acquirers.yaml | 8 ++
docs/acquirers/tsys.mdx | 10 ++
docs/features/avs-for-moto.mdx | 209 +++++++++++++++++++++++++++++
docusaurus.config.js | 1 +
scripts/generate-acquirer-pages.js | 12 ++
sidebars.js | 11 ++
src/data/acquirerDetails.js | 4 +
src/partials/functions/moto.mdx | 2 +
static/llms.txt | 2 +-
9 files changed, 258 insertions(+), 1 deletion(-)
create mode 100644 docs/features/avs-for-moto.mdx
diff --git a/data/acquirers.yaml b/data/acquirers.yaml
index 83b1175..53a8417 100644
--- a/data/acquirers.yaml
+++ b/data/acquirers.yaml
@@ -19,6 +19,14 @@ acquirers:
Batch auto-closes ~11pm EST (host-capture). Partial reversal available for
TSYS US and Canada — uses the MasterCard flag in ISO 8583.
capabilities:
+ avs-for-moto:
+ # Draft feature — TSYS only, Android SDK (PAX) and Cloud API only for now.
+ # Not modeled as a Functionalities capability row on purpose: it has no
+ # entry in CapabilitySummary's CAPABILITY_LABELS, so it stays invisible
+ # in the acquirer table. Consumed only by generate-acquirer-pages.js to
+ # inject the callout in moto.mdx. Full detail lives in docs/features/avs-for-moto.mdx.
+ cloud-api: public
+ android-pax: public
sale:
cloud-api: public
android-pax: public
diff --git a/docs/acquirers/tsys.mdx b/docs/acquirers/tsys.mdx
index 53bf8ce..bda053a 100644
--- a/docs/acquirers/tsys.mdx
+++ b/docs/acquirers/tsys.mdx
@@ -947,6 +947,16 @@ Use for call centres, phone order systems, or recurring billing where the cardho
Batch auto-closes ~11pm EST (host-capture). Partial reversal available for TSYS US and Canada — uses the MasterCard flag in ISO 8583.
:::
+### AVS
+
+TSYS supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on Android SDK and Cloud API only, for now.
+
+Turning it on for a merchant requires the `avsForMoto` Console parameter (read-only from the ISV side, default `false`) and `motoEnabled = true`.
+
+:::info
+Setup, code samples for both integration paths, and known limitations (there's no address-match result in the response today) are covered in [AVS for MOTO](/features/avs-for-moto).
+:::
+
### Code
diff --git a/docs/features/avs-for-moto.mdx b/docs/features/avs-for-moto.mdx
new file mode 100644
index 0000000..7758500
--- /dev/null
+++ b/docs/features/avs-for-moto.mdx
@@ -0,0 +1,209 @@
+---
+id: avs-for-moto
+title: "AVS for MOTO"
+sidebar_label: "AVS for MOTO"
+description: "Attach the cardholder's billing address to a MOTO transaction so the acquirer can use it during authorization."
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# AVS for MOTO
+
+Attach the cardholder's billing address to a MOTO Sale, Pre-Authorization, or Refund, so the acquirer can use it during authorization.
+
+:::info Availability
+Available via **Android SDK** and **Cloud API**. For now, only on **TSYS**.
+:::
+
+## Overview
+
+MOTO transactions carry more fraud risk than card-present ones — there's no chip, no PIN, no physical card to inspect. Address Verification Service (AVS) is the acquirer's way of checking a piece of the cardholder's billing information against what the issuer has on file for that card, alongside the card number and CVV. It's one of the standard risk signals issuers and acquirers use when deciding whether to approve a MOTO transaction, on top of the usual authorization checks.
+
+This feature adds a `Billing` object — a postal code and, optionally, a street address — to a MOTO Sale, Pre-Authorization, or Refund. Handpoint doesn't validate the address or run any lookup: you (or the cardholder, via the on-device prompt) supply the data, and the gateway forwards it to the acquirer as part of the authorization request. What the acquirer and issuer do with it, and whether it affects the approve/decline decision, happens entirely on their side — the SDK and API don't surface that back to you today.
+
+:::caution No match result today
+Sending billing data doesn't produce a result you can branch on — there's no address-match field in the response yet. See [What comes back](#what-comes-back) before building any logic against it.
+:::
+
+AVS only applies to MOTO — Sale, Pre-Authorization, and Refund. It doesn't apply to card-present transactions, and MOTO must already be enabled for the merchant (see [Prerequisites](#prerequisites)).
+
+## Prerequisites
+
+- Handpoint Android SDK (hapi-android) **4.14.0 or later** for `Billing`, `zipCode`, and `address` on MOTO.
+- A more recent SDK release for the on-device prompt opt-in (`enableAvsFields` on `MoToOptions`) — this shipped recently; pin to the latest release rather than 4.14.0 if you need it.
+- MOTO enabled for the merchant (`motoEnabled = true`), regardless of who supplies the billing data.
+- Cloud API integrations target `POST /transactions` with `operation=moToSale`, `moToRefund`, or `moToPreAuthorization`.
+
+## Configuration
+
+AVS availability is driven by a Console parameter.
+
+| Key | Type | Access | Description |
+|---|---|---|---|
+| `avsForMoto` | boolean | read-only | "AVS for MOTO" in the Console parameter catalog. Default `false`. Requires `motoEnabled = true`. This is the Console-side name only — the native SDK reads the same setting under a different key, `"AVS"` (see [Code](#code)). |
+
+:::note
+Read-only from the ISV side — the Console UI doesn't support changing it yourself, so treat the value as configured by Handpoint rather than something your integration sets. Read it to adapt your own UI (for example, hide billing fields when AVS isn't enabled), but don't build a settings screen around it. It doesn't control the on-device prompt — that's `enableAvsFields`, set per transaction.
+:::
+
+## Handling cardholder data
+
+:::note
+The billing address is personal data — don't store it in clear text or write it to application logs (mask or truncate if you display it). The postal code isn't subject to the same restriction and can be logged. Apply your own retention policy and don't keep it longer than necessary.
+:::
+
+## Collecting the billing address
+
+Two ways to get `zipCode` / `address`, mutually exclusive on the same `MoToOptions`:
+
+| If you... | Do this |
+|---|---|
+| Have your own billing screen | Collect `zipCode` / `address` yourself and pass them via `Billing`. Don't set `enableAvsFields` — it's ignored once `billing` is already set. |
+| Don't want to build one | Set `enableAvsFields = true` and leave `billing` unset. The native card-entry screen asks for `zipCode` / `address` before sending the transaction. |
+
+This applies to Sale and Pre-Authorization only — Refund never shows the on-device prompt, so set `billing` programmatically if you want it on a refund.
+
+## Code
+
+
+
+
+Build the `Billing` object:
+
+```kotlin
+val billing = Billing(
+ zipCode = customerZipCode, // e.g. "10001" — required
+ address = customerAddress // e.g. "123 Main St" — optional
+)
+```
+
+Leaving `billing` unset on `MoToOptions` is safe — it just means no billing data is attached to this transaction.
+
+Attach it to the operation you're calling:
+
+```kotlin
+// Sale
+val options = MoToOptions().apply { this.billing = billing }
+hapi.motoSale(amount, currency, options)
+
+// Pre-Authorization
+val options = MoToOptions().apply { this.billing = billing }
+hapi.motoPreauthorization(amount, currency, options)
+
+// Refund
+val options = MoToOptions().apply { this.billing = billing }
+hapi.motoRefund(amount, currency, originalTransactionId, options)
+```
+
+Or, to have the terminal ask for it instead of collecting it yourself:
+
+```kotlin
+val options = MoToOptions().apply {
+ enableAvsFields = true // ignored if billing is already set above
+}
+hapi.motoSale(amount, currency, options)
+```
+
+:::note
+The on-device prompt appears only when `enableAvsFields` is `true` **and** `billing` is unset on the same `MoToOptions` — it doesn't depend on the `avsForMoto` / `"AVS"` Console parameter. If you set `billing` yourself, your values are used as-is and the prompt never appears.
+:::
+
+Optionally read the Console flag for your own UI logic (this doesn't control the prompt):
+
+```kotlin
+val avsEnabled = try {
+ configurationManager[configurationManager.getBooleanKey("AVS")]
+} catch (e: ConfigurationNotFoundException) {
+ false
+}
+```
+
+If you read it, keep it in sync with remote Console changes:
+
+```kotlin
+override fun newConfiguration(newValues: List>) {
+ if (newValues.any { it.key.name == "AVS" }) {
+ avsEnabled = configurationManager[configurationManager.getBooleanKey("AVS")]
+ }
+}
+```
+
+
+
+
+Attach a `billing` object to the transaction payload. The same shape applies to `moToSale`, `moToRefund`, and `moToPreAuthorization`:
+
+```json
+POST https://cloud.handpoint.io/transactions
+{
+ "operation": "moToSale",
+ "serial_number": "2740013262",
+ "terminal_type": "PAXA920MAX",
+ "amount": 322,
+ "currency": "USD",
+ "billing": {
+ "zipCode": "10001",
+ "address": "123 Main St"
+ }
+}
+```
+
+`zipCode` is the same field name on both the native SDK and the Cloud API payload.
+
+The request also accepts a top-level `enableAvsFields` boolean, mirroring the native SDK:
+
+```json
+POST https://cloud.handpoint.io/transactions
+{
+ "operation": "moToSale",
+ "serial_number": "2740013262",
+ "terminal_type": "PAXA920MAX",
+ "amount": 322,
+ "currency": "USD",
+ "enableAvsFields": true
+}
+```
+
+:::note
+`enableAvsFields` triggers an on-device dialog on the native SDK — there's no device screen to show it on in a pure Cloud API integration, so its effect here isn't defined. Don't depend on it outside the native SDK flow.
+:::
+
+
+
+
+## What comes back
+
+`TransactionResult` doesn't expose an address-match result — sending billing data doesn't add a field to branch on. The approve/decline outcome arrives the same way it does for any other MOTO transaction, on both the native SDK and Cloud API.
+
+```kotlin
+// Inside your HapiEventHandler.transactionResultReady callback
+override fun transactionResultReady(result: TransactionResult, device: Device) {
+ // result reflects the usual approve/decline outcome.
+ // there is no address-match field to read here.
+}
+```
+
+Don't build decision logic against a match result — it doesn't exist in the response today.
+
+## Edge cases
+
+| Scenario | Behaviour |
+|---|---|
+| `billing` is null / omitted | Transaction proceeds normally, no billing data sent. |
+| `zipCode` omitted, `address` supplied | Not a supported combination — `zipCode` is required whenever you construct a `Billing` object. |
+| `address` omitted, `zipCode` supplied | Valid — `address` is optional. |
+| `billing` supplied, AVS not enabled for the merchant | No special handling — the SDK forwards whatever billing you set regardless of this Console parameter (verified in `MoToRequestFactory`: billing is sent whenever it's present, with no check against `avsForMoto`). The parameter only matters if you choose to read it for your own UI logic — see the Android SDK sample under [Code](#code). |
+| MOTO Refund with no billing set | Transaction proceeds without billing data. MOTO Refund has no on-device prompt under any circumstance, regardless of `enableAvsFields` — collect and set `billing` yourself if you need it on a refund. |
+| `enableAvsFields = true` but `billing` already set (native SDK) | The on-device prompt is suppressed — your billing values are used as-is. |
+
+## What to persist after a transaction
+
+Store the following locally. Don't persist the raw billing address in clear text.
+
+| Field to store | Source | Notes |
+|---|---|---|
+| `originalTransactionId` | `TransactionResult.transactionId` / API transaction id | Needed to link any later void or refund. |
+| `billingSent` | Whether you set billing on this transaction | Your own local flag — useful for reconciliation, since no result comes back today. |
+| `billingZipCode` (optional) | Your local variable at transaction time | Store only what your reconciliation process needs. |
+| `billingAddress` | Not stored in clear text | Mask, truncate, or omit per your data retention policy. |
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 4dfdc3d..2d7051c 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -47,6 +47,7 @@ const config = {
{ type: 'custom-GlobalFilters', position: 'left' },
{ type: 'doc', docId: 'get-started/index', label: 'Get Started', position: 'left' },
{ type: 'docSidebar', sidebarId: 'acquirersSidebar', label: 'Functionalities', position: 'left' },
+ { type: 'docSidebar', sidebarId: 'featuresSidebar', label: 'Features', position: 'left' },
{ type: 'docSidebar', sidebarId: 'referenceSidebar', label: 'Reference', position: 'left' },
{ type: 'docSidebar', sidebarId: 'releaseNotesSidebar', label: 'Release Notes', position: 'left' },
{ type: 'custom-VersionToggle', position: 'right' },
diff --git a/scripts/generate-acquirer-pages.js b/scripts/generate-acquirer-pages.js
index a0e012f..d9e381c 100644
--- a/scripts/generate-acquirer-pages.js
+++ b/scripts/generate-acquirer-pages.js
@@ -114,6 +114,18 @@ function buildPage(slug, a) {
? `:::note ${a.name}\n${a.notes.trim()}\n:::\n`
: '';
content = content.replace('{/* ACQUIRER_NOTE_INJECTION_POINT */}', note);
+
+ if (partialName === 'moto') {
+ const avsCaps = caps['avs-for-moto'];
+ let avsNote = '';
+ if (avsCaps && isVisible(avsCaps)) {
+ const supportedPaths = PATHS.filter(p => avsCaps[p] === 'public' || avsCaps[p] === 'coming-soon');
+ const pathLabels = supportedPaths.map(p => PATH_LABELS[p]).join(' and ');
+ avsNote = `### AVS\n\n${a.name} supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on ${pathLabels} only, for now.\n\nTurning it on for a merchant requires the \`avsForMoto\` Console parameter (read-only from the ISV side, default \`false\`) and \`motoEnabled = true\`.\n\n:::info\nSetup, code samples for both integration paths, and known limitations (there's no address-match result in the response today) are covered in [AVS for MOTO](/features/avs-for-moto).\n:::\n`;
+ }
+ content = content.replace('{/* AVS_FOR_MOTO_INJECTION_POINT */}', avsNote);
+ }
+
sections.push(content);
}
}
diff --git a/sidebars.js b/sidebars.js
index e4b36fd..ffb29fb 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -50,6 +50,17 @@ const sidebars = {
},
],
+ featuresSidebar: [
+ {
+ type: 'category',
+ label: 'Features',
+ collapsible: false,
+ items: [
+ 'features/avs-for-moto',
+ ],
+ },
+ ],
+
referenceSidebar: [
{
type: 'category',
diff --git a/src/data/acquirerDetails.js b/src/data/acquirerDetails.js
index f0a2e9c..7d179a5 100644
--- a/src/data/acquirerDetails.js
+++ b/src/data/acquirerDetails.js
@@ -15,6 +15,10 @@ export const ACQUIRER_DETAILS = [
"Discover"
],
"capabilities": {
+ "avs-for-moto": {
+ "cloud-api": "public",
+ "android-pax": "public"
+ },
"sale": {
"cloud-api": "public",
"android-pax": "public",
diff --git a/src/partials/functions/moto.mdx b/src/partials/functions/moto.mdx
index fef9ac2..6927a86 100644
--- a/src/partials/functions/moto.mdx
+++ b/src/partials/functions/moto.mdx
@@ -27,6 +27,8 @@ Use for call centres, phone order systems, or recurring billing where the cardho
{/* ACQUIRER_NOTE_INJECTION_POINT */}
+{/* AVS_FOR_MOTO_INJECTION_POINT */}
+
### Code
diff --git a/static/llms.txt b/static/llms.txt
index 2a020c2..d2a88e9 100644
--- a/static/llms.txt
+++ b/static/llms.txt
@@ -3,7 +3,7 @@
# Generated: 2026-06-12T06:05:24.079Z
## Acquirers
-TSYS | geography: US, Canada | sale, refund, reversal, partial-reversal, tip-adjustment, pre-auth, moto, tokenization, batching, pre-auth-capture-reversal | cards: VISA, MC, Discover | url: /acquirers/tsys
+TSYS | geography: US, Canada | avs-for-moto, sale, refund, reversal, partial-reversal, tip-adjustment, pre-auth, moto, tokenization, batching, pre-auth-capture-reversal | cards: VISA, MC, Discover | url: /acquirers/tsys
PAYSAFE + Interac | geography: Canada | sale, refund, reversal, tip-adjustment, pre-auth, moto, tokenization, batching, void | cards: VISA, MC, Discover, Interac | interac: true | url: /acquirers/tsys-tns
TNS (Interac) | geography: Canada | sale, void | cards: Interac | interac: true | url: /acquirers/tns
PAYSAFE | geography: US | sale, refund, reversal | cards: VISA, MC, AMEX, Discover, Interac | interac: true | url: /acquirers/paysafe-tsys
From 1367f0fbf3e6436641c830cba8bcd0d4fa804522 Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 17:47:11 +0200
Subject: [PATCH 2/9] fix(docs): correct AVS-for-MOTO domain, amount type, and
terminal model
Cloud API examples pointed at cloud.handpoint.io instead of .com, sent
amount as a JSON number instead of the string format used everywhere
else in the repo, and used a fabricated terminal model (PAXA920MAX).
Also flags the Android SDK code samples as unverified against the real
hapi-android source.
---
docs/features/avs-for-moto.mdx | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/docs/features/avs-for-moto.mdx b/docs/features/avs-for-moto.mdx
index 7758500..2fe0bf2 100644
--- a/docs/features/avs-for-moto.mdx
+++ b/docs/features/avs-for-moto.mdx
@@ -66,6 +66,10 @@ This applies to Sale and Pre-Authorization only — Refund never shows the on-de
## Code
+:::caution Pending SDK verification
+The Android SDK samples below (`Billing`, `enableAvsFields`, `MoToOptions.billing`) are transcribed from the AVS integration guide draft and haven't been cross-checked against the `hapi-android` source. Every other MOTO sample in this repo only shows `hapi.motoSale(BigInteger, Currency)` — `motoPreauthorization` and `motoRefund` as separate methods, and a `billing` field on `MoToOptions`, have no precedent elsewhere in this codebase. Confirm the real method names, parameter types, and `MoToOptions` fields against the `hapi-android` source before an integrator relies on this section.
+:::
+
@@ -135,12 +139,12 @@ override fun newConfiguration(newValues: List>) {
Attach a `billing` object to the transaction payload. The same shape applies to `moToSale`, `moToRefund`, and `moToPreAuthorization`:
```json
-POST https://cloud.handpoint.io/transactions
+POST https://cloud.handpoint.com/transactions
{
"operation": "moToSale",
"serial_number": "2740013262",
- "terminal_type": "PAXA920MAX",
- "amount": 322,
+ "terminal_type": "PAXA920",
+ "amount": "322",
"currency": "USD",
"billing": {
"zipCode": "10001",
@@ -154,12 +158,12 @@ POST https://cloud.handpoint.io/transactions
The request also accepts a top-level `enableAvsFields` boolean, mirroring the native SDK:
```json
-POST https://cloud.handpoint.io/transactions
+POST https://cloud.handpoint.com/transactions
{
"operation": "moToSale",
"serial_number": "2740013262",
- "terminal_type": "PAXA920MAX",
- "amount": 322,
+ "terminal_type": "PAXA920",
+ "amount": "322",
"currency": "USD",
"enableAvsFields": true
}
From eee2209182bc1f5088d22e344288c8f1bfb3bb13 Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 17:57:53 +0200
Subject: [PATCH 3/9] docs(avs-moto): trim known-limitations callout in TSYS
summary
---
docs/acquirers/tsys.mdx | 2 +-
scripts/generate-acquirer-pages.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/acquirers/tsys.mdx b/docs/acquirers/tsys.mdx
index bda053a..5fa2a04 100644
--- a/docs/acquirers/tsys.mdx
+++ b/docs/acquirers/tsys.mdx
@@ -954,7 +954,7 @@ TSYS supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorizati
Turning it on for a merchant requires the `avsForMoto` Console parameter (read-only from the ISV side, default `false`) and `motoEnabled = true`.
:::info
-Setup, code samples for both integration paths, and known limitations (there's no address-match result in the response today) are covered in [AVS for MOTO](/features/avs-for-moto).
+Setup, code samples for both integration paths, and known limitations are covered in [AVS for MOTO](/features/avs-for-moto).
:::
diff --git a/scripts/generate-acquirer-pages.js b/scripts/generate-acquirer-pages.js
index d9e381c..889885e 100644
--- a/scripts/generate-acquirer-pages.js
+++ b/scripts/generate-acquirer-pages.js
@@ -121,7 +121,7 @@ function buildPage(slug, a) {
if (avsCaps && isVisible(avsCaps)) {
const supportedPaths = PATHS.filter(p => avsCaps[p] === 'public' || avsCaps[p] === 'coming-soon');
const pathLabels = supportedPaths.map(p => PATH_LABELS[p]).join(' and ');
- avsNote = `### AVS\n\n${a.name} supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on ${pathLabels} only, for now.\n\nTurning it on for a merchant requires the \`avsForMoto\` Console parameter (read-only from the ISV side, default \`false\`) and \`motoEnabled = true\`.\n\n:::info\nSetup, code samples for both integration paths, and known limitations (there's no address-match result in the response today) are covered in [AVS for MOTO](/features/avs-for-moto).\n:::\n`;
+ avsNote = `### AVS\n\n${a.name} supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on ${pathLabels} only, for now.\n\nTurning it on for a merchant requires the \`avsForMoto\` Console parameter (read-only from the ISV side, default \`false\`) and \`motoEnabled = true\`.\n\n:::info\nSetup, code samples for both integration paths, and known limitations are covered in [AVS for MOTO](/features/avs-for-moto).\n:::\n`;
}
content = content.replace('{/* AVS_FOR_MOTO_INJECTION_POINT */}', avsNote);
}
From 057c91e9f1866a0ffcfa0b59b844c8408ad16d4f Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 18:00:38 +0200
Subject: [PATCH 4/9] docs(avs-moto): spell out Address Verification Service
(AVS) heading
---
docs/acquirers/tsys.mdx | 2 +-
scripts/generate-acquirer-pages.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/acquirers/tsys.mdx b/docs/acquirers/tsys.mdx
index 5fa2a04..3df8307 100644
--- a/docs/acquirers/tsys.mdx
+++ b/docs/acquirers/tsys.mdx
@@ -947,7 +947,7 @@ Use for call centres, phone order systems, or recurring billing where the cardho
Batch auto-closes ~11pm EST (host-capture). Partial reversal available for TSYS US and Canada — uses the MasterCard flag in ISO 8583.
:::
-### AVS
+### Address Verification Service (AVS)
TSYS supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on Android SDK and Cloud API only, for now.
diff --git a/scripts/generate-acquirer-pages.js b/scripts/generate-acquirer-pages.js
index 889885e..6f18ed2 100644
--- a/scripts/generate-acquirer-pages.js
+++ b/scripts/generate-acquirer-pages.js
@@ -121,7 +121,7 @@ function buildPage(slug, a) {
if (avsCaps && isVisible(avsCaps)) {
const supportedPaths = PATHS.filter(p => avsCaps[p] === 'public' || avsCaps[p] === 'coming-soon');
const pathLabels = supportedPaths.map(p => PATH_LABELS[p]).join(' and ');
- avsNote = `### AVS\n\n${a.name} supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on ${pathLabels} only, for now.\n\nTurning it on for a merchant requires the \`avsForMoto\` Console parameter (read-only from the ISV side, default \`false\`) and \`motoEnabled = true\`.\n\n:::info\nSetup, code samples for both integration paths, and known limitations are covered in [AVS for MOTO](/features/avs-for-moto).\n:::\n`;
+ avsNote = `### Address Verification Service (AVS)\n\n${a.name} supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on ${pathLabels} only, for now.\n\nTurning it on for a merchant requires the \`avsForMoto\` Console parameter (read-only from the ISV side, default \`false\`) and \`motoEnabled = true\`.\n\n:::info\nSetup, code samples for both integration paths, and known limitations are covered in [AVS for MOTO](/features/avs-for-moto).\n:::\n`;
}
content = content.replace('{/* AVS_FOR_MOTO_INJECTION_POINT */}', avsNote);
}
From 58614043b822c12f78eb8dfa23f8c968e717c2c8 Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 18:08:53 +0200
Subject: [PATCH 5/9] docs(avs-moto): update Android SDK version requirement to
7.1014.0
---
docs/features/avs-for-moto.mdx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/features/avs-for-moto.mdx b/docs/features/avs-for-moto.mdx
index 2fe0bf2..9a8fbc0 100644
--- a/docs/features/avs-for-moto.mdx
+++ b/docs/features/avs-for-moto.mdx
@@ -30,8 +30,8 @@ AVS only applies to MOTO — Sale, Pre-Authorization, and Refund. It doesn't app
## Prerequisites
-- Handpoint Android SDK (hapi-android) **4.14.0 or later** for `Billing`, `zipCode`, and `address` on MOTO.
-- A more recent SDK release for the on-device prompt opt-in (`enableAvsFields` on `MoToOptions`) — this shipped recently; pin to the latest release rather than 4.14.0 if you need it.
+- Handpoint Android SDK (hapi-android) **7.1014.0 or later** for `Billing`, `zipCode`, and `address` on MOTO.
+- A more recent SDK release for the on-device prompt opt-in (`enableAvsFields` on `MoToOptions`) — this shipped recently; pin to the latest release rather than 7.1014.0 if you need it.
- MOTO enabled for the merchant (`motoEnabled = true`), regardless of who supplies the billing data.
- Cloud API integrations target `POST /transactions` with `operation=moToSale`, `moToRefund`, or `moToPreAuthorization`.
From 9aba0c056598998828f0132ad7f40dd7dbb8b932 Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 18:21:21 +0200
Subject: [PATCH 6/9] =?UTF-8?q?docs(avs-moto):=20address=20review=20commen?=
=?UTF-8?q?ts=20=E2=80=94=20remove=20Console=20framing,=20fix=20AVS=20resu?=
=?UTF-8?q?lt=20claim,=20move=20code=20to=20acquirer=20page?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Removed all references to a live Console UI for avsForMoto — it's not
a live product yet; reframed as an internal flag Handpoint sets per
merchant.
- Corrected "no match result" claim: the issuer/acquirer response does
include an AVS result. Exact field name/shape is unconfirmed and
flagged as pending in both the Overview and What Comes Back sections.
- Moved the Android SDK and Cloud API code samples out of the Features
page and into the MOTO Code tabs on the TSYS acquirer page, next to
the existing MOTO on-terminal/back-office samples. The Features page
now just links to them.
Refs: PR review comments from flozanofdez
---
docs/acquirers/tsys.mdx | 53 ++++++++++-
docs/features/avs-for-moto.mdx | 146 ++++-------------------------
scripts/generate-acquirer-pages.js | 2 +-
3 files changed, 70 insertions(+), 131 deletions(-)
diff --git a/docs/acquirers/tsys.mdx b/docs/acquirers/tsys.mdx
index 3df8307..846735a 100644
--- a/docs/acquirers/tsys.mdx
+++ b/docs/acquirers/tsys.mdx
@@ -951,7 +951,7 @@ Batch auto-closes ~11pm EST (host-capture). Partial reversal available for TSYS
TSYS supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on Android SDK and Cloud API only, for now.
-Turning it on for a merchant requires the `avsForMoto` Console parameter (read-only from the ISV side, default `false`) and `motoEnabled = true`.
+Turning it on for a merchant requires `avsForMoto` (an internal flag Handpoint sets per merchant, default `false`) and `motoEnabled = true`.
:::info
Setup, code samples for both integration paths, and known limitations are covered in [AVS for MOTO](/features/avs-for-moto).
@@ -997,6 +997,33 @@ Content-Type: application/json
For back-office MOTO, `amount` is in major currency units (decimal string). `transactionReference` is UUID v4 and used for idempotency.
+**AVS (optional)** — attach a `billing` object to a MOTO on terminal request (TSYS only):
+
+```http
+POST https://cloud.handpoint.com/transactions
+ApiKeyCloud: YOUR_MERCHANT_API_KEY
+Content-Type: application/json
+
+{
+ "operation": "moToSale",
+ "amount": "1000",
+ "currency": "USD",
+ "terminal_type": "PAXA920",
+ "serial_number": "082104578",
+ "transactionReference": "2bfde1fc-23b1-4c67-93d9-1d4a557f4d4f",
+ "billing": {
+ "zipCode": "10001",
+ "address": "123 Main St"
+ }
+}
+```
+
+`zipCode` is required whenever you include `billing`; `address` is optional. See [AVS for MOTO](/features/avs-for-moto) for enablement, the on-device prompt alternative (`enableAvsFields`), edge cases, and what to persist.
+
+:::caution Pending SDK verification
+Whether this same shape applies to MOTO back-office, `moToRefund`, or `moToPreAuthorization` hasn't been confirmed — those operations have no precedent for a `billing` field anywhere in this repo.
+:::
+
@@ -1015,6 +1042,30 @@ options.cardToken = "YOUR_STORED_CARD_TOKEN"
hapi.motoSale(BigInteger("1000"), Currency.USD, options)
```
+**AVS (optional)** — attach a `Billing` object on MOTO on terminal (TSYS only):
+
+```kotlin
+val billing = Billing(
+ zipCode = customerZipCode, // e.g. "10001" — required
+ address = customerAddress // e.g. "123 Main St" — optional
+)
+val options = MoToOptions().apply { this.billing = billing }
+hapi.motoSale(BigInteger("1000"), Currency.USD, options)
+```
+
+Or let the terminal ask for it instead of collecting it yourself:
+
+```kotlin
+val options = MoToOptions().apply { enableAvsFields = true }
+hapi.motoSale(BigInteger("1000"), Currency.USD, options)
+```
+
+See [AVS for MOTO](/features/avs-for-moto) for enablement, edge cases, and what to persist.
+
+:::caution Pending SDK verification
+This uses `hapi.motoSale(BigInteger, Currency, MoToOptions)` with a `billing`/`enableAvsFields` field on `MoToOptions` that has no other precedent in this repo. Confirm against the real `hapi-android` source before relying on it.
+:::
+
diff --git a/docs/features/avs-for-moto.mdx b/docs/features/avs-for-moto.mdx
index 9a8fbc0..e80f1b2 100644
--- a/docs/features/avs-for-moto.mdx
+++ b/docs/features/avs-for-moto.mdx
@@ -5,9 +5,6 @@ sidebar_label: "AVS for MOTO"
description: "Attach the cardholder's billing address to a MOTO transaction so the acquirer can use it during authorization."
---
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-
# AVS for MOTO
Attach the cardholder's billing address to a MOTO Sale, Pre-Authorization, or Refund, so the acquirer can use it during authorization.
@@ -20,10 +17,10 @@ Available via **Android SDK** and **Cloud API**. For now, only on **TSYS**.
MOTO transactions carry more fraud risk than card-present ones — there's no chip, no PIN, no physical card to inspect. Address Verification Service (AVS) is the acquirer's way of checking a piece of the cardholder's billing information against what the issuer has on file for that card, alongside the card number and CVV. It's one of the standard risk signals issuers and acquirers use when deciding whether to approve a MOTO transaction, on top of the usual authorization checks.
-This feature adds a `Billing` object — a postal code and, optionally, a street address — to a MOTO Sale, Pre-Authorization, or Refund. Handpoint doesn't validate the address or run any lookup: you (or the cardholder, via the on-device prompt) supply the data, and the gateway forwards it to the acquirer as part of the authorization request. What the acquirer and issuer do with it, and whether it affects the approve/decline decision, happens entirely on their side — the SDK and API don't surface that back to you today.
+This feature adds a `Billing` object — a postal code and, optionally, a street address — to a MOTO Sale, Pre-Authorization, or Refund. Handpoint doesn't validate the address or run any lookup: you (or the cardholder, via the on-device prompt) supply the data, and the gateway forwards it to the acquirer as part of the authorization request. The issuer/acquirer checks it and returns an AVS result as part of the transaction response — see [What comes back](#what-comes-back).
-:::caution No match result today
-Sending billing data doesn't produce a result you can branch on — there's no address-match field in the response yet. See [What comes back](#what-comes-back) before building any logic against it.
+:::caution Response field pending confirmation
+The AVS result is included in the issuer/acquirer response, but the exact field name and possible values in the SDK/API response haven't been confirmed yet. This page will be updated once confirmed — don't build decision logic against a specific field/value until then.
:::
AVS only applies to MOTO — Sale, Pre-Authorization, and Refund. It doesn't apply to card-present transactions, and MOTO must already be enabled for the merchant (see [Prerequisites](#prerequisites)).
@@ -37,14 +34,14 @@ AVS only applies to MOTO — Sale, Pre-Authorization, and Refund. It doesn't app
## Configuration
-AVS availability is driven by a Console parameter.
+AVS for MOTO is enabled per merchant on the backend by Handpoint — there's no self-service toggle for it today.
-| Key | Type | Access | Description |
-|---|---|---|---|
-| `avsForMoto` | boolean | read-only | "AVS for MOTO" in the Console parameter catalog. Default `false`. Requires `motoEnabled = true`. This is the Console-side name only — the native SDK reads the same setting under a different key, `"AVS"` (see [Code](#code)). |
+| Key | Type | Description |
+|---|---|---|
+| `avsForMoto` | boolean | Internal flag Handpoint sets per merchant. Default `false`. Requires `motoEnabled = true`. The native SDK reads the same setting under a different key, `"AVS"` (see [Code](#code)). |
:::note
-Read-only from the ISV side — the Console UI doesn't support changing it yourself, so treat the value as configured by Handpoint rather than something your integration sets. Read it to adapt your own UI (for example, hide billing fields when AVS isn't enabled), but don't build a settings screen around it. It doesn't control the on-device prompt — that's `enableAvsFields`, set per transaction.
+You can't set this yourself — it's configured by Handpoint on the backend. Read it (via the SDK key `"AVS"`) to adapt your own UI, for example hiding billing fields when AVS isn't enabled for the merchant. It doesn't control the on-device prompt — that's `enableAvsFields`, set per transaction.
:::
## Handling cardholder data
@@ -66,129 +63,20 @@ This applies to Sale and Pre-Authorization only — Refund never shows the on-de
## Code
-:::caution Pending SDK verification
-The Android SDK samples below (`Billing`, `enableAvsFields`, `MoToOptions.billing`) are transcribed from the AVS integration guide draft and haven't been cross-checked against the `hapi-android` source. Every other MOTO sample in this repo only shows `hapi.motoSale(BigInteger, Currency)` — `motoPreauthorization` and `motoRefund` as separate methods, and a `billing` field on `MoToOptions`, have no precedent elsewhere in this codebase. Confirm the real method names, parameter types, and `MoToOptions` fields against the `hapi-android` source before an integrator relies on this section.
-:::
-
-
-
-
-Build the `Billing` object:
-
-```kotlin
-val billing = Billing(
- zipCode = customerZipCode, // e.g. "10001" — required
- address = customerAddress // e.g. "123 Main St" — optional
-)
-```
-
-Leaving `billing` unset on `MoToOptions` is safe — it just means no billing data is attached to this transaction.
-
-Attach it to the operation you're calling:
-
-```kotlin
-// Sale
-val options = MoToOptions().apply { this.billing = billing }
-hapi.motoSale(amount, currency, options)
-
-// Pre-Authorization
-val options = MoToOptions().apply { this.billing = billing }
-hapi.motoPreauthorization(amount, currency, options)
+Code samples live with the rest of the MOTO implementation for each integration path, not here:
-// Refund
-val options = MoToOptions().apply { this.billing = billing }
-hapi.motoRefund(amount, currency, originalTransactionId, options)
-```
+- **Android SDK** — see [MOTO on the TSYS page](/acquirers/tsys#moto-mail-order--telephone-order), Android (PAX) tab, for how to attach `Billing` and use `enableAvsFields`.
+- **Cloud API** — see the same [MOTO section](/acquirers/tsys#moto-mail-order--telephone-order), Cloud API tab, for the `billing` payload shape.
-Or, to have the terminal ask for it instead of collecting it yourself:
-
-```kotlin
-val options = MoToOptions().apply {
- enableAvsFields = true // ignored if billing is already set above
-}
-hapi.motoSale(amount, currency, options)
-```
-
-:::note
-The on-device prompt appears only when `enableAvsFields` is `true` **and** `billing` is unset on the same `MoToOptions` — it doesn't depend on the `avsForMoto` / `"AVS"` Console parameter. If you set `billing` yourself, your values are used as-is and the prompt never appears.
-:::
-
-Optionally read the Console flag for your own UI logic (this doesn't control the prompt):
-
-```kotlin
-val avsEnabled = try {
- configurationManager[configurationManager.getBooleanKey("AVS")]
-} catch (e: ConfigurationNotFoundException) {
- false
-}
-```
-
-If you read it, keep it in sync with remote Console changes:
-
-```kotlin
-override fun newConfiguration(newValues: List>) {
- if (newValues.any { it.key.name == "AVS" }) {
- avsEnabled = configurationManager[configurationManager.getBooleanKey("AVS")]
- }
-}
-```
-
-
-
-
-Attach a `billing` object to the transaction payload. The same shape applies to `moToSale`, `moToRefund`, and `moToPreAuthorization`:
-
-```json
-POST https://cloud.handpoint.com/transactions
-{
- "operation": "moToSale",
- "serial_number": "2740013262",
- "terminal_type": "PAXA920",
- "amount": "322",
- "currency": "USD",
- "billing": {
- "zipCode": "10001",
- "address": "123 Main St"
- }
-}
-```
-
-`zipCode` is the same field name on both the native SDK and the Cloud API payload.
-
-The request also accepts a top-level `enableAvsFields` boolean, mirroring the native SDK:
-
-```json
-POST https://cloud.handpoint.com/transactions
-{
- "operation": "moToSale",
- "serial_number": "2740013262",
- "terminal_type": "PAXA920",
- "amount": "322",
- "currency": "USD",
- "enableAvsFields": true
-}
-```
-
-:::note
-`enableAvsFields` triggers an on-device dialog on the native SDK — there's no device screen to show it on in a pure Cloud API integration, so its effect here isn't defined. Don't depend on it outside the native SDK flow.
+:::caution Pending SDK verification
+Those samples are transcribed from the AVS integration guide draft and haven't been cross-checked against the `hapi-android` source. The only other MOTO sample in this repo shows `hapi.motoSale(BigInteger, Currency)` for Sale only — `motoPreauthorization` and `motoRefund` as separate methods, and a `billing` field on `MoToOptions`, have no precedent elsewhere in this codebase. Confirm the real method names, parameter types, and `MoToOptions` fields against the `hapi-android` source before an integrator relies on them.
:::
-
-
-
## What comes back
-`TransactionResult` doesn't expose an address-match result — sending billing data doesn't add a field to branch on. The approve/decline outcome arrives the same way it does for any other MOTO transaction, on both the native SDK and Cloud API.
-
-```kotlin
-// Inside your HapiEventHandler.transactionResultReady callback
-override fun transactionResultReady(result: TransactionResult, device: Device) {
- // result reflects the usual approve/decline outcome.
- // there is no address-match field to read here.
-}
-```
+The issuer/acquirer response for a MOTO transaction with billing data attached includes an AVS result, alongside the usual approve/decline outcome. The exact field name and possible values in `TransactionResult` and the REST response are being confirmed — this section will be updated with the real field and a code sample once that's settled.
-Don't build decision logic against a match result — it doesn't exist in the response today.
+Until then, don't build decision logic against a specific field or value.
## Edge cases
@@ -197,7 +85,7 @@ Don't build decision logic against a match result — it doesn't exist in the re
| `billing` is null / omitted | Transaction proceeds normally, no billing data sent. |
| `zipCode` omitted, `address` supplied | Not a supported combination — `zipCode` is required whenever you construct a `Billing` object. |
| `address` omitted, `zipCode` supplied | Valid — `address` is optional. |
-| `billing` supplied, AVS not enabled for the merchant | No special handling — the SDK forwards whatever billing you set regardless of this Console parameter (verified in `MoToRequestFactory`: billing is sent whenever it's present, with no check against `avsForMoto`). The parameter only matters if you choose to read it for your own UI logic — see the Android SDK sample under [Code](#code). |
+| `billing` supplied, AVS not enabled for the merchant | No special handling — the SDK forwards whatever billing you set regardless of this flag (verified in `MoToRequestFactory`: billing is sent whenever it's present, with no check against `avsForMoto`). The flag only matters if you choose to read it for your own UI logic — see [Code](#code). |
| MOTO Refund with no billing set | Transaction proceeds without billing data. MOTO Refund has no on-device prompt under any circumstance, regardless of `enableAvsFields` — collect and set `billing` yourself if you need it on a refund. |
| `enableAvsFields = true` but `billing` already set (native SDK) | The on-device prompt is suppressed — your billing values are used as-is. |
@@ -208,6 +96,6 @@ Store the following locally. Don't persist the raw billing address in clear text
| Field to store | Source | Notes |
|---|---|---|
| `originalTransactionId` | `TransactionResult.transactionId` / API transaction id | Needed to link any later void or refund. |
-| `billingSent` | Whether you set billing on this transaction | Your own local flag — useful for reconciliation, since no result comes back today. |
+| `billingSent` | Whether you set billing on this transaction | Your own local flag — useful for reconciliation alongside the AVS result field, once its exact shape is confirmed. |
| `billingZipCode` (optional) | Your local variable at transaction time | Store only what your reconciliation process needs. |
| `billingAddress` | Not stored in clear text | Mask, truncate, or omit per your data retention policy. |
diff --git a/scripts/generate-acquirer-pages.js b/scripts/generate-acquirer-pages.js
index 6f18ed2..d754aa0 100644
--- a/scripts/generate-acquirer-pages.js
+++ b/scripts/generate-acquirer-pages.js
@@ -121,7 +121,7 @@ function buildPage(slug, a) {
if (avsCaps && isVisible(avsCaps)) {
const supportedPaths = PATHS.filter(p => avsCaps[p] === 'public' || avsCaps[p] === 'coming-soon');
const pathLabels = supportedPaths.map(p => PATH_LABELS[p]).join(' and ');
- avsNote = `### Address Verification Service (AVS)\n\n${a.name} supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on ${pathLabels} only, for now.\n\nTurning it on for a merchant requires the \`avsForMoto\` Console parameter (read-only from the ISV side, default \`false\`) and \`motoEnabled = true\`.\n\n:::info\nSetup, code samples for both integration paths, and known limitations are covered in [AVS for MOTO](/features/avs-for-moto).\n:::\n`;
+ avsNote = `### Address Verification Service (AVS)\n\n${a.name} supports optional Address Verification (AVS) for MOTO Sale, Pre-Authorization, and Refund — on ${pathLabels} only, for now.\n\nTurning it on for a merchant requires \`avsForMoto\` (an internal flag Handpoint sets per merchant, default \`false\`) and \`motoEnabled = true\`.\n\n:::info\nSetup, code samples for both integration paths, and known limitations are covered in [AVS for MOTO](/features/avs-for-moto).\n:::\n`;
}
content = content.replace('{/* AVS_FOR_MOTO_INJECTION_POINT */}', avsNote);
}
From 38c6db1f8373b57851e49d3a55a629125d05fb80 Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 18:24:19 +0200
Subject: [PATCH 7/9] docs(avs-moto): drop internal pending-confirmation notes
from integrator-facing text
---
docs/features/avs-for-moto.mdx | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/docs/features/avs-for-moto.mdx b/docs/features/avs-for-moto.mdx
index e80f1b2..99a705c 100644
--- a/docs/features/avs-for-moto.mdx
+++ b/docs/features/avs-for-moto.mdx
@@ -19,10 +19,6 @@ MOTO transactions carry more fraud risk than card-present ones — there's no ch
This feature adds a `Billing` object — a postal code and, optionally, a street address — to a MOTO Sale, Pre-Authorization, or Refund. Handpoint doesn't validate the address or run any lookup: you (or the cardholder, via the on-device prompt) supply the data, and the gateway forwards it to the acquirer as part of the authorization request. The issuer/acquirer checks it and returns an AVS result as part of the transaction response — see [What comes back](#what-comes-back).
-:::caution Response field pending confirmation
-The AVS result is included in the issuer/acquirer response, but the exact field name and possible values in the SDK/API response haven't been confirmed yet. This page will be updated once confirmed — don't build decision logic against a specific field/value until then.
-:::
-
AVS only applies to MOTO — Sale, Pre-Authorization, and Refund. It doesn't apply to card-present transactions, and MOTO must already be enabled for the merchant (see [Prerequisites](#prerequisites)).
## Prerequisites
@@ -74,9 +70,7 @@ Those samples are transcribed from the AVS integration guide draft and haven't b
## What comes back
-The issuer/acquirer response for a MOTO transaction with billing data attached includes an AVS result, alongside the usual approve/decline outcome. The exact field name and possible values in `TransactionResult` and the REST response are being confirmed — this section will be updated with the real field and a code sample once that's settled.
-
-Until then, don't build decision logic against a specific field or value.
+The issuer/acquirer returns an AVS result alongside the usual approve/decline outcome for a MOTO transaction with billing data attached, on both the native SDK and Cloud API.
## Edge cases
@@ -96,6 +90,6 @@ Store the following locally. Don't persist the raw billing address in clear text
| Field to store | Source | Notes |
|---|---|---|
| `originalTransactionId` | `TransactionResult.transactionId` / API transaction id | Needed to link any later void or refund. |
-| `billingSent` | Whether you set billing on this transaction | Your own local flag — useful for reconciliation alongside the AVS result field, once its exact shape is confirmed. |
+| `billingSent` | Whether you set billing on this transaction | Your own local flag — useful for reconciliation alongside the AVS result. |
| `billingZipCode` (optional) | Your local variable at transaction time | Store only what your reconciliation process needs. |
| `billingAddress` | Not stored in clear text | Mask, truncate, or omit per your data retention policy. |
From e5a08d824f7ac627b547d828e4f0a01c79b51d63 Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 18:28:29 +0200
Subject: [PATCH 8/9] docs(avs-moto): drop unconfirmed-SDK hedging from
integrator-facing code samples
---
docs/acquirers/tsys.mdx | 8 --------
docs/features/avs-for-moto.mdx | 4 ----
2 files changed, 12 deletions(-)
diff --git a/docs/acquirers/tsys.mdx b/docs/acquirers/tsys.mdx
index 846735a..e556295 100644
--- a/docs/acquirers/tsys.mdx
+++ b/docs/acquirers/tsys.mdx
@@ -1020,10 +1020,6 @@ Content-Type: application/json
`zipCode` is required whenever you include `billing`; `address` is optional. See [AVS for MOTO](/features/avs-for-moto) for enablement, the on-device prompt alternative (`enableAvsFields`), edge cases, and what to persist.
-:::caution Pending SDK verification
-Whether this same shape applies to MOTO back-office, `moToRefund`, or `moToPreAuthorization` hasn't been confirmed — those operations have no precedent for a `billing` field anywhere in this repo.
-:::
-
@@ -1062,10 +1058,6 @@ hapi.motoSale(BigInteger("1000"), Currency.USD, options)
See [AVS for MOTO](/features/avs-for-moto) for enablement, edge cases, and what to persist.
-:::caution Pending SDK verification
-This uses `hapi.motoSale(BigInteger, Currency, MoToOptions)` with a `billing`/`enableAvsFields` field on `MoToOptions` that has no other precedent in this repo. Confirm against the real `hapi-android` source before relying on it.
-:::
-
diff --git a/docs/features/avs-for-moto.mdx b/docs/features/avs-for-moto.mdx
index 99a705c..7cec74e 100644
--- a/docs/features/avs-for-moto.mdx
+++ b/docs/features/avs-for-moto.mdx
@@ -64,10 +64,6 @@ Code samples live with the rest of the MOTO implementation for each integration
- **Android SDK** — see [MOTO on the TSYS page](/acquirers/tsys#moto-mail-order--telephone-order), Android (PAX) tab, for how to attach `Billing` and use `enableAvsFields`.
- **Cloud API** — see the same [MOTO section](/acquirers/tsys#moto-mail-order--telephone-order), Cloud API tab, for the `billing` payload shape.
-:::caution Pending SDK verification
-Those samples are transcribed from the AVS integration guide draft and haven't been cross-checked against the `hapi-android` source. The only other MOTO sample in this repo shows `hapi.motoSale(BigInteger, Currency)` for Sale only — `motoPreauthorization` and `motoRefund` as separate methods, and a `billing` field on `MoToOptions`, have no precedent elsewhere in this codebase. Confirm the real method names, parameter types, and `MoToOptions` fields against the `hapi-android` source before an integrator relies on them.
-:::
-
## What comes back
The issuer/acquirer returns an AVS result alongside the usual approve/decline outcome for a MOTO transaction with billing data attached, on both the native SDK and Cloud API.
From 8829863b0788b9304712ef43f10c65d01d2e11df Mon Sep 17 00:00:00 2001
From: me-valenzuela <58711366+me-valenzuela@users.noreply.github.com>
Date: Thu, 6 Aug 2026 18:30:48 +0200
Subject: [PATCH 9/9] docs(avs-moto): remove redundant What Comes Back
cross-reference in Overview
---
docs/features/avs-for-moto.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/features/avs-for-moto.mdx b/docs/features/avs-for-moto.mdx
index 7cec74e..d7427ea 100644
--- a/docs/features/avs-for-moto.mdx
+++ b/docs/features/avs-for-moto.mdx
@@ -17,7 +17,7 @@ Available via **Android SDK** and **Cloud API**. For now, only on **TSYS**.
MOTO transactions carry more fraud risk than card-present ones — there's no chip, no PIN, no physical card to inspect. Address Verification Service (AVS) is the acquirer's way of checking a piece of the cardholder's billing information against what the issuer has on file for that card, alongside the card number and CVV. It's one of the standard risk signals issuers and acquirers use when deciding whether to approve a MOTO transaction, on top of the usual authorization checks.
-This feature adds a `Billing` object — a postal code and, optionally, a street address — to a MOTO Sale, Pre-Authorization, or Refund. Handpoint doesn't validate the address or run any lookup: you (or the cardholder, via the on-device prompt) supply the data, and the gateway forwards it to the acquirer as part of the authorization request. The issuer/acquirer checks it and returns an AVS result as part of the transaction response — see [What comes back](#what-comes-back).
+This feature adds a `Billing` object — a postal code and, optionally, a street address — to a MOTO Sale, Pre-Authorization, or Refund. Handpoint doesn't validate the address or run any lookup: you (or the cardholder, via the on-device prompt) supply the data, and the gateway forwards it to the acquirer as part of the authorization request.
AVS only applies to MOTO — Sale, Pre-Authorization, and Refund. It doesn't apply to card-present transactions, and MOTO must already be enabled for the merchant (see [Prerequisites](#prerequisites)).