Proxy Switch Use Cases

Eclipse enables integration with externally hosted card and switch systems - such as cards or accounts managed on a Postilion platform - through a capability known as Proxy Switch Management. This allows external cards or accounts to be managed via Eclipse's secure and fine-grained API-driven authorization framework. While it does not provide the full suite of Eclipse features like native card issuing or wallet management, it serves as a powerful modernization layer for card management systems and payment switches.

The following Proxy Switch Management functions are currently supported:

  • Search for a card by ID number or linked account number
  • Configure and update card limits
  • Manage card status (e.g., block, unblock)
  • Link and manage accounts associated with a card
  • Activate new cards
  • Perform PIN operations (e.g., change, reset, validate)
  • Query card transaction history
  • Initiate switch-side transactions (ZipIt, bill payments, internal transfers)

Card Identifier

When calling these APIs typically a card identifier is required. To prevent exposure of PCI sensitive data in API calls the cardIdentifier is an encrypted field consisting of PAN, expiry and sequence number.

The algorithm for the caller to define this is:

public String encryptCardIdentifier(byte\[] key, String pan, String expiryMMYY, String sequenceNumber) {  
        String dataToEncrypt = pan + "." + (expiryMMYY == null ? "" : expiryMMYY) + "." + (sequenceNumber == null ? "" : sequenceNumber);  
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");  
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");  
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new GCMParameterSpec(128, new byte[16]));  
        return Base64.getEncoder().encodeToString(cipher.doFinal(dataToEncrypt));  
}

The key to be used is set in tenant config proxy.cards.aesKey and will be shared shared out of the band by the EFT onboarding team.

External System Identifier

The external service to query for the proxy cards, for example the Postilion interface, is determined by the bin of the card identifier. The EFT onboarding team will map the relevant bins to the particular external service in the global mapping property.

Prerequisites:

  • A valid JWT for API calls
  • Permission ProxyCard.CREATE/READ/UPDATE/DELETE assigned to the calling user
  • Tenant config proxy.cards.aesKey defined and shared with the tenant for generating a secure card identifier
  • Bins mapped to particular external system that is hosting the cards

Search for a proxy card

Before a cardIdentifier can be computed you need the underlying PAN, expiry and sequence number. If the caller only has the cardholder's ID number or a linked account number, use the search endpoint to look up the card first.

Use the search proxy cards endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards
    ?idNumber=8001015009087
    &accountNumber=00210104203902013
Authorization: Bearer {jwt}
Query parameterTypeDescription
idNumberstringThe cardholder's ID number. At least one of idNumber or accountNumber is required
accountNumberstringAn account number linked to the card. At least one of idNumber or accountNumber is required
[
  {
    "pan": "512345******9012",
    "seqNr": "01",
    "expiry": "2803",
    "cardStatus": "ACTIVE"
  }
]
📘

Note

This endpoint returns a masked PAN and status only — not a usable cardIdentifier. It's a lookup to confirm whether a card exists and its status, not a substitute for the Card Identifier encryption step above.

Manage card program limits

Get limits

Use the get limits by card program endpoint.

Update limits

Use the update limits by card program endpoint.

📘

Note

These two endpoints are not currently available — calling them returns an error. To manage limits for a specific card program today, use Manage card limits below with the relevant cardProgramName.

Manage card limits

Get Limits

Use the get limits by card endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/limits
    ?cardProgramName=GOLD
Authorization: Bearer {jwt}
Query parameterTypeRequiredDescription
cardProgramNamestringYesThe sub-program code identifying the card program the limits apply to

Update Limits

Use the update limits by card endpoint.

PUT /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/limits
    ?cardProgramName=GOLD
Authorization: Bearer {jwt}
Content-Type: application/json

cardProgramName is required here too. Only the limit keys present in the request body are updated; any limit not included is left unchanged.

Manage card status

Get card status

Use the get card status endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}
    ?attemptCVV=false
    &masked=true
Authorization: Bearer {jwt}
Query parameterTypeDefaultDescription
attemptCVVbooleanfalseWhen true, the response includes the card CVV retrieved from the external system
maskedbooleantrueWhen false, the unmasked PAN is returned (requires elevated permissions)
{
  "accountId": "string",
  "cardStatus": "ACTIVE",
  "lifeCycleStatus": "ACTIVATED",
  "pinStatus": "INVALID_PIN"
}
📘

Note

