# Partial Authorization

Accept an authorization for less than the full requested amount when a prepaid or debit card can't cover the order total.

Source: https://developer.inoviopay.com/api/partial-auth.html  
Markdown: https://developer.inoviopay.com/api/partial-auth.md

Partial Authorization is a processor-specific feature that allows merchants to accept an authorization for a portion of the total requested amount. This is common when customers use prepaid or debit cards with a balance lower than the order total.

### How it Works

- You submit a standard `CCAUTHCAP` or `CCAUTHORIZE` request.
- You include the `PARTIAL_AUTH` flag and define a `PARTIAL_AUTH_MIN` (the lowest amount you are willing to accept to proceed).
- If the card has at least the minimum amount, the gateway returns an `APPROVED` status.

| Field Name | Description |
|---|---|
| PARTIAL_AUTH | Set to `1` to enable. Set to `0` or omit to disable. |
| PARTIAL_AUTH_MIN | The minimum numeric amount you will accept (e.g., `10.00`). If the card balance is below this, the transaction is declined. |

> **Critical Implementation Note**
> When Partial Authorization is enabled, you **must** parse the `TRANS_VALUE` field in the response. Do not assume an `APPROVED` status means the full amount was captured. Your system must handle the remaining balance via a secondary payment method.

<!-- Illustrative example: CCAUTHCAP with partial_auth enabled. The requested amount (75.00) exceeds partial_auth_min (10.00); TRANS_VALUE below shows a partial approval between the two. -->

**cURL**

```bash
curl -X POST "https://api.inoviopay.com/payment/pmt_service.cfm" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "request_action=CCAUTHCAP&req_username=api_user&req_password=P%40ssw0rd%21&site_id=12345&request_api_version=4.14&request_response_format=JSON&pmt_numb=4111111111111111&pmt_expiry=122026&pmt_key=123&request_currency=USD&li_value_1=75.00&xtl_order_id=INV-999&partial_auth=1&partial_auth_min=10.00"
```

**PHP**

```php
use Inovio\Gateway\{Credentials, InovioClient};
use Inovio\Gateway\Model\{LineItem, Money, PartialAuth, PaymentMethods};
use Inovio\Gateway\Request\TransactionRequest;

$client = new InovioClient(new Credentials('api_user', 'P@ssw0rd!', '12345'), 'SANDBOX');

$req = (new TransactionRequest(
    PaymentMethods::card('4111111111111111', '122026', '123'),
    [new LineItem('SKU-992', 1, Money::of('75.00', 'USD'))]
))->withIdempotency('INV-999');

$req->partialAuth = new PartialAuth(enabled: true);
$req->partialAuth->minimumAmount = Money::of('10.00', 'USD');

$result = $client->sale($req);

match ($result->status) {
    'APPROVED' => /* $result->raw['TRANS_VALUE'] may be less than 75.00 — reconcile the remainder */,
    'DECLINED' => /* card balance was below PARTIAL_AUTH_MIN */,
    default    => /* PENDING | RUNNING | FAILED */,
};
```

**Node**

```ts
import { InovioClient, Money, PaymentMethods } from '@inovio/gateway-sdk';

const client = new InovioClient(
  { reqUsername: 'api_user', reqPassword: 'P@ssw0rd!', siteId: '12345' },
  { environment: 'SANDBOX' }
);

const result = await client.sale({
  paymentMethod: PaymentMethods.card('4111111111111111', '122026', '123'),
  lineItems: [{ productId: 'SKU-992', count: 1, value: Money.of('75.00', 'USD') }],
  idempotency: { xtlOrderId: 'INV-999' },
  partialAuth: { enabled: true, minimumAmount: Money.of('10.00', 'USD') },
});

switch (result.status) {
  case 'APPROVED': /* result.raw.TRANS_VALUE may be less than 75.00 */ break;
  case 'DECLINED': /* card balance was below the minimum */ break;
  default: /* PENDING | RUNNING | FAILED */ break;
}
```

**Python**

