# Testing

Test bank usage, a full reference table of gateway test scenarios, and the test credit card numbers that trigger them.

Source: https://developer.inoviopay.com/api/testing.html  
Markdown: https://developer.inoviopay.com/api/testing.md

### Using the Test Bank

Merchants may run test authorizations and other gateway actions using the test bank MID already configured in the portal.

Please note that transactions that have been blocked by the gateway due to invalid format or missing data will not be recorded and will not show up in merchant-facing reports on the Portal.

## Basic Gateway Test Scenarios

Use the table below as a reference for basic gateway testing scenarios and for testing your gateway response parser.

| Case | Description / Action | Expected Result |
|---|---|---|
| INVALID DATA | Send "1234" in `PMT_EXPIRY` | API_ADVICE: Invalid Data |
| REQUIRED FIELD | Send null in `SITE_ID` | API_ADVICE: Required field \| REF_FIELD: SITE_ID |
| INVALID MERCH_ACCT_ID | Send "9999" in `MERCH_ACCT_FIELD` | SERVICE_ADVICE: No merchant account configured |
| APPROVED AUTHORIZATION | Send `CCAUTHORIZE` with valid data | TRANS_STATUS_NAME: APPROVED |
| CAPTURE AUTHORIZATION | Send `CCCAPTURE` with required fields | TRANS_STATUS_NAME: APPROVED |
| SALE (AUTH + CAPTURE) | Send `CCAUTHCAP` with valid data | TRANS_STATUS_NAME: APPROVED |
| EXPIRED CARD | Send "5.02" in `LI_VALUE_1` | SERVICE_ADVICE: Expired Card |
| FAILED CVV | Send "5.03" in `LI_VALUE_1` | SERVICE_ADVICE: Failed CVV |
| FAILED AVS | Send "5.04" in `LI_VALUE_1` | SERVICE_ADVICE: Failed AVS |
| BANK DECLINED | Send "5.05" in `LI_VALUE_1` | SERVICE_ADVICE: Declined |
| FRAUD | Send "5.06" in `LI_VALUE_1` | SERVICE_ADVICE: Fraud |
| OVER LIMIT | Send "5.07" in `LI_VALUE_1` | PROCESSOR_ADVICE: Overlimit |
| AVS NO MATCH | Send "5.08" in `LI_VALUE_1` | AVS_RESPONSE: N |
| MISSING REQUIRED FIELD | Send "5.18" in `LI_VALUE_1` | PROCESSOR_ADVICE: Missing Required Field |
| PROCESSOR UNAVAILABLE | Send "5.30" in `LI_VALUE_1` | PROCESSOR_ADVICE: Downstream Processor Unavail |
| GENERAL DECLINE | Send "6.00" in `LI_VALUE_1` | PROCESSOR_ADVICE: General Decline |
| STOLEN CARD | Send "6.05" in `LI_VALUE_1` | PROCESSOR_ADVICE: Stolen Card |
| PICKUP CARD | Send "6.10" in `LI_VALUE_1` | PROCESSOR_ADVICE: Pickup Card |
| INVALID CVV | Send "6.20" in `LI_VALUE_1` | PROCESSOR_ADVICE: Invalid CVV |
| EXPIRED CARD (ALT) | Send "6.24" in `LI_VALUE_1` | PROCESSOR_ADVICE: Expired Card |
| TIMEOUT VOID | Send "6.26" in `LI_VALUE_1` | SERVICE_ADVICE: Voided per Timeout Void settings |
| INSUFFICIENT FUNDS | Send "6.35" in `LI_VALUE_1` | PROCESSOR_ADVICE: Insufficient Funds |
| PARTIAL AUTH TEST | Send `PARTIAL_AUTH=1`, `PARTIAL_AUTH_MIN=5.00`, `LI_VALUE_1=6.60` | TRANS_STATUS_NAME: APPROVED \| TRANS_VALUE: 5.5 |
| CONVERT CURRENCY | Send `REQUEST_CURRENCY=EUR` and `LI_VALUE_1=7.00` | TRANS_VALUE: 7 \| TRANS_VALUE_SETTLED: 5.686415 |
| CVV NO MATCH | Send "7.25" in `LI_VALUE_1` | CVV_RESPONSE: N |
| R1 REVOCATION (INDUSTRY) | Send "8.81" in `LI_VALUE_1` | INDUSTRY_RESPONSE: R1 |
| R3 REVOCATION (INDUSTRY) | Send "8.83" in `LI_VALUE_1` | INDUSTRY_RESPONSE: R3 |
| R1 REVOCATION (PROCESSOR) | Send "9.91" in `LI_VALUE_1` | PROCESSOR_RESPONSE: R1 |
| R3 REVOCATION (PROCESSOR) | Send "9.93" in `LI_VALUE_1` | PROCESSOR_RESPONSE: R3 |

## Triggering a Decline in Code

The `LI_VALUE_1` amounts in the table above are live triggers, not documentation placeholders: send `5.05` as the line item value against a test card and the gateway declines it every time, with `SERVICE_ADVICE: Declined`. Use it to exercise your decline-handling path without waiting on a real bank response.

**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=5.05&xtl_order_id=TEST-DECLINE-001"
```

**PHP**

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

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

// 5.05 is a live decline trigger in the test bank, not a placeholder amount.
$req = (new TransactionRequest(
    PaymentMethods::card('4111111111111111', '122026', '123'),
    [new LineItem('SKU-TEST', 1, Money::of('5.05', 'USD'))]
))->withIdempotency('TEST-DECLINE-001');

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

echo $result->status, "\n";   // DECLINED — this is not an exception
if ($result->status === 'DECLINED') {
    echo $result->outcome->service->code, ' ', $result->outcome->service->advice, "\n";
}
```

**Node**

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

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

// 5.05 is a live decline trigger in the test bank, not a placeholder amount.
const result = await client.sale({
  paymentMethod: PaymentMethods.card('4111111111111111', '122026', '123'),
  lineItems: [{ productId: 'SKU-TEST', count: 1, value: Money.of('5.05', 'USD') }],
  idempotency: { xtlOrderId: 'TEST-DECLINE-001' },
});

console.log(result.status);   // DECLINED — this is not a thrown error
if (result.status === 'DECLINED') {
  console.log(result.outcome.service.code, result.outcome.service.advice);
}
```

**Python**

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

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

# 5.05 is a live decline trigger in the test bank, not a placeholder amount.
req = TransactionRequest(
    payment_method=PaymentMethods.card("4111111111111111", "122026", "123"),
    line_items=[LineItem("SKU-TEST", 1, Money.of("5.05", "USD"))],
    idempotency=Idempotency(xtl_order_id="TEST-DECLINE-001"),
)

result = client.sale(req)

print(result.status.value)   # DECLINED — this is not a raised exception
if result.status is TransactionStatus.DECLINED:
    print(result.outcome.service.code, result.outcome.service.advice)
```

**Java**

```java
// 5.05 is a live decline trigger in the test bank, not a placeholder amount.
TransactionRequest req = new TransactionRequest(
    PaymentMethods.card("4111111111111111", "122026", "123"),
    new LineItem("SKU-TEST", 1, Money.of("5.05", "USD")))
    .idempotency("TEST-DECLINE-001");

TransactionResult result = client.sale(req);

System.out.println(result.status());   // DECLINED — this is not a thrown exception
if (result.status() == TransactionStatus.DECLINED) {
    System.out.println(result.outcome().service().code() + " " + result.outcome().service().advice());
}
```

**Response**

```json
{
  "REQUEST_ACTION": "CCAUTHCAP",
  "TRANS_STATUS_NAME": "DECLINED",
  "TRANS_VALUE": 5.05,
  "CURR_CODE_ALPHA": "USD",
  "PO_ID": 18103700,
  "XTL_ORDER_ID": "TEST-DECLINE-001",
  "TRANS_ID": 3948572200,
  "API_RESPONSE": "0",
  "SERVICE_RESPONSE": 515,
  "SERVICE_ADVICE": "Declined",
  "PROCESSOR_ADVICE": "General Decline",
  "CARD_BRAND_NAME": "Visa",
  "PMT_L4": "1111",
  "REQUEST_API_VERSION": "4.14"
}
```

## Test Credit Cards

> **Note**
> Use the credit cards below with any address, expiration date, and CVV2 data.

| Network | Credit Card Number |
|---|---|
| MASTERCARD | `5105105105105100` |
| MASTERCARD | `5555555555554444` |
| MASTERCARD | `5546989999990033` |
| VISA | `4111111111111111` |
| VISA | `4907639999990022` |
| AMERICAN EXPRESS | `378282246310005` |
| DINERS CLUB | `38520000023237` |
| DINERS CLUB | `30569309025904` |
| DISCOVER | `6011111111111117` |
| DISCOVER | `6011000990139424` |
| JCB | `3530111333300000` |
| JCB | `3566002020360505` |