On this GET response, cardStatus can also come back as LINKED (the card has been successfully linked to the external switch but not yet activated) or LINK_FAILED (linking failed). These two are read-only outcomes of linking — you can only ever set cardStatus to ACTIVE or BLOCKED (see below).

Set card status (block or unblock card)

Use the set card status endpoint.

PUT /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "cardStatus": "BLOCKED",
  "blockReason": "LOST"
}

Valid cardStatus values: ACTIVE, BLOCKED.

Valid blockReason values: LOST, STOLEN, OTHER. blockReason must not be provided when setting status to ACTIVE.

Manage linked accounts

Get linked accounts

Use the get linked accounts endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/accounts
Authorization: Bearer {jwt}
{
    "accounts": [
        {
            "accountId": "00210104203902013",
            "accountType": "92",
            "currencyCode": "924",
            "ledgerBalance": 0
        }
    ]
}
📘

Note

Set tenant config proxy.cards.accounts.ledgerBalance.enabled to false to omit ledgerBalance from each account in this response. It defaults to true.

Link account to card

Use the link account to card endpoint.

POST /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/accounts
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "accountId": "12047675344333023",
  "accountType": "92",
  "accountTypeNominated": "92",
  "accountTypeQualifier": "1"
}

Unlink account

Use the unlink account from card endpoint.

DELETE /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/accounts/{accountId}
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "accountType": "92",
  "accountTypeNominated": "92",
  "accountTypeQualifier": "1"
}

Update account linked to card

Use the update account linked to card endpoint to update the account that a card is linked to.

PUT /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/accounts/{accountId}
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "accountType": "92",
  "accountTypeNominated": "92",
  "accountTypeQualifier": "1",
  "updatedAccountId": "00210104203902013"
}

Activate a new card

Use the activate a new card endpoint.

POST /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "customerId": "CUST00123456",
  "pin": "4321",
  "pinBlock": "ABC123...",
  "pinBlockFormat": "ISO0"
}
FieldTypeRequiredDescription
customerIdstringNoThe cardholder's ID in the external card management system. Recorded against the proxy.card.link.success audit event
pinstringConditionalPlaintext PIN — sandbox/testing only
pinBlockstringConditionalEncrypted PIN block — production
pinBlockFormatstringConditionalRequired with pinBlock. See valid values below

Provide either pin (plaintext, sandbox/testing only) or pinBlock + pinBlockFormat (production). Valid pinBlockFormat values: ISO0, ISO1, ISO2, ISO3, ISO4. These same pinBlockFormat values apply to every PIN operation on this page (generate, change/reset, validate).

Pin management on a card

Generate a new pin

Use the generate a new pin endpoint.

POST /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/pin-sets
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "pin": "4321",
  "pinBlock": "ABC123...",
  "pinBlockFormat": "ISO0"
}

Change or reset pin

Use the change or reset pin endpoint.

PUT /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/pin-sets
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "pin": "1234",
  "newPin": "9999",
  "pinBlock": "ABC123...",
  "pinBlockFormat": "ISO0"
}

Validate a pin

Use the validate a pin endpoint.

POST /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/validate-pins
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "accountId": "12047675344333023",
  "pin": "4321",
  "pinBlock": "ABC123...",
  "pinBlockFormat": "ISO0"
}

Balances and Mini Statements

Get the balance of a given account

Use the get balance of account endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/accounts/{accountId}/balance
    ?accountType=92
    &currencyCode=710
Authorization: Bearer {jwt}
Query parameterDescription
accountTypeOptional. Filters the balance by account type (e.g., 92 for cheque)
currencyCodeOptional. ISO 4217 numeric currency code (e.g., 710 for ZAR)
{
  "availableBalance": 0,
  "currency": "string",
  "ledgerBalance": 0,
  "timestamp": "2022-03-10T12:15:50-04:00"
}

Get the balance of a given card

Use the retrieve balance of proxy card endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/balance
Authorization: Bearer {jwt}
{
  "availableBalance": 0,
  "currency": "string",
  "ledgerBalance": 0,
  "timestamp": "2022-03-10T12:15:50-04:00"
}

Get mini statement of a given account

Use the get mini-statement of account endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/accounts/{accountId}/mini-statement
    ?accountType=92
    &currencyCode=710
Authorization: Bearer {jwt}
Query parameterDescription
accountTypeOptional. Filters by account type
currencyCodeOptional. ISO 4217 numeric currency code
[
  {
    "amount": 0,
    "currency": "string",
    "description": "string",
    "timestamp": "2022-03-10T12:15:50-04:00",
    "transactionId": "string",
    "type": "string"
  }
]

