Problempayment gateway

Session: Sign in to solve

Solution.txt

Payment Gateway

Problem

Design PaymentGateway, an in-memory service that manages client access to payment modes and routes valid payments to deterministic mock banks. One gateway instance owns its clients, enabled modes, routing progress, bank outcomes, and observed success history.

Requirements

  • Manage clients. addClient adds a missing client with no enabled modes and returns true, or returns false for a duplicate without changing it. removeClient removes an existing client and its modes and returns true, or returns false for a missing client. hasClient reflects the current membership.
  • Add mode support. Without clientId, addSupportForPaymentMode enables a configured, currently disabled gateway mode. With clientId, it enables the mode for that existing client only when the gateway enables it and the client does not. The method returns true only when it changes the selected set.
  • Remove mode support. Without clientId, removePaymentMode disables an enabled gateway mode, removes it from every client, and returns true. With clientId, it removes a mode present for that client and returns true. Missing clients or absent memberships return false; disabling and re-enabling a gateway mode preserves its routing cursor, bank outcome positions, and success history.
  • List mode support. listSupportedPaymentModes returns the exact gateway set when clientId is absent, the exact client set for a registered client, or an empty array for a missing client. Array order is not judged.
  • Reject ineligible payments. makePayment returns {status: "REJECTED", bankId: ""} when the client is missing or the mode is not enabled by both the gateway and that client. A rejected payment changes no cursor, outcome position, or success history.
  • Validate instrument details. A UPI payment requires a non-empty vpa; CARD requires non-empty cardNumber, expiry, and cvv; NET_BANKING requires non-empty userId and password. Missing required details reject the payment, OTP is never required, and extra fields are ignored.
  • Route and execute payments. Each valid payment reads that mode's cursor from 0 through 99, selects the first configured bank when the cursor is less than its active percentage and the second bank otherwise, then advances the cursor modulo 100. The selected bank consumes its next repeating boolean outcome; the result contains that bank's ID and has status SUCCESS for true or FAILED for false. The gateway records attempts and successes separately for each bank and payment mode.
  • Adapt and inspect distribution. An unobserved bank whose configured percentage is positive has a 100 percent success rate. Equal rates keep the configured split; unequal rates send 100 percent to the higher-rate bank, while a bank configured at 0 percent stays excluded. For an enabled mode, showDistribution returns the two active integer percentages in configured bank order; they sum to 100. Disabled or unknown modes return an empty array.

API

SignatureReturnsBehavior
PaymentGateway(bankConfigs: BankConfig[], routingRules: RoutingRule[])PaymentGatewayCreates the configured banks and routes with empty client, mode, cursor, and history state.
addClient(clientId: string)booleanAttempts to register one client.
removeClient(clientId: string)booleanAttempts to remove one client.
hasClient(clientId: string)booleanReads current client membership.
listSupportedPaymentModes(clientId?: string)string[]Reads gateway-wide or client-specific mode support.
addSupportForPaymentMode(paymentMode: string, clientId?: string)booleanAttempts to enable gateway-wide or client-specific support.
removePaymentMode(paymentMode: string, clientId?: string)booleanAttempts to disable gateway-wide or client-specific support.
showDistribution(paymentMode: string)DistributionEntry[]Reads the active route allocation.
makePayment(clientId: string, paymentMode: string, details: object)PaymentResultValidates, routes, executes, and records one payment attempt.
TypeShape
BankConfig{bankId: string, supportedPaymentModes: string[], outcomePattern: boolean[]}
RoutingRule{paymentMode: string, firstBankId: string, secondBankId: string, firstBankPercent: integer}
DistributionEntry{bankId: string, percent: integer}
PaymentResult{status: string, bankId: string} where status is SUCCESS, FAILED, or REJECTED

Examples

Given banks A and B for UPI with outcome patterns [false] and [true], and a route from A to B with firstBankPercent 50:

StepOperationResult
1addClient("shop")true
2addSupportForPaymentMode("UPI")true
3addSupportForPaymentMode("UPI", "shop")true
4showDistribution("UPI")[{bankId: "A", percent: 50}, {bankId: "B", percent: 50}]
5makePayment("shop", "UPI", {}){status: "REJECTED", bankId: ""}
6makePayment("shop", "UPI", {vpa: "shop@upi"}){status: "FAILED", bankId: "A"}
7showDistribution("UPI")[{bankId: "A", percent: 0}, {bankId: "B", percent: 100}]
8makePayment("shop", "UPI", {vpa: "shop@upi"}){status: "SUCCESS", bankId: "B"}

Constraints

  • Each testcase has 2 to 20 banks, 1 to 3 routing rules, and at most one rule for each of UPI, CARD, and NET_BANKING.
  • A rule names two distinct configured banks that support its mode; firstBankPercent is an integer from 0 through 100.
  • Each bank supports 1 to 3 distinct modes and has an outcomePattern of 1 to 100 booleans.
  • Client and bank IDs contain 1 to 64 ASCII letters, digits, hyphens, or underscores and are compared exactly.
  • At most 1,000 clients are registered at once, and a testcase makes at most 50,000 public method calls.
  • Payment detail keys and values contain at most 256 characters; a required value must be present and non-empty.
  • Constructor inputs satisfy these configuration constraints.

Notes

Calls are sequential and perform no network, database, real-bank, or real-money I/O. Percentage comparisons use exact integer ratios, counters never become negative or exceed 50,000, and all state belongs to one gateway instance for one testcase.

PRIVATE WORKSPACE

Checking your session…

The statement is public. The editor, editorial, submissions, and saved work are private.