```python
from inovio_gateway import Credentials, InovioClient, Money, PaymentMethods, TransactionStatus
from inovio_gateway.model import Idempotency, LineItem, PartialAuth
from inovio_gateway.request import TransactionRequest

client = InovioClient(Credentials("api_user", "P@ssw0rd!", site_id="12345"), environment="SANDBOX")

result = client.sale(TransactionRequest(
    payment_method=PaymentMethods.card("4111111111111111", "122026", "123"),
    line_items=[LineItem("SKU-992", 1, Money.of("75.00", "USD"))],
    idempotency=Idempotency(xtl_order_id="INV-999"),
    partial_auth=PartialAuth(enabled=True, minimum_amount=Money.of("10.00", "USD")),
))

if result.status is TransactionStatus.APPROVED:
    pass  # result.raw["TRANS_VALUE"] may be less than 75.00
elif result.status is TransactionStatus.DECLINED:
    pass  # card balance was below the minimum
```

**Java**

```java
InovioClient client = new InovioClient(
    new InovioClient.Credentials("api_user", "P@ssw0rd!", "12345"));

TransactionRequest req = new TransactionRequest(
    PaymentMethods.card("4111111111111111", "122026", "123"),
    new LineItem("SKU-992", 1, Money.of("75.00", "USD")))
    .idempotency("INV-999");

RequestParts.PartialAuth partialAuth = new RequestParts.PartialAuth(true);
partialAuth.minimumAmount = Money.of("10.00", "USD");
req.partialAuth = partialAuth;

TransactionResult result = client.sale(req);

switch (result.status()) {
    case APPROVED -> { /* result.raw().get("TRANS_VALUE") may be less than 75.00 */ }
    case DECLINED -> { /* card balance was below the minimum */ }
    default -> { /* PENDING | RUNNING | FAILED */ }
}
```

**Response**

```json
{
  "REQUEST_ACTION": "CCAUTHCAP",
  "REQ_ID": "68192033",
  "TRANS_STATUS_NAME": "APPROVED",
  "TRANS_VALUE": 32.50,
  "CURR_CODE_ALPHA": "USD",
  "TRANS_VALUE_SETTLED": 32.50,
  "CURR_CODE_ALPHA_SETTLED": "USD",
  "TRANS_EXCH_RATE": "",
  "TRANS_ID": 8839201112,
  "CUST_ID": 9928102,
  "XTL_CUST_ID": "cUsT992xP",
  "PO_ID": 77281920,
  "XTL_ORDER_ID": "INV-999",
  "BATCH_ID": 882910,
  "PROC_NAME": "Inovio Primary",
  "MERCH_ACCT_ID": 110203,
  "CARD_BRAND_NAME": "Mastercard",
  "CARD_TYPE": "MASTERCARD BLACK CARD",
  "CARD_CLASS": "Consumer Credit",
  "CARD_PREPAID": 0,
  "CARD_BANK": "CREDOMATIC INTERNATIONAL",
  "CARD_COUNTRY": "CRI",
  "CARD_DETAIL": "Credit",
  "CARD_BALANCE": "",
  "PMT_L4": "3535",
  "PMT_ID": 8829102,
  "PMT_ID_XTL": "",
  "PMT_AAU_UPDATE_DT": "",
  "PMT_AAU_UPDATE_DESC": "",
  "PROC_UDF01": "",
  "ANI_RESP_DECISION": "",
  "PROC_UDF02": "",
  "PROC_AUTH_RESPONSE": "AUTH99",
  "PROC_RETRIEVAL_NUM": "1029384A-B8C7-D6E5-F4G3-H2I1J0K9L8M7",
  "PROC_REFERENCE_NUM": "REF10293847",
  "PROC_REDIRECT_URL": "",
  "AVS_RESPONSE": "M",
  "CVV_RESPONSE": "M",
  "CARD_BRAND_TRANSID": "",
  "REQUEST_API_VERSION": "4.14",
  "P3DS_VENDOR": "",
  "P3DS_RESPONSE": "",
  "PO_LI_ID_1": "8829103",
  "PO_LI_COUNT_1": 1,
  "PO_LI_AMOUNT_1": "49.99",
  "PO_LI_PROD_ID_1": "SKU-992",
  "MBSHP_ID_1": "88291",
  "TRANS_NTOKEN_USED": 1
}
```