Get mini statement of a given card

Use the retrieve mini-statement of proxy card endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/mini-statement
Authorization: Bearer {jwt}
[
  {
    "amount": 0,
    "currency": "string",
    "description": "string",
    "timestamp": "2022-03-10T12:15:50-04:00",
    "transactionId": "string",
    "type": "string"
  }
]

Transaction Activities

Retrieve the full authorisation history for a proxy card. This endpoint returns a paginated list of card transactions from the external switch, including approval codes, response codes, merchant details, and settlement amounts.

Use the retrieve card activities endpoint.

GET /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/activities
    ?dateFromIncl=2026-05-01T00:00:00.000Z
    &dateToExcl=2026-05-31T23:59:59.999Z
    &dateFilterOn=transactionDate
    &limit=50
    &offset=0
Authorization: Bearer {jwt}
Query parameterDescription
dateFromInclStart of date range (inclusive), ISO 8601
dateToExclEnd of date range (exclusive), ISO 8601
dateFilterOntransactionDate filters on the transaction date; omit to filter on record created date
messageTypeIdFilter by ISO 8583 MTI (e.g., 0100, 0200)
cardBinFilter by card BIN
cardLast4DigitFilter by last 4 digits of PAN
transactionTypeFilter by ISO 8583 processing code
responseCodeFilter by ISO 8583 response code (e.g., 00 for approved)
terminalIdFilter by terminal ID
merchantIdFilter by merchant ID
offsetPagination offset (default: 0)
limitPage size (default: 50, max: 1000)
[
  {
    "cardHistoryId": 50001,
    "maskedPan": "512345******9012",
    "mti": "0200",
    "processingCode": "000000",
    "transactionAmount": 299.00,
    "transactionCurrencyCode": "710",
    "settlementAmount": 299.00,
    "settlementCurrencyCode": "710",
    "transactionDate": "2026-05-19T09:45:00.000Z",
    "authCode": "123456",
    "responseCode": "00",
    "rrn": "123456789012",
    "merchantId": "MERCH001",
    "merchantLocation": "TAKEALOT ONLINE ZA",
    "terminalId": "TERM0001",
    "acquiringInstitutionId": "123456",
    "merchantType": "5999"
  }
]

responseCode: "00" indicates an approved transaction. See Application Error Codes for the full list of ISO 8583 response codes.

Proxy Transactions

Initiate a switch-side transaction against a proxy card. This is used for operations such as interbank transfers (ZipIt), internal transfers, and bill payments that are routed through the external card switch rather than the Eclipse wallet layer.

Use the proxy transactions endpoint.

POST /eclipse-conductor/rest/v1/tenants/{tenantId}/proxy-cards/{cardIdentifier}/proxy-transactions
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "sourceAccount": "00210104203902013",
  "destinationAccount": "00210104203902099",
  "amount": 500.00,
  "operationTransactionType": "INTERNAL_TRANSFER"
}
FieldTypeRequiredDescription
sourceAccountstringYesAccount ID to debit
destinationAccountstringYesAccount ID to credit
amountnumberYesTransaction amount
operationTransactionTypestringYesTransaction type: ZIPIT, BILL_PAYMENT, or INTERNAL_TRANSFER
billPayeestringConditionalRequired when operationTransactionType is BILL_PAYMENT; rejected as a bad request if omitted
destinationBankNamestringConditionalRequired when operationTransactionType is ZIPIT; rejected as a bad request if omitted

For a BILL_PAYMENT, include billPayee instead of omitting it:

{
  "sourceAccount": "00210104203902013",
  "destinationAccount": "00210104203902099",
  "amount": 250.00,
  "operationTransactionType": "BILL_PAYMENT",
  "billPayee": "ZESA-1234567"
}

For a ZIPIT, include destinationBankName instead:

{
  "sourceAccount": "00210104203902013",
  "destinationAccount": "00210104203902099",
  "amount": 100.00,
  "operationTransactionType": "ZIPIT",
  "destinationBankName": "CBZ Bank"
}

Response:

{
  "cardIdentifier": "AbCdEf123...",
  "sourceAccount": "00210104203902013",
  "destinationAccount": "00210104203902099",
  "amount": 500.00,
  "operationType": "INTERNAL_TRANSFER",
  "transactionStatus": "SUCCESS"
}

transactionStatus is either SUCCESS or DECLINED.


Did this page help you?