PIN Debit & EBT balance check
1. Method & Path
POST /payment/balance-inquiry
2. Supported Variants
| # | Card Type | Entry Mode | Notes |
|---|---|---|---|
| 1 | PIN Debit | contactless | Tap debit card |
| 2 | PIN Debit | contact | Chip insert (EMV) |
| 3 | PIN Debit | swiped | Magnetic stripe — requires pin_block + ksn |
| 4 | EBT | Food (SNAP) | ebtCategory: "FOOD" |
| 5 | EBT | Cash | ebtCategory: "CASH" |
3. Handler module
payment.payment.handler — branched on paymentType: "balance_inquiry". Validation uses payment.model.balance_inquiry.BalanceInquiryRequest (which mandates commerceIndicator: "retail").
4. Request fields
Same scaffolding as /payment/auth plus:
| Field | Type | Required | Notes |
|---|---|---|---|
paymentType | "balance_inquiry" | yes | Literal |
commerceIndicator | "retail" | yes | Always retail |
entryMode | enum | yes | swiped, contact, contactless, msd (no manual / keyed) |
cardData.trackData (or emvData.trackData) | string | yes | Card-present required |
pin_block | hex string | conditional | Required for swiped entry mode |
ksn | hex string | conditional | Required for swiped entry mode |
ebtCategory | "FOOD" or "CASH" | conditional | Required for EBT inquiries only |
No amount field — the response IS the amount.
Entry mode differences
| Entry Mode | Card Data Required | PIN Required |
|---|---|---|
contactless | emvData.trackData + emvData.tags | No |
contact | emvData.trackData + emvData.tags | No |
swiped | cardData.trackData | Yes (pin_block + ksn) |
5. Response fields
Top-level fields
| Field | Type | Description |
|---|---|---|
responseCode | string | ISO 8583 response code. "00" = approved. |
ref_id | UUID | Idempotency key echoed back from the request |
transaction_id | string | Valor-assigned transaction identifier |
status | enum | AUTHORIZED, ERROR |
creatorName | string | Processor name (e.g. "VALOR") |
txn_type | string | Always "balance_inquiry" for this endpoint |
tran_no | integer | Sequential transaction number within the terminal session |
batch_no | string | Current open batch number |
authCode | string | Authorization code from the issuer |
reference | string | Retrieval reference number (RRN) |
created | ISO 8601 | Timestamp of the transaction |
balance object
balance object| Field | Type | Description |
|---|---|---|
amount | string | Signed decimal balance (e.g. "+20.00") |
accountType | string | Two-digit code identifying the account type (see table below) |
amountType | string | Two-digit code identifying the type of balance returned (see table below) |
cardInformation object
cardInformation object| Field | Type | Description |
|---|---|---|
maskedPan | string | Masked card number (e.g. "411111XXXXXX1111") |
expiryDate | string | Card expiry in MMYY format |
accountType codes (verified via CyberSource)
accountType codes (verified via CyberSource)| Code | Account Type | Description |
|---|---|---|
00 | Default | Not specified / generic |
10 | Savings | Savings account |
20 | Checking | Checking account |
30 | Credit | Credit card account (non-PIN-debit only) |
40 | Universal | Default debit account (PIN debit when no specific account selected) |
96 | EBT Cash | Cash benefit account (TANF, general assistance) |
98 | EBT Food (SNAP) | Supplemental Nutrition Assistance Program benefits |
PIN Debit cards return a single balance response with account type 40 (universal).
EBT cards typically return two separate balance responses — one for SNAP food (98) and one for cash benefits (96).
amountType codes (verified via CyberSource)
amountType codes (verified via CyberSource)For deposit accounts (PIN debit, EBT):
| Code | Amount Type | Description |
|---|---|---|
01 | Ledger balance | Current posted balance (total including pending/held amounts) |
02 | Available balance | Funds currently available for use (ledger minus outstanding auths; may include pending deposits and overdraft line) |
For credit card accounts:
| Code | Amount Type | Description |
|---|---|---|
01 | Open to buy | Credit amount remaining for customer |
02 | Credit limit | Total credit limit on the account |
Note: CyberSource states "the issuer determines the value that is returned." For EBT and PIN debit balance inquiries, amountType is typically "02" (available balance).
responseCode values (common)
responseCode values (common)| Code | Meaning |
|---|---|
00 | Approved |
05 | Do not honor |
12 | Invalid transaction |
14 | Invalid card number |
51 | Insufficient funds |
54 | Expired card |
55 | Incorrect PIN |
91 | Issuer unavailable |
96 | System malfunction |
6. Sample requests
PIN Debit — contactless
{
"merchantId": "855500000027",
"terminalId": "48593451",
"paymentType": "balance_inquiry",
"commerceIndicator": "retail",
"entryMode": "contactless",
"ref_id": "00000000-0000-0000-0000-000000000001",
"cardData": {
"panNumber": "4111111111111111",
"expiryDate": "1233",
"emvData": {
"trackData": "9F2608ABCDEF",
"tags": "9F1A0208"
}
}
}PIN Debit — contact (chip)
{
"merchantId": "855500000027",
"terminalId": "48593451",
"paymentType": "balance_inquiry",
"commerceIndicator": "retail",
"entryMode": "contact",
"ref_id": "00000000-0000-0000-0000-000000000002",
"cardData": {
"panNumber": "4111111111111111",
"expiryDate": "1233",
"emvData": {
"trackData": "9F2608ABCDEF",
"tags": "9F1A0208"
}
}
}PIN Debit — swiped
{
"merchantId": "855500000027",
"terminalId": "48593451",
"paymentType": "balance_inquiry",
"commerceIndicator": "retail",
"entryMode": "swiped",
"ref_id": "00000000-0000-0000-0000-000000000003",
"cardData": {
"trackData": "%B4111111111111111^TEST^30121011000000?;4111111111111111=30121011?"
},
"pin_block": "1A2B3C4D5E6F7890",
"ksn": "FFFF9876543210E00001"
}EBT — Food (SNAP)
{
"merchantId": "855500000027",
"terminalId": "48593451",
"paymentType": "balance_inquiry",
"commerceIndicator": "retail",
"entryMode": "swiped",
"ebtCategory": "FOOD",
"ref_id": "00000000-0000-0000-0000-000000000004",
"cardData": {
"trackData": "%B4111111111111111^TEST^30121011000000?;4111111111111111=30121011?"
},
"pin_block": "1A2B3C4D5E6F7890",
"ksn": "FFFF9876543210E00001"
}EBT — Cash
{
"merchantId": "855500000027",
"terminalId": "48593451",
"paymentType": "balance_inquiry",
"commerceIndicator": "retail",
"entryMode": "swiped",
"ebtCategory": "CASH",
"ref_id": "00000000-0000-0000-0000-000000000005",
"cardData": {
"trackData": "%B5061120000009012^TEST^30121011000000?;5061120000009012=30121011?"
},
"pin_block": "1A2B3C4D5E6F7890",
"ksn": "FFFF9876543210E00001"
}7. Sample responses
PIN Debit balance inquiry (accountType 40)
40){
"responseCode": "00",
"ref_id": "d5fd7466-01d3-45ad-82e8-724926db8571",
"transaction_id": "827517653749LD8",
"status": "AUTHORIZED",
"creatorName": "VALOR",
"txn_type": "balance_inquiry",
"tran_no": 54,
"batch_no": "1",
"balance": {
"amount": "+20.00",
"accountType": "40",
"amountType": "02"
},
"authCode": "925513",
"reference": "123456660749",
"cardInformation": {
"maskedPan": "411111XXXXXX1111",
"expiryDate": "1233"
},
"created": "2026-06-25T16:06:05Z"
}EBT Food (SNAP) balance inquiry (accountType 98)
98){
"responseCode": "00",
"ref_id": "a0d49c05-6828-4c89-8ae1-0fad51306ade",
"transaction_id": "827517611387O93",
"status": "AUTHORIZED",
"creatorName": "VALOR",
"txn_type": "balance_inquiry",
"tran_no": 35,
"batch_no": "1",
"balance": {
"amount": "+20.00",
"accountType": "98",
"amountType": "02"
},
"authCode": "450136",
"reference": "123456647008",
"cardInformation": {
"maskedPan": "411111XXXXXX1111",
"expiryDate": "1233"
},
"created": "2026-06-25T13:12:10Z"
}EBT Cash balance inquiry (accountType 96)
96){
"responseCode": "00",
"ref_id": "d56b2ade-1b2e-4184-a17f-96e2be9d90dd",
"transaction_id": "827517610024AGK",
"status": "AUTHORIZED",
"creatorName": "VALOR",
"txn_type": "balance_inquiry",
"tran_no": 36,
"batch_no": "1",
"balance": {
"amount": "+20.00",
"accountType": "96",
"amountType": "02"
},
"authCode": "649585",
"reference": "123456647070",
"cardInformation": {
"maskedPan": "506112XXXXXX9012",
"expiryDate": "1233"
},
"created": "2026-06-25T13:12:46Z"
}8. Errors
Same matrix as auth.md. Additionally:
| Trigger | Result |
|---|---|
entryMode not in swiped/contact/contactless/msd | 400 — entry mode validation |
commerceIndicator != "retail" | 400 — Pydantic literal rejection |
Missing pin_block + ksn for swiped | 400 — _validate_swiped_entry |
Missing ebtCategory for EBT card | 400 — validation error |