# POST /api/customers/add-stored-payment-method-async

Adds a new stored payment method to a customer's collection and persists it.

**Required permissions**: `Customers`, `Customers.Create`  
**Scope**: merchant

**Operation ID:** `customersAddStoredPaymentMethod`

## Authorization

Requires: Customers.Customers, Customers.Customers.Create, merchant scope.

Requires API key scope: `customers`

Required permissions:
- `Customers.Customers`
- `Customers.Customers.Create`

## Parameters

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| customerId | query | no | string(uuid) | The customer to add the payment method to. |
| suppressNulls | query | no | boolean | If true, omit properties with null values. |

## Request Body

**Content type:** `application/json`

Schema: [`AddStoredPaymentMethodInput`](https://devportal.demo.winkpg.io/docs/api/models/AddStoredPaymentMethodInput.md)

Properties:
- `paymentMethodType` ([CustomerStoredPaymentMethodType](https://devportal.demo.winkpg.io/docs/api/models/CustomerStoredPaymentMethodType.md)): Gets or sets the type of payment method (Card or Check). Conditional: When IsReaderTokenBacked is true. Must equal Card.
  Values:
  - `Card`
  - `Check`
- `cardData` ([CardData](https://devportal.demo.winkpg.io/docs/api/models/CardData.md)): Gets or sets the card data when `paymentMethodType` is Card. Required: When PaymentMethodType == Card and IsReaderTokenBacked is false. Conditional: When CardData is not null and PaymentMethodType == Card and IsReaderTokenBacked is false.
  Fields:
  - `cardNumber` (string): The card account number. Conditional: When IsStoredPayment is not true. (nullable)
  - `last4CardNumber` (integer(int32)): The last 4 digits of the card number as an integer. (nullable, read only)
  - `expirationMonth` (integer(int32)): The expiration month of the card as an integer in the range `1` to `12`.
  - `expirationYear` (integer(int32)): The expiration year of the card. Either a two-digit year (e.g. `29`) or a  four-digit year (e.g. `2029`); two-digit years resolve to the 2000s.
  - `expirationDate` (string(date-time)): The expiration date of the card. Conditional: When IsStoredPayment is not true. (nullable)
  - `binData` ([BinData](https://devportal.demo.winkpg.io/docs/api/models/BinData.md)): The BIN (Bank Identification Number) data associated with the card.
  - `cvv` (integer(int32)): Deprecated: send `cardVerificationValue` instead. The CVV (Card Verification  Value) of the card as an integer. Conditional: When IsStoredPayment is not true. Range: 100 to 9999. (nullable, deprecated)
  - `cardVerificationValue` (string): The card verification value (CVV, CVC or CID) exactly as printed on the card: three digits,  or four for American Express. Send it as a string so a leading zero is kept. Conditional: When IsStoredPayment is not true. (nullable)
  - `nameOnCard` (string): The name on the card. Conditional: When IsStoredPayment is not true. Max length: 25. (nullable, min length 0, max length 25)
  - `pin` (string): The PIN (Personal Identification Number) of the card. (nullable)
  - `keySerialNumber` (string): The Key Serial Number associated with the card. (nullable)
  - `emvData` (string): The EMV (Europay, Mastercard, and Visa) data associated with the card. (nullable)
  - `trackData` (string): The track data of the card. (nullable)
  - `encryptedTrack1Data` (string): The encrypted track 1 data of the card. (nullable)
  - `encryptedTrack2Data` (string): The encrypted track 2 data of the card. (nullable)
  - `encryptedTrack3Data` (string): The encrypted track 3 data of the card. (nullable)
  - `dynamicCardVerificationData` (string): A reader-generated dynamic card verification value captured at the moment the card was  read. Card readers that support it derive this value from physical characteristics of the  magnetic stripe, which differ between an original card and a copy, so the decryption  service that fronts the processor can score whether the presented card is genuine. (nullable)
  - `dynamicCardVerificationStatus` (string): Status metadata the reader reported alongside  `dynamicCardVerificationData` (for example whether the reader considered the  dynamic verification read successful). Non-secret: it describes the read, it is not the  verification value itself, so it is persisted as submitted. (nullable)
  - `iin` (string): The IIN (Issuer Identification Number) of the card. (nullable)
  - `arqc` (string): The ARQC (Authorization Request Cryptogram) of the card. (nullable)
  - `entryMode` ([EntryModes](https://devportal.demo.winkpg.io/docs/api/models/EntryModes.md)): The entry mode of the card.
    Values:
    - `Unknown`: The entry mode is unknown.
    - `NotApplicable`: The entry mode is not applicable for this transaction.
    - `Manual`: The transaction details were entered manually.
    - `UnencryptedCardReaderSwipe`: The card was swiped through an unencrypted card reader.
    - `EncryptedCardReaderSwipe`: The card was swiped through an encrypted card reader.
    - `Icc`: The transaction was processed using an ICC (Integrated Circuit Card) or chip card.
    - `Proximity`: The transaction was processed using a proximity or contactless payment method.
    - `Fallback`: The transaction was processed using a fallback method when the primary method failed.
    - `TechnicalFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `EmptyCandidateFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `DigitalWallet`: The transaction was processed using a digital wallet.
  - `cvPresence` ([CvPresence](https://devportal.demo.winkpg.io/docs/api/models/CvPresence.md)): The CV (Card Verification) presence status.
    Values:
    - `None`: The CV status is not specified or unknown.
    - `NotSubmitted`: The CV has not been submitted.
    - `Submitted`: The CV has been successfully submitted.
    - `Illegible`: The submitted CV is illegible or cannot be read.
    - `NotPresent`: The CV is not present or missing from the submission.
  - `billingAddress` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The billing address associated with the card.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `phone` (string): The phone number associated with the card. Conditional: When IsStoredPayment is not true. Max length: 15. Pattern: ^[0-9+()\-\s]*$. (nullable, min length 0, max length 15)
  - `email` (string): The email address associated with the card. Conditional: When IsStoredPayment is not true. Must be a valid email. Max length: 50. (nullable, min length 0, max length 50)
  - `hasEmvData` (boolean): Indicates whether EMV data was provided in the original request.  The raw `emvData` value is not stored. (nullable)
  - `hasTrackData` (boolean): Indicates whether track data was provided in the original request.  The raw `trackData` value is not stored. (nullable)
  - `hasEncryptedTrackData` (boolean): Indicates whether any encrypted track data (track 1, 2, or 3) was provided in the original request.  The raw encrypted track values are not stored. (nullable)
  - `hasCvv` (boolean): Indicates whether a CVV was provided in the original request, in either  `cardVerificationValue` or `cvv`. The raw value is not stored. (nullable)
  - `hasPin` (boolean): Indicates whether a PIN was provided in the original request.  The raw `pin` value is not stored. (nullable)
  - `hasDynamicCardVerificationData` (boolean): Indicates whether reader-generated dynamic card verification data was provided in the  original request. The raw `dynamicCardVerificationData` value is not stored. (nullable)
  - `emvAid` (string): (nullable)
  - `isDebitRouting` (boolean): (nullable)
  - `tenderType` ([CardTenderType](https://devportal.demo.winkpg.io/docs/api/models/CardTenderType.md)): The card-rail tender the caller is attempting to use. Drives deterministic  processor routing. `null` (or absent JSON) is treated as  `CreditDebit` for backward compatibility: see  `EffectiveTenderType`. (nullable)
    Values:
    - `CreditDebit`: Standard credit/debit card. The current card-rail behaviour. isDebitRouting modulates whether the request prefers debit-network routing within this rail.
    - `EbtSnap`: EBT SNAP (food benefits). Routes through the EBT SNAP processor lane and requires PIN + card-present per program rules.
    - `EbtCash`: EBT Cash (cash benefits). Distinct rail from SNAP; supports cashback where SNAP does not. PIN + card-present required.
    - `Ewic`: eWIC (Women, Infants, and Children). Distinct rail from EBT, with item-level eligibility / voucher-select flow handled in the eWIC follow-up epic.
  - `isStoredPayment` (boolean): When `true`, this card data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  card data from the payment token. (nullable)
  - `terminalCapability` ([TerminalCapability](https://devportal.demo.winkpg.io/docs/api/models/TerminalCapability.md)): The static hardware capability of the terminal. Selects the POS capability subfields on  the processor wire message. Resolved once in `ProcessorSelectionApplier`: request  value wins over the processor-profile default, which wins over `Unspecified`. (nullable)
    Values:
    - `Unspecified`: No capability declared. The handler emits its current default POS capability fields, preserving existing wire behavior exactly.
    - `MagneticStripe`: Magnetic stripe reader only (implies keyed entry).
    - `MagneticStripeWithPin`: Magnetic stripe reader with PIN pad (implies keyed entry).
    - `Chip`: Contact chip reader (EMV ICC).
    - `ChipWithPin`: Contact chip reader with PIN pad.
    - `ChipContactless`: Contactless chip reader (EMV contactless / NFC).
    - `ChipContactlessWithPin`: Contactless chip reader with PIN pad.
  - `cryptogram` (string): The payment network cryptogram recovered from wallet-token decryption  (the online payment cryptogram for Apple Pay / Google Pay DPAN  transactions). Sensitive: masked from logs. (nullable)
  - `eciIndicator` (string): The Electronic Commerce Indicator (ECI) describing the authentication  context of a tokenized / wallet transaction (e.g. `"05"` for a  3DS-authenticated transaction). Drives the liability-shift indicators  processors include in the network message. (nullable)
  - `isTokenized` (boolean): Indicates the credential is a tokenized account number (DPAN / network  token) rather than a raw PAN. `null` means unknown, which is treated the same as not  tokenized. (nullable)
  - `tokenTransactionId` (string): The provider-specific transaction identifier returned alongside a wallet  token (Apple Pay `transactionIdentifier`, network-token  transaction id). Used for dispute matching against the wallet provider. (nullable)
- `checkData` ([CheckData](https://devportal.demo.winkpg.io/docs/api/models/CheckData.md)): Gets or sets the check data when `paymentMethodType` is Check. Required: When PaymentMethodType == Check. Conditional: When CheckData is not null and PaymentMethodType == Check.
  Fields:
  - `nameOnCheck` (string): The name printed on the check. Required: When IsStoredPayment is not true. (nullable)
  - `routingNumber` (string): The routing number of the bank. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `routingNumberLast4` (string): The last 4 digits of `routingNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `accountNumber` (string): The account number associated with the check. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `accountNumberLast4` (string): The last 4 digits of `accountNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `checkNumber` (string): The check number. (nullable)
  - `micr` (string): The Magnetic Ink Character Recognition (MICR) data. (nullable)
  - `driversLicense` (string): The driver's license number of the check writer. (nullable)
  - `state` (string): The state of issuance for the driver's license. (nullable)
  - `ssn` (string): The Social Security Number of the check writer. (nullable)
  - `dateOfBirth` (string): The date of birth of the check writer. (nullable)
  - `checkType` ([CheckType](https://devportal.demo.winkpg.io/docs/api/models/CheckType.md)): The type of check.
    Values:
    - `Personal`: Represents a personal check. This is typically issued by an individual from their personal account.
    - `Business`: Represents a business check. This is typically issued by a company or organization from their business account.
  - `accountType` ([CheckAccountType](https://devportal.demo.winkpg.io/docs/api/models/CheckAccountType.md)): The type of account associated with the check. Conditional: When IsStoredPayment is not true.
    Values:
    - `Checking`: Represents a checking account.
    - `Savings`: Represents a savings account.
  - `rawMicr` (string): The raw MICR data. (nullable)
  - `branchCity` (string): The city of the bank branch. (nullable)
  - `emailAddress` (string): The email address of the check writer. Conditional: When IsStoredPayment is not true. Must be a valid email. (nullable)
  - `telephoneNumber` (string): The telephone number of the check writer. Conditional: When IsStoredPayment is not true. Pattern: ^[0-9+()\-\s]*$. (nullable)
  - `address` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The address associated with the check.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `secCode` ([SecCode](https://devportal.demo.winkpg.io/docs/api/models/SecCode.md)): The Standard Entry Class (SEC) code for the transaction. (nullable)
    Values:
    - `Ccd`: Corporate Credit or Debit (CCD) - Used for business-to-business transactions.
    - `Ppd`: Prearranged Payment and Deposit (PPD) - Used for consumer transactions.
    - `Web`: Internet-Initiated/Mobile Entry (WEB) - Used for internet or mobile-initiated transactions.
    - `Arc`: Accounts Receivable Conversion (ARC) - Used for converting eligible checks to ACH debits.
    - `Tel`: Telephone-Initiated Entry (TEL) - Used for telephone-initiated transactions.
  - `isStoredPayment` (boolean): When `true`, this check data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  account data from the payment token. (nullable)
- `isDefault` (boolean): Gets or sets whether this should be the customer's default payment method.
- `customName` (string): Gets or sets an optional user-defined display name (e.g., "Marriott Chase"). (nullable)
- `initialSchemeTransactionId` (string): Optional initial (first-in-series) network / scheme transaction id captured from the  authorization response of the cardholder-initiated transaction that stored this credential.  Populated only on the transaction-driven save-card path (the manual Customer admin add has no  authorization response); persisted onto the stored payment method so later charges can echo  it without a consent lookup. Non-sensitive card-network protocol metadata. (nullable)
- `schemeTransactionIdBrand` (string): Optional card brand at capture time (e.g. "Visa") tagged alongside  `initialSchemeTransactionId`. Ignored when the initial id is absent. (nullable)
- `schemeTransactionIdProcessor` (string): Optional originating processor ("tsys" / "fiserv") tagged alongside  `initialSchemeTransactionId`. Ignored when the initial id is absent. (nullable)
- `readerToken` (string): The processor reader token to store for a PAN-less card (a decrypt-and-forward processor such  as MagTek DAF, where the gateway never sees the PAN). When set, this input mints a reader-token  stored method: the token is written encrypted onto the backing vault token's  `ProcessorTokens` and there is no card data to vault. Set by the server only: a value  supplied over the API is not accepted. Never logged. (nullable)
- `readerTokenProcessorName` (string): The processor key ("magtekdaf") the `readerToken` belongs to, used as the  `ProcessorTokens` selection key. Required when `readerToken` is set. Required: When IsReaderTokenBacked is true. (nullable)
- `readerTokenProcessorProfileId` (string(uuid)): The processor profile the `readerToken` was captured under, used as the second part  of the `ProcessorTokens` selection key. Optional. (nullable)
- `readerTokenRequestorId` (string): Optional token-requestor id captured alongside the `readerToken`. Stored on the  backing token's `ProcessorTokens` entry for lineage. Non-sensitive. (nullable)
- `readerTokenMaskedCardNumber` (string): The masked card number of the card the `readerToken` stands in for, in the  platform's masked shape (for example `411111******1111`), read off the approved  authorization. Optional: absent when the processor response carried no card identity.  Display only. It is never a charge credential and never a dedupe input (two distinct reader  tokens can share a last four; `ReaderTokenFingerprint` stays the only matching key).  The consuming services re-mask it before persisting, so a full PAN cannot travel through  this field. Ignored unless `readerToken` is set. (nullable)
- `readerTokenCardBrand` (string): The card brand ("Visa", "Mastercard", ...) resolved for the card behind the  `readerToken`, or `null` when neither the processor response nor  the BIN lookup produced one. Best-effort display metadata; ignored unless  `readerTokenMaskedCardNumber` is set. (nullable)
- `isReaderTokenBacked` (boolean): True when this input describes a reader-token (PAN-less) stored method rather than a  PAN- or account-backed one. In that case `cardData` is absent by design. (read only)

_Example: Add Card_

Adds a credit/debit card to the customer's stored payment methods. Set IsDefault = true to mark this as the customer's default payment method (any prior default is automatically demoted server-side).

```json
{
  "paymentMethodType": "Card",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationDate": "2028-10-22",
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "None",
    "billingAddress": {
      "address1": "456 Oak Ave",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "isDefault": true,
  "customName": "Personal Visa"
}
```

_Example: Add ACH / eCheck_

Adds a US checking or savings account for ACH debits/credits. Routing + account numbers are required; the account is tokenized server-side.

```json
{
  "paymentMethodType": "Check",
  "checkData": {
    "nameOnCheck": "Acme Corp",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkType": "Business",
    "accountType": "Checking"
  },
  "customName": "Operating Account"
}
```

**Content type:** `text/json`

Schema: [`AddStoredPaymentMethodInput`](https://devportal.demo.winkpg.io/docs/api/models/AddStoredPaymentMethodInput.md)

Properties:
- `paymentMethodType` ([CustomerStoredPaymentMethodType](https://devportal.demo.winkpg.io/docs/api/models/CustomerStoredPaymentMethodType.md)): Gets or sets the type of payment method (Card or Check). Conditional: When IsReaderTokenBacked is true. Must equal Card.
  Values:
  - `Card`
  - `Check`
- `cardData` ([CardData](https://devportal.demo.winkpg.io/docs/api/models/CardData.md)): Gets or sets the card data when `paymentMethodType` is Card. Required: When PaymentMethodType == Card and IsReaderTokenBacked is false. Conditional: When CardData is not null and PaymentMethodType == Card and IsReaderTokenBacked is false.
  Fields:
  - `cardNumber` (string): The card account number. Conditional: When IsStoredPayment is not true. (nullable)
  - `last4CardNumber` (integer(int32)): The last 4 digits of the card number as an integer. (nullable, read only)
  - `expirationMonth` (integer(int32)): The expiration month of the card as an integer in the range `1` to `12`.
  - `expirationYear` (integer(int32)): The expiration year of the card. Either a two-digit year (e.g. `29`) or a  four-digit year (e.g. `2029`); two-digit years resolve to the 2000s.
  - `expirationDate` (string(date-time)): The expiration date of the card. Conditional: When IsStoredPayment is not true. (nullable)
  - `binData` ([BinData](https://devportal.demo.winkpg.io/docs/api/models/BinData.md)): The BIN (Bank Identification Number) data associated with the card.
  - `cvv` (integer(int32)): Deprecated: send `cardVerificationValue` instead. The CVV (Card Verification  Value) of the card as an integer. Conditional: When IsStoredPayment is not true. Range: 100 to 9999. (nullable, deprecated)
  - `cardVerificationValue` (string): The card verification value (CVV, CVC or CID) exactly as printed on the card: three digits,  or four for American Express. Send it as a string so a leading zero is kept. Conditional: When IsStoredPayment is not true. (nullable)
  - `nameOnCard` (string): The name on the card. Conditional: When IsStoredPayment is not true. Max length: 25. (nullable, min length 0, max length 25)
  - `pin` (string): The PIN (Personal Identification Number) of the card. (nullable)
  - `keySerialNumber` (string): The Key Serial Number associated with the card. (nullable)
  - `emvData` (string): The EMV (Europay, Mastercard, and Visa) data associated with the card. (nullable)
  - `trackData` (string): The track data of the card. (nullable)
  - `encryptedTrack1Data` (string): The encrypted track 1 data of the card. (nullable)
  - `encryptedTrack2Data` (string): The encrypted track 2 data of the card. (nullable)
  - `encryptedTrack3Data` (string): The encrypted track 3 data of the card. (nullable)
  - `dynamicCardVerificationData` (string): A reader-generated dynamic card verification value captured at the moment the card was  read. Card readers that support it derive this value from physical characteristics of the  magnetic stripe, which differ between an original card and a copy, so the decryption  service that fronts the processor can score whether the presented card is genuine. (nullable)
  - `dynamicCardVerificationStatus` (string): Status metadata the reader reported alongside  `dynamicCardVerificationData` (for example whether the reader considered the  dynamic verification read successful). Non-secret: it describes the read, it is not the  verification value itself, so it is persisted as submitted. (nullable)
  - `iin` (string): The IIN (Issuer Identification Number) of the card. (nullable)
  - `arqc` (string): The ARQC (Authorization Request Cryptogram) of the card. (nullable)
  - `entryMode` ([EntryModes](https://devportal.demo.winkpg.io/docs/api/models/EntryModes.md)): The entry mode of the card.
    Values:
    - `Unknown`: The entry mode is unknown.
    - `NotApplicable`: The entry mode is not applicable for this transaction.
    - `Manual`: The transaction details were entered manually.
    - `UnencryptedCardReaderSwipe`: The card was swiped through an unencrypted card reader.
    - `EncryptedCardReaderSwipe`: The card was swiped through an encrypted card reader.
    - `Icc`: The transaction was processed using an ICC (Integrated Circuit Card) or chip card.
    - `Proximity`: The transaction was processed using a proximity or contactless payment method.
    - `Fallback`: The transaction was processed using a fallback method when the primary method failed.
    - `TechnicalFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `EmptyCandidateFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `DigitalWallet`: The transaction was processed using a digital wallet.
  - `cvPresence` ([CvPresence](https://devportal.demo.winkpg.io/docs/api/models/CvPresence.md)): The CV (Card Verification) presence status.
    Values:
    - `None`: The CV status is not specified or unknown.
    - `NotSubmitted`: The CV has not been submitted.
    - `Submitted`: The CV has been successfully submitted.
    - `Illegible`: The submitted CV is illegible or cannot be read.
    - `NotPresent`: The CV is not present or missing from the submission.
  - `billingAddress` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The billing address associated with the card.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `phone` (string): The phone number associated with the card. Conditional: When IsStoredPayment is not true. Max length: 15. Pattern: ^[0-9+()\-\s]*$. (nullable, min length 0, max length 15)
  - `email` (string): The email address associated with the card. Conditional: When IsStoredPayment is not true. Must be a valid email. Max length: 50. (nullable, min length 0, max length 50)
  - `hasEmvData` (boolean): Indicates whether EMV data was provided in the original request.  The raw `emvData` value is not stored. (nullable)
  - `hasTrackData` (boolean): Indicates whether track data was provided in the original request.  The raw `trackData` value is not stored. (nullable)
  - `hasEncryptedTrackData` (boolean): Indicates whether any encrypted track data (track 1, 2, or 3) was provided in the original request.  The raw encrypted track values are not stored. (nullable)
  - `hasCvv` (boolean): Indicates whether a CVV was provided in the original request, in either  `cardVerificationValue` or `cvv`. The raw value is not stored. (nullable)
  - `hasPin` (boolean): Indicates whether a PIN was provided in the original request.  The raw `pin` value is not stored. (nullable)
  - `hasDynamicCardVerificationData` (boolean): Indicates whether reader-generated dynamic card verification data was provided in the  original request. The raw `dynamicCardVerificationData` value is not stored. (nullable)
  - `emvAid` (string): (nullable)
  - `isDebitRouting` (boolean): (nullable)
  - `tenderType` ([CardTenderType](https://devportal.demo.winkpg.io/docs/api/models/CardTenderType.md)): The card-rail tender the caller is attempting to use. Drives deterministic  processor routing. `null` (or absent JSON) is treated as  `CreditDebit` for backward compatibility: see  `EffectiveTenderType`. (nullable)
    Values:
    - `CreditDebit`: Standard credit/debit card. The current card-rail behaviour. isDebitRouting modulates whether the request prefers debit-network routing within this rail.
    - `EbtSnap`: EBT SNAP (food benefits). Routes through the EBT SNAP processor lane and requires PIN + card-present per program rules.
    - `EbtCash`: EBT Cash (cash benefits). Distinct rail from SNAP; supports cashback where SNAP does not. PIN + card-present required.
    - `Ewic`: eWIC (Women, Infants, and Children). Distinct rail from EBT, with item-level eligibility / voucher-select flow handled in the eWIC follow-up epic.
  - `isStoredPayment` (boolean): When `true`, this card data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  card data from the payment token. (nullable)
  - `terminalCapability` ([TerminalCapability](https://devportal.demo.winkpg.io/docs/api/models/TerminalCapability.md)): The static hardware capability of the terminal. Selects the POS capability subfields on  the processor wire message. Resolved once in `ProcessorSelectionApplier`: request  value wins over the processor-profile default, which wins over `Unspecified`. (nullable)
    Values:
    - `Unspecified`: No capability declared. The handler emits its current default POS capability fields, preserving existing wire behavior exactly.
    - `MagneticStripe`: Magnetic stripe reader only (implies keyed entry).
    - `MagneticStripeWithPin`: Magnetic stripe reader with PIN pad (implies keyed entry).
    - `Chip`: Contact chip reader (EMV ICC).
    - `ChipWithPin`: Contact chip reader with PIN pad.
    - `ChipContactless`: Contactless chip reader (EMV contactless / NFC).
    - `ChipContactlessWithPin`: Contactless chip reader with PIN pad.
  - `cryptogram` (string): The payment network cryptogram recovered from wallet-token decryption  (the online payment cryptogram for Apple Pay / Google Pay DPAN  transactions). Sensitive: masked from logs. (nullable)
  - `eciIndicator` (string): The Electronic Commerce Indicator (ECI) describing the authentication  context of a tokenized / wallet transaction (e.g. `"05"` for a  3DS-authenticated transaction). Drives the liability-shift indicators  processors include in the network message. (nullable)
  - `isTokenized` (boolean): Indicates the credential is a tokenized account number (DPAN / network  token) rather than a raw PAN. `null` means unknown, which is treated the same as not  tokenized. (nullable)
  - `tokenTransactionId` (string): The provider-specific transaction identifier returned alongside a wallet  token (Apple Pay `transactionIdentifier`, network-token  transaction id). Used for dispute matching against the wallet provider. (nullable)
- `checkData` ([CheckData](https://devportal.demo.winkpg.io/docs/api/models/CheckData.md)): Gets or sets the check data when `paymentMethodType` is Check. Required: When PaymentMethodType == Check. Conditional: When CheckData is not null and PaymentMethodType == Check.
  Fields:
  - `nameOnCheck` (string): The name printed on the check. Required: When IsStoredPayment is not true. (nullable)
  - `routingNumber` (string): The routing number of the bank. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `routingNumberLast4` (string): The last 4 digits of `routingNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `accountNumber` (string): The account number associated with the check. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `accountNumberLast4` (string): The last 4 digits of `accountNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `checkNumber` (string): The check number. (nullable)
  - `micr` (string): The Magnetic Ink Character Recognition (MICR) data. (nullable)
  - `driversLicense` (string): The driver's license number of the check writer. (nullable)
  - `state` (string): The state of issuance for the driver's license. (nullable)
  - `ssn` (string): The Social Security Number of the check writer. (nullable)
  - `dateOfBirth` (string): The date of birth of the check writer. (nullable)
  - `checkType` ([CheckType](https://devportal.demo.winkpg.io/docs/api/models/CheckType.md)): The type of check.
    Values:
    - `Personal`: Represents a personal check. This is typically issued by an individual from their personal account.
    - `Business`: Represents a business check. This is typically issued by a company or organization from their business account.
  - `accountType` ([CheckAccountType](https://devportal.demo.winkpg.io/docs/api/models/CheckAccountType.md)): The type of account associated with the check. Conditional: When IsStoredPayment is not true.
    Values:
    - `Checking`: Represents a checking account.
    - `Savings`: Represents a savings account.
  - `rawMicr` (string): The raw MICR data. (nullable)
  - `branchCity` (string): The city of the bank branch. (nullable)
  - `emailAddress` (string): The email address of the check writer. Conditional: When IsStoredPayment is not true. Must be a valid email. (nullable)
  - `telephoneNumber` (string): The telephone number of the check writer. Conditional: When IsStoredPayment is not true. Pattern: ^[0-9+()\-\s]*$. (nullable)
  - `address` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The address associated with the check.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `secCode` ([SecCode](https://devportal.demo.winkpg.io/docs/api/models/SecCode.md)): The Standard Entry Class (SEC) code for the transaction. (nullable)
    Values:
    - `Ccd`: Corporate Credit or Debit (CCD) - Used for business-to-business transactions.
    - `Ppd`: Prearranged Payment and Deposit (PPD) - Used for consumer transactions.
    - `Web`: Internet-Initiated/Mobile Entry (WEB) - Used for internet or mobile-initiated transactions.
    - `Arc`: Accounts Receivable Conversion (ARC) - Used for converting eligible checks to ACH debits.
    - `Tel`: Telephone-Initiated Entry (TEL) - Used for telephone-initiated transactions.
  - `isStoredPayment` (boolean): When `true`, this check data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  account data from the payment token. (nullable)
- `isDefault` (boolean): Gets or sets whether this should be the customer's default payment method.
- `customName` (string): Gets or sets an optional user-defined display name (e.g., "Marriott Chase"). (nullable)
- `initialSchemeTransactionId` (string): Optional initial (first-in-series) network / scheme transaction id captured from the  authorization response of the cardholder-initiated transaction that stored this credential.  Populated only on the transaction-driven save-card path (the manual Customer admin add has no  authorization response); persisted onto the stored payment method so later charges can echo  it without a consent lookup. Non-sensitive card-network protocol metadata. (nullable)
- `schemeTransactionIdBrand` (string): Optional card brand at capture time (e.g. "Visa") tagged alongside  `initialSchemeTransactionId`. Ignored when the initial id is absent. (nullable)
- `schemeTransactionIdProcessor` (string): Optional originating processor ("tsys" / "fiserv") tagged alongside  `initialSchemeTransactionId`. Ignored when the initial id is absent. (nullable)
- `readerToken` (string): The processor reader token to store for a PAN-less card (a decrypt-and-forward processor such  as MagTek DAF, where the gateway never sees the PAN). When set, this input mints a reader-token  stored method: the token is written encrypted onto the backing vault token's  `ProcessorTokens` and there is no card data to vault. Set by the server only: a value  supplied over the API is not accepted. Never logged. (nullable)
- `readerTokenProcessorName` (string): The processor key ("magtekdaf") the `readerToken` belongs to, used as the  `ProcessorTokens` selection key. Required when `readerToken` is set. Required: When IsReaderTokenBacked is true. (nullable)
- `readerTokenProcessorProfileId` (string(uuid)): The processor profile the `readerToken` was captured under, used as the second part  of the `ProcessorTokens` selection key. Optional. (nullable)
- `readerTokenRequestorId` (string): Optional token-requestor id captured alongside the `readerToken`. Stored on the  backing token's `ProcessorTokens` entry for lineage. Non-sensitive. (nullable)
- `readerTokenMaskedCardNumber` (string): The masked card number of the card the `readerToken` stands in for, in the  platform's masked shape (for example `411111******1111`), read off the approved  authorization. Optional: absent when the processor response carried no card identity.  Display only. It is never a charge credential and never a dedupe input (two distinct reader  tokens can share a last four; `ReaderTokenFingerprint` stays the only matching key).  The consuming services re-mask it before persisting, so a full PAN cannot travel through  this field. Ignored unless `readerToken` is set. (nullable)
- `readerTokenCardBrand` (string): The card brand ("Visa", "Mastercard", ...) resolved for the card behind the  `readerToken`, or `null` when neither the processor response nor  the BIN lookup produced one. Best-effort display metadata; ignored unless  `readerTokenMaskedCardNumber` is set. (nullable)
- `isReaderTokenBacked` (boolean): True when this input describes a reader-token (PAN-less) stored method rather than a  PAN- or account-backed one. In that case `cardData` is absent by design. (read only)

_Example: Add Card_

Adds a credit/debit card to the customer's stored payment methods. Set IsDefault = true to mark this as the customer's default payment method (any prior default is automatically demoted server-side).

```json
{
  "paymentMethodType": "Card",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationDate": "2028-10-22",
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "None",
    "billingAddress": {
      "address1": "456 Oak Ave",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "isDefault": true,
  "customName": "Personal Visa"
}
```

_Example: Add ACH / eCheck_

Adds a US checking or savings account for ACH debits/credits. Routing + account numbers are required; the account is tokenized server-side.

```json
{
  "paymentMethodType": "Check",
  "checkData": {
    "nameOnCheck": "Acme Corp",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkType": "Business",
    "accountType": "Checking"
  },
  "customName": "Operating Account"
}
```

**Content type:** `application/*+json`

Schema: [`AddStoredPaymentMethodInput`](https://devportal.demo.winkpg.io/docs/api/models/AddStoredPaymentMethodInput.md)

Properties:
- `paymentMethodType` ([CustomerStoredPaymentMethodType](https://devportal.demo.winkpg.io/docs/api/models/CustomerStoredPaymentMethodType.md)): Gets or sets the type of payment method (Card or Check). Conditional: When IsReaderTokenBacked is true. Must equal Card.
  Values:
  - `Card`
  - `Check`
- `cardData` ([CardData](https://devportal.demo.winkpg.io/docs/api/models/CardData.md)): Gets or sets the card data when `paymentMethodType` is Card. Required: When PaymentMethodType == Card and IsReaderTokenBacked is false. Conditional: When CardData is not null and PaymentMethodType == Card and IsReaderTokenBacked is false.
  Fields:
  - `cardNumber` (string): The card account number. Conditional: When IsStoredPayment is not true. (nullable)
  - `last4CardNumber` (integer(int32)): The last 4 digits of the card number as an integer. (nullable, read only)
  - `expirationMonth` (integer(int32)): The expiration month of the card as an integer in the range `1` to `12`.
  - `expirationYear` (integer(int32)): The expiration year of the card. Either a two-digit year (e.g. `29`) or a  four-digit year (e.g. `2029`); two-digit years resolve to the 2000s.
  - `expirationDate` (string(date-time)): The expiration date of the card. Conditional: When IsStoredPayment is not true. (nullable)
  - `binData` ([BinData](https://devportal.demo.winkpg.io/docs/api/models/BinData.md)): The BIN (Bank Identification Number) data associated with the card.
  - `cvv` (integer(int32)): Deprecated: send `cardVerificationValue` instead. The CVV (Card Verification  Value) of the card as an integer. Conditional: When IsStoredPayment is not true. Range: 100 to 9999. (nullable, deprecated)
  - `cardVerificationValue` (string): The card verification value (CVV, CVC or CID) exactly as printed on the card: three digits,  or four for American Express. Send it as a string so a leading zero is kept. Conditional: When IsStoredPayment is not true. (nullable)
  - `nameOnCard` (string): The name on the card. Conditional: When IsStoredPayment is not true. Max length: 25. (nullable, min length 0, max length 25)
  - `pin` (string): The PIN (Personal Identification Number) of the card. (nullable)
  - `keySerialNumber` (string): The Key Serial Number associated with the card. (nullable)
  - `emvData` (string): The EMV (Europay, Mastercard, and Visa) data associated with the card. (nullable)
  - `trackData` (string): The track data of the card. (nullable)
  - `encryptedTrack1Data` (string): The encrypted track 1 data of the card. (nullable)
  - `encryptedTrack2Data` (string): The encrypted track 2 data of the card. (nullable)
  - `encryptedTrack3Data` (string): The encrypted track 3 data of the card. (nullable)
  - `dynamicCardVerificationData` (string): A reader-generated dynamic card verification value captured at the moment the card was  read. Card readers that support it derive this value from physical characteristics of the  magnetic stripe, which differ between an original card and a copy, so the decryption  service that fronts the processor can score whether the presented card is genuine. (nullable)
  - `dynamicCardVerificationStatus` (string): Status metadata the reader reported alongside  `dynamicCardVerificationData` (for example whether the reader considered the  dynamic verification read successful). Non-secret: it describes the read, it is not the  verification value itself, so it is persisted as submitted. (nullable)
  - `iin` (string): The IIN (Issuer Identification Number) of the card. (nullable)
  - `arqc` (string): The ARQC (Authorization Request Cryptogram) of the card. (nullable)
  - `entryMode` ([EntryModes](https://devportal.demo.winkpg.io/docs/api/models/EntryModes.md)): The entry mode of the card.
    Values:
    - `Unknown`: The entry mode is unknown.
    - `NotApplicable`: The entry mode is not applicable for this transaction.
    - `Manual`: The transaction details were entered manually.
    - `UnencryptedCardReaderSwipe`: The card was swiped through an unencrypted card reader.
    - `EncryptedCardReaderSwipe`: The card was swiped through an encrypted card reader.
    - `Icc`: The transaction was processed using an ICC (Integrated Circuit Card) or chip card.
    - `Proximity`: The transaction was processed using a proximity or contactless payment method.
    - `Fallback`: The transaction was processed using a fallback method when the primary method failed.
    - `TechnicalFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `EmptyCandidateFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `DigitalWallet`: The transaction was processed using a digital wallet.
  - `cvPresence` ([CvPresence](https://devportal.demo.winkpg.io/docs/api/models/CvPresence.md)): The CV (Card Verification) presence status.
    Values:
    - `None`: The CV status is not specified or unknown.
    - `NotSubmitted`: The CV has not been submitted.
    - `Submitted`: The CV has been successfully submitted.
    - `Illegible`: The submitted CV is illegible or cannot be read.
    - `NotPresent`: The CV is not present or missing from the submission.
  - `billingAddress` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The billing address associated with the card.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `phone` (string): The phone number associated with the card. Conditional: When IsStoredPayment is not true. Max length: 15. Pattern: ^[0-9+()\-\s]*$. (nullable, min length 0, max length 15)
  - `email` (string): The email address associated with the card. Conditional: When IsStoredPayment is not true. Must be a valid email. Max length: 50. (nullable, min length 0, max length 50)
  - `hasEmvData` (boolean): Indicates whether EMV data was provided in the original request.  The raw `emvData` value is not stored. (nullable)
  - `hasTrackData` (boolean): Indicates whether track data was provided in the original request.  The raw `trackData` value is not stored. (nullable)
  - `hasEncryptedTrackData` (boolean): Indicates whether any encrypted track data (track 1, 2, or 3) was provided in the original request.  The raw encrypted track values are not stored. (nullable)
  - `hasCvv` (boolean): Indicates whether a CVV was provided in the original request, in either  `cardVerificationValue` or `cvv`. The raw value is not stored. (nullable)
  - `hasPin` (boolean): Indicates whether a PIN was provided in the original request.  The raw `pin` value is not stored. (nullable)
  - `hasDynamicCardVerificationData` (boolean): Indicates whether reader-generated dynamic card verification data was provided in the  original request. The raw `dynamicCardVerificationData` value is not stored. (nullable)
  - `emvAid` (string): (nullable)
  - `isDebitRouting` (boolean): (nullable)
  - `tenderType` ([CardTenderType](https://devportal.demo.winkpg.io/docs/api/models/CardTenderType.md)): The card-rail tender the caller is attempting to use. Drives deterministic  processor routing. `null` (or absent JSON) is treated as  `CreditDebit` for backward compatibility: see  `EffectiveTenderType`. (nullable)
    Values:
    - `CreditDebit`: Standard credit/debit card. The current card-rail behaviour. isDebitRouting modulates whether the request prefers debit-network routing within this rail.
    - `EbtSnap`: EBT SNAP (food benefits). Routes through the EBT SNAP processor lane and requires PIN + card-present per program rules.
    - `EbtCash`: EBT Cash (cash benefits). Distinct rail from SNAP; supports cashback where SNAP does not. PIN + card-present required.
    - `Ewic`: eWIC (Women, Infants, and Children). Distinct rail from EBT, with item-level eligibility / voucher-select flow handled in the eWIC follow-up epic.
  - `isStoredPayment` (boolean): When `true`, this card data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  card data from the payment token. (nullable)
  - `terminalCapability` ([TerminalCapability](https://devportal.demo.winkpg.io/docs/api/models/TerminalCapability.md)): The static hardware capability of the terminal. Selects the POS capability subfields on  the processor wire message. Resolved once in `ProcessorSelectionApplier`: request  value wins over the processor-profile default, which wins over `Unspecified`. (nullable)
    Values:
    - `Unspecified`: No capability declared. The handler emits its current default POS capability fields, preserving existing wire behavior exactly.
    - `MagneticStripe`: Magnetic stripe reader only (implies keyed entry).
    - `MagneticStripeWithPin`: Magnetic stripe reader with PIN pad (implies keyed entry).
    - `Chip`: Contact chip reader (EMV ICC).
    - `ChipWithPin`: Contact chip reader with PIN pad.
    - `ChipContactless`: Contactless chip reader (EMV contactless / NFC).
    - `ChipContactlessWithPin`: Contactless chip reader with PIN pad.
  - `cryptogram` (string): The payment network cryptogram recovered from wallet-token decryption  (the online payment cryptogram for Apple Pay / Google Pay DPAN  transactions). Sensitive: masked from logs. (nullable)
  - `eciIndicator` (string): The Electronic Commerce Indicator (ECI) describing the authentication  context of a tokenized / wallet transaction (e.g. `"05"` for a  3DS-authenticated transaction). Drives the liability-shift indicators  processors include in the network message. (nullable)
  - `isTokenized` (boolean): Indicates the credential is a tokenized account number (DPAN / network  token) rather than a raw PAN. `null` means unknown, which is treated the same as not  tokenized. (nullable)
  - `tokenTransactionId` (string): The provider-specific transaction identifier returned alongside a wallet  token (Apple Pay `transactionIdentifier`, network-token  transaction id). Used for dispute matching against the wallet provider. (nullable)
- `checkData` ([CheckData](https://devportal.demo.winkpg.io/docs/api/models/CheckData.md)): Gets or sets the check data when `paymentMethodType` is Check. Required: When PaymentMethodType == Check. Conditional: When CheckData is not null and PaymentMethodType == Check.
  Fields:
  - `nameOnCheck` (string): The name printed on the check. Required: When IsStoredPayment is not true. (nullable)
  - `routingNumber` (string): The routing number of the bank. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `routingNumberLast4` (string): The last 4 digits of `routingNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `accountNumber` (string): The account number associated with the check. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `accountNumberLast4` (string): The last 4 digits of `accountNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `checkNumber` (string): The check number. (nullable)
  - `micr` (string): The Magnetic Ink Character Recognition (MICR) data. (nullable)
  - `driversLicense` (string): The driver's license number of the check writer. (nullable)
  - `state` (string): The state of issuance for the driver's license. (nullable)
  - `ssn` (string): The Social Security Number of the check writer. (nullable)
  - `dateOfBirth` (string): The date of birth of the check writer. (nullable)
  - `checkType` ([CheckType](https://devportal.demo.winkpg.io/docs/api/models/CheckType.md)): The type of check.
    Values:
    - `Personal`: Represents a personal check. This is typically issued by an individual from their personal account.
    - `Business`: Represents a business check. This is typically issued by a company or organization from their business account.
  - `accountType` ([CheckAccountType](https://devportal.demo.winkpg.io/docs/api/models/CheckAccountType.md)): The type of account associated with the check. Conditional: When IsStoredPayment is not true.
    Values:
    - `Checking`: Represents a checking account.
    - `Savings`: Represents a savings account.
  - `rawMicr` (string): The raw MICR data. (nullable)
  - `branchCity` (string): The city of the bank branch. (nullable)
  - `emailAddress` (string): The email address of the check writer. Conditional: When IsStoredPayment is not true. Must be a valid email. (nullable)
  - `telephoneNumber` (string): The telephone number of the check writer. Conditional: When IsStoredPayment is not true. Pattern: ^[0-9+()\-\s]*$. (nullable)
  - `address` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The address associated with the check.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `secCode` ([SecCode](https://devportal.demo.winkpg.io/docs/api/models/SecCode.md)): The Standard Entry Class (SEC) code for the transaction. (nullable)
    Values:
    - `Ccd`: Corporate Credit or Debit (CCD) - Used for business-to-business transactions.
    - `Ppd`: Prearranged Payment and Deposit (PPD) - Used for consumer transactions.
    - `Web`: Internet-Initiated/Mobile Entry (WEB) - Used for internet or mobile-initiated transactions.
    - `Arc`: Accounts Receivable Conversion (ARC) - Used for converting eligible checks to ACH debits.
    - `Tel`: Telephone-Initiated Entry (TEL) - Used for telephone-initiated transactions.
  - `isStoredPayment` (boolean): When `true`, this check data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  account data from the payment token. (nullable)
- `isDefault` (boolean): Gets or sets whether this should be the customer's default payment method.
- `customName` (string): Gets or sets an optional user-defined display name (e.g., "Marriott Chase"). (nullable)
- `initialSchemeTransactionId` (string): Optional initial (first-in-series) network / scheme transaction id captured from the  authorization response of the cardholder-initiated transaction that stored this credential.  Populated only on the transaction-driven save-card path (the manual Customer admin add has no  authorization response); persisted onto the stored payment method so later charges can echo  it without a consent lookup. Non-sensitive card-network protocol metadata. (nullable)
- `schemeTransactionIdBrand` (string): Optional card brand at capture time (e.g. "Visa") tagged alongside  `initialSchemeTransactionId`. Ignored when the initial id is absent. (nullable)
- `schemeTransactionIdProcessor` (string): Optional originating processor ("tsys" / "fiserv") tagged alongside  `initialSchemeTransactionId`. Ignored when the initial id is absent. (nullable)
- `readerToken` (string): The processor reader token to store for a PAN-less card (a decrypt-and-forward processor such  as MagTek DAF, where the gateway never sees the PAN). When set, this input mints a reader-token  stored method: the token is written encrypted onto the backing vault token's  `ProcessorTokens` and there is no card data to vault. Set by the server only: a value  supplied over the API is not accepted. Never logged. (nullable)
- `readerTokenProcessorName` (string): The processor key ("magtekdaf") the `readerToken` belongs to, used as the  `ProcessorTokens` selection key. Required when `readerToken` is set. Required: When IsReaderTokenBacked is true. (nullable)
- `readerTokenProcessorProfileId` (string(uuid)): The processor profile the `readerToken` was captured under, used as the second part  of the `ProcessorTokens` selection key. Optional. (nullable)
- `readerTokenRequestorId` (string): Optional token-requestor id captured alongside the `readerToken`. Stored on the  backing token's `ProcessorTokens` entry for lineage. Non-sensitive. (nullable)
- `readerTokenMaskedCardNumber` (string): The masked card number of the card the `readerToken` stands in for, in the  platform's masked shape (for example `411111******1111`), read off the approved  authorization. Optional: absent when the processor response carried no card identity.  Display only. It is never a charge credential and never a dedupe input (two distinct reader  tokens can share a last four; `ReaderTokenFingerprint` stays the only matching key).  The consuming services re-mask it before persisting, so a full PAN cannot travel through  this field. Ignored unless `readerToken` is set. (nullable)
- `readerTokenCardBrand` (string): The card brand ("Visa", "Mastercard", ...) resolved for the card behind the  `readerToken`, or `null` when neither the processor response nor  the BIN lookup produced one. Best-effort display metadata; ignored unless  `readerTokenMaskedCardNumber` is set. (nullable)
- `isReaderTokenBacked` (boolean): True when this input describes a reader-token (PAN-less) stored method rather than a  PAN- or account-backed one. In that case `cardData` is absent by design. (read only)

_Example: Add Card_

Adds a credit/debit card to the customer's stored payment methods. Set IsDefault = true to mark this as the customer's default payment method (any prior default is automatically demoted server-side).

```json
{
  "paymentMethodType": "Card",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationDate": "2028-10-22",
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "None",
    "billingAddress": {
      "address1": "456 Oak Ave",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "isDefault": true,
  "customName": "Personal Visa"
}
```

_Example: Add ACH / eCheck_

Adds a US checking or savings account for ACH debits/credits. Routing + account numbers are required; the account is tokenized server-side.

```json
{
  "paymentMethodType": "Check",
  "checkData": {
    "nameOnCheck": "Acme Corp",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkType": "Business",
    "accountType": "Checking"
  },
  "customName": "Operating Account"
}
```

## Responses

### 200

OK

**Content type:** `application/json`

Schema: [`CustomerStoredPaymentMethodDto`](https://devportal.demo.winkpg.io/docs/api/models/CustomerStoredPaymentMethodDto.md)

Properties:
- `extraProperties` (object): (nullable, read only)
- `id` (string(uuid))
- `creationTime` (string(date-time)): The date and time when this entity was created.
- `creatorId` (string(uuid)): The ID of the user who created this entity. (nullable)
- `lastModificationTime` (string(date-time)): The date and time when this entity was last modified. (nullable)
- `lastModifierId` (string(uuid)): The ID of the user who last modified this entity. (nullable)
- `isDeleted` (boolean): Indicates whether this entity has been deleted.
- `deleterId` (string(uuid)): The ID of the user who deleted this entity, if it is deleted. (nullable)
- `deletionTime` (string(date-time)): The date and time when this entity was deleted, if it is deleted. (nullable)
- `tenantId` (string(uuid)): Id of the related tenant. (nullable, read only)
- `concurrencyStamp` (string): Gets or sets the concurrency stamp used for optimistic concurrency control. (nullable)
- `entityVersion` (integer(int32)): A version value that is increased whenever the entity is changed. (read only)
- `paymentMethodType` ([CustomerStoredPaymentMethodType](https://devportal.demo.winkpg.io/docs/api/models/CustomerStoredPaymentMethodType.md)): Gets or sets the type of stored payment method (card, check, etc.).
  Values:
  - `Card`
  - `Check`
- `cardData` ([CardData](https://devportal.demo.winkpg.io/docs/api/models/CardData.md)): Gets or sets the card data when `paymentMethodType` is `Card`.
  Fields:
  - `cardNumber` (string): The card account number. Conditional: When IsStoredPayment is not true. (nullable)
  - `last4CardNumber` (integer(int32)): The last 4 digits of the card number as an integer. (nullable, read only)
  - `expirationMonth` (integer(int32)): The expiration month of the card as an integer in the range `1` to `12`.
  - `expirationYear` (integer(int32)): The expiration year of the card. Either a two-digit year (e.g. `29`) or a  four-digit year (e.g. `2029`); two-digit years resolve to the 2000s.
  - `expirationDate` (string(date-time)): The expiration date of the card. Conditional: When IsStoredPayment is not true. (nullable)
  - `binData` ([BinData](https://devportal.demo.winkpg.io/docs/api/models/BinData.md)): The BIN (Bank Identification Number) data associated with the card.
  - `cvv` (integer(int32)): Deprecated: send `cardVerificationValue` instead. The CVV (Card Verification  Value) of the card as an integer. Conditional: When IsStoredPayment is not true. Range: 100 to 9999. (nullable, deprecated)
  - `cardVerificationValue` (string): The card verification value (CVV, CVC or CID) exactly as printed on the card: three digits,  or four for American Express. Send it as a string so a leading zero is kept. Conditional: When IsStoredPayment is not true. (nullable)
  - `nameOnCard` (string): The name on the card. Conditional: When IsStoredPayment is not true. Max length: 25. (nullable, min length 0, max length 25)
  - `pin` (string): The PIN (Personal Identification Number) of the card. (nullable)
  - `keySerialNumber` (string): The Key Serial Number associated with the card. (nullable)
  - `emvData` (string): The EMV (Europay, Mastercard, and Visa) data associated with the card. (nullable)
  - `trackData` (string): The track data of the card. (nullable)
  - `encryptedTrack1Data` (string): The encrypted track 1 data of the card. (nullable)
  - `encryptedTrack2Data` (string): The encrypted track 2 data of the card. (nullable)
  - `encryptedTrack3Data` (string): The encrypted track 3 data of the card. (nullable)
  - `dynamicCardVerificationData` (string): A reader-generated dynamic card verification value captured at the moment the card was  read. Card readers that support it derive this value from physical characteristics of the  magnetic stripe, which differ between an original card and a copy, so the decryption  service that fronts the processor can score whether the presented card is genuine. (nullable)
  - `dynamicCardVerificationStatus` (string): Status metadata the reader reported alongside  `dynamicCardVerificationData` (for example whether the reader considered the  dynamic verification read successful). Non-secret: it describes the read, it is not the  verification value itself, so it is persisted as submitted. (nullable)
  - `iin` (string): The IIN (Issuer Identification Number) of the card. (nullable)
  - `arqc` (string): The ARQC (Authorization Request Cryptogram) of the card. (nullable)
  - `entryMode` ([EntryModes](https://devportal.demo.winkpg.io/docs/api/models/EntryModes.md)): The entry mode of the card.
    Values:
    - `Unknown`: The entry mode is unknown.
    - `NotApplicable`: The entry mode is not applicable for this transaction.
    - `Manual`: The transaction details were entered manually.
    - `UnencryptedCardReaderSwipe`: The card was swiped through an unencrypted card reader.
    - `EncryptedCardReaderSwipe`: The card was swiped through an encrypted card reader.
    - `Icc`: The transaction was processed using an ICC (Integrated Circuit Card) or chip card.
    - `Proximity`: The transaction was processed using a proximity or contactless payment method.
    - `Fallback`: The transaction was processed using a fallback method when the primary method failed.
    - `TechnicalFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `EmptyCandidateFallback`: The transaction was processed using a fallback method when the primary method failed.
    - `DigitalWallet`: The transaction was processed using a digital wallet.
  - `cvPresence` ([CvPresence](https://devportal.demo.winkpg.io/docs/api/models/CvPresence.md)): The CV (Card Verification) presence status.
    Values:
    - `None`: The CV status is not specified or unknown.
    - `NotSubmitted`: The CV has not been submitted.
    - `Submitted`: The CV has been successfully submitted.
    - `Illegible`: The submitted CV is illegible or cannot be read.
    - `NotPresent`: The CV is not present or missing from the submission.
  - `billingAddress` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The billing address associated with the card.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `phone` (string): The phone number associated with the card. Conditional: When IsStoredPayment is not true. Max length: 15. Pattern: ^[0-9+()\-\s]*$. (nullable, min length 0, max length 15)
  - `email` (string): The email address associated with the card. Conditional: When IsStoredPayment is not true. Must be a valid email. Max length: 50. (nullable, min length 0, max length 50)
  - `hasEmvData` (boolean): Indicates whether EMV data was provided in the original request.  The raw `emvData` value is not stored. (nullable)
  - `hasTrackData` (boolean): Indicates whether track data was provided in the original request.  The raw `trackData` value is not stored. (nullable)
  - `hasEncryptedTrackData` (boolean): Indicates whether any encrypted track data (track 1, 2, or 3) was provided in the original request.  The raw encrypted track values are not stored. (nullable)
  - `hasCvv` (boolean): Indicates whether a CVV was provided in the original request, in either  `cardVerificationValue` or `cvv`. The raw value is not stored. (nullable)
  - `hasPin` (boolean): Indicates whether a PIN was provided in the original request.  The raw `pin` value is not stored. (nullable)
  - `hasDynamicCardVerificationData` (boolean): Indicates whether reader-generated dynamic card verification data was provided in the  original request. The raw `dynamicCardVerificationData` value is not stored. (nullable)
  - `emvAid` (string): (nullable)
  - `isDebitRouting` (boolean): (nullable)
  - `tenderType` ([CardTenderType](https://devportal.demo.winkpg.io/docs/api/models/CardTenderType.md)): The card-rail tender the caller is attempting to use. Drives deterministic  processor routing. `null` (or absent JSON) is treated as  `CreditDebit` for backward compatibility: see  `EffectiveTenderType`. (nullable)
    Values:
    - `CreditDebit`: Standard credit/debit card. The current card-rail behaviour. isDebitRouting modulates whether the request prefers debit-network routing within this rail.
    - `EbtSnap`: EBT SNAP (food benefits). Routes through the EBT SNAP processor lane and requires PIN + card-present per program rules.
    - `EbtCash`: EBT Cash (cash benefits). Distinct rail from SNAP; supports cashback where SNAP does not. PIN + card-present required.
    - `Ewic`: eWIC (Women, Infants, and Children). Distinct rail from EBT, with item-level eligibility / voucher-select flow handled in the eWIC follow-up epic.
  - `isStoredPayment` (boolean): When `true`, this card data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  card data from the payment token. (nullable)
  - `terminalCapability` ([TerminalCapability](https://devportal.demo.winkpg.io/docs/api/models/TerminalCapability.md)): The static hardware capability of the terminal. Selects the POS capability subfields on  the processor wire message. Resolved once in `ProcessorSelectionApplier`: request  value wins over the processor-profile default, which wins over `Unspecified`. (nullable)
    Values:
    - `Unspecified`: No capability declared. The handler emits its current default POS capability fields, preserving existing wire behavior exactly.
    - `MagneticStripe`: Magnetic stripe reader only (implies keyed entry).
    - `MagneticStripeWithPin`: Magnetic stripe reader with PIN pad (implies keyed entry).
    - `Chip`: Contact chip reader (EMV ICC).
    - `ChipWithPin`: Contact chip reader with PIN pad.
    - `ChipContactless`: Contactless chip reader (EMV contactless / NFC).
    - `ChipContactlessWithPin`: Contactless chip reader with PIN pad.
  - `cryptogram` (string): The payment network cryptogram recovered from wallet-token decryption  (the online payment cryptogram for Apple Pay / Google Pay DPAN  transactions). Sensitive: masked from logs. (nullable)
  - `eciIndicator` (string): The Electronic Commerce Indicator (ECI) describing the authentication  context of a tokenized / wallet transaction (e.g. `"05"` for a  3DS-authenticated transaction). Drives the liability-shift indicators  processors include in the network message. (nullable)
  - `isTokenized` (boolean): Indicates the credential is a tokenized account number (DPAN / network  token) rather than a raw PAN. `null` means unknown, which is treated the same as not  tokenized. (nullable)
  - `tokenTransactionId` (string): The provider-specific transaction identifier returned alongside a wallet  token (Apple Pay `transactionIdentifier`, network-token  transaction id). Used for dispute matching against the wallet provider. (nullable)
- `checkData` ([CheckData](https://devportal.demo.winkpg.io/docs/api/models/CheckData.md)): Gets or sets the check/ACH data when `paymentMethodType` is `Check`.
  Fields:
  - `nameOnCheck` (string): The name printed on the check. Required: When IsStoredPayment is not true. (nullable)
  - `routingNumber` (string): The routing number of the bank. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `routingNumberLast4` (string): The last 4 digits of `routingNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `accountNumber` (string): The account number associated with the check. Required: When IsStoredPayment is not true. Conditional: When IsStoredPayment is true. (nullable)
  - `accountNumberLast4` (string): The last 4 digits of `accountNumber` as a string, preserving leading zeros, or  `null` when no digits are available. (nullable, read only)
  - `checkNumber` (string): The check number. (nullable)
  - `micr` (string): The Magnetic Ink Character Recognition (MICR) data. (nullable)
  - `driversLicense` (string): The driver's license number of the check writer. (nullable)
  - `state` (string): The state of issuance for the driver's license. (nullable)
  - `ssn` (string): The Social Security Number of the check writer. (nullable)
  - `dateOfBirth` (string): The date of birth of the check writer. (nullable)
  - `checkType` ([CheckType](https://devportal.demo.winkpg.io/docs/api/models/CheckType.md)): The type of check.
    Values:
    - `Personal`: Represents a personal check. This is typically issued by an individual from their personal account.
    - `Business`: Represents a business check. This is typically issued by a company or organization from their business account.
  - `accountType` ([CheckAccountType](https://devportal.demo.winkpg.io/docs/api/models/CheckAccountType.md)): The type of account associated with the check. Conditional: When IsStoredPayment is not true.
    Values:
    - `Checking`: Represents a checking account.
    - `Savings`: Represents a savings account.
  - `rawMicr` (string): The raw MICR data. (nullable)
  - `branchCity` (string): The city of the bank branch. (nullable)
  - `emailAddress` (string): The email address of the check writer. Conditional: When IsStoredPayment is not true. Must be a valid email. (nullable)
  - `telephoneNumber` (string): The telephone number of the check writer. Conditional: When IsStoredPayment is not true. Pattern: ^[0-9+()\-\s]*$. (nullable)
  - `address` ([Address](https://devportal.demo.winkpg.io/docs/api/models/Address.md)): The address associated with the check.  Optional by default (no nested validation enforced). Conditional: When IsStoredPayment is not true.
  - `secCode` ([SecCode](https://devportal.demo.winkpg.io/docs/api/models/SecCode.md)): The Standard Entry Class (SEC) code for the transaction. (nullable)
    Values:
    - `Ccd`: Corporate Credit or Debit (CCD) - Used for business-to-business transactions.
    - `Ppd`: Prearranged Payment and Deposit (PPD) - Used for consumer transactions.
    - `Web`: Internet-Initiated/Mobile Entry (WEB) - Used for internet or mobile-initiated transactions.
    - `Arc`: Accounts Receivable Conversion (ARC) - Used for converting eligible checks to ACH debits.
    - `Tel`: Telephone-Initiated Entry (TEL) - Used for telephone-initiated transactions.
  - `isStoredPayment` (boolean): When `true`, this check data originates from a stored payment method and  client-side field validation is not applicable. The server resolves actual  account data from the payment token. (nullable)
- `isDefault` (boolean): Gets or sets a value indicating whether this is the customer's default payment method.
- `displayName` (string): Gets the human-readable display name for this payment method. When `customName`  is set, it takes priority over the computed brand + last-4 fallback. (nullable, read only)
- `customName` (string): Gets or sets an optional user-defined name for this payment method  (e.g., "Marriott Chase", "Bank of America Checkcard"). (nullable)
- `paymentTokenId` (string(uuid)): Gets or sets the identifier of the `PaymentToken` document that stores  the encrypted card/check data for this stored payment method. (nullable)
- `publicReference` (string): Gets or sets the chargeable public reference (the opaque `pt_`-prefixed handle) of the  backing `PaymentToken`. (nullable)
- `origin` ([StoredPaymentMethodOrigin](https://devportal.demo.winkpg.io/docs/api/models/StoredPaymentMethodOrigin.md)): Gets or sets the surface / add-channel this stored payment method was captured through  (manual admin, hosted payment page, virtual terminal, or API). Null when the method predates  this field, which callers treat as `Unknown`.  Non-sensitive add-channel metadata. (nullable)
  Values:
  - `Unknown`: The add-channel was not recorded. Assigned to methods that predate this field (materialized from a null value) and to any path that did not classify its origin.
  - `ManualAdmin`: Added by an operator through a Customer admin surface that mints the stored method on the customer document directly (the customer edit form's payment-methods dialog, and the create-customer / create-contract-from-transaction dialogs). Note: the contract add-payment dialog submits through the HTTP add endpoint and is therefore recorded as Api, since origin on that boundary is server-authoritative and cannot be caller-supplied.
  - `HostedPaymentPage`: Vaulted from a hosted payment page: either tokenize-on-payment or the direct ACH vault flow.
  - `VirtualTerminal`: Vaulted from a Virtual Terminal save-on-payment.
  - `Api`: Added through the HTTP add-stored-payment-method endpoint. Covers external API token registration and any in-process operator surface that submits through that same gated endpoint (e.g. the contract add-payment dialog): origin on this boundary is stamped server-side and is never caller-supplied.
- `isReaderTokenBacked` (boolean): Gets or sets whether this stored method is backed by a processor card token rather than a  stored card number: the card was captured by a card reader on a decrypt-and-forward processor,  so the platform never held its number and the method carries no expiration date. Such a method  is charged through its `publicReference` exactly like any other, but only on the  processor that issued the token. `false` for every card-number-backed card and  every bank account method.

### 403

Forbidden

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

### 401

Unauthorized

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

### 400

Bad Request

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

_Example: Request failed validation_

One or more fields were rejected before any rule ran. error.code is null on the envelope and the causes are in validationErrors, one entry per failure. An entry carries code when the validator declared a publishable one, and memberPaths when the full path says more than members does (an element inside a collection, for example). Both keys are omitted when they would add nothing.

```json
{
  "error": {
    "code": "null",
    "message": "Your request is not valid!",
    "details": "The following errors were detected during validation.",
    "data": {
      "correlationId": "0123456789abcdef0123456789abcdef"
    },
    "validationErrors": [
      {
        "message": "'Amount' must be greater than 0.",
        "members": [
          "amount"
        ]
      },
      {
        "message": "The card has expired.",
        "members": [
          "expirationDate"
        ],
        "code": "CardData:CardExpired"
      },
      {
        "message": "'Value' must not be empty.",
        "members": [
          "value"
        ],
        "memberPaths": [
          "customFields[2].value"
        ]
      }
    ]
  }
}
```

### 404

Not Found

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

_Example: Resource not found_

The id in the path names no record the caller can see. Most resources answer with a null error.code and a message naming the resource type and the id; a resource that publishes a not-found code in the catalog above carries it in error.code instead, so check for one before matching on the message.

```json
{
  "error": {
    "code": "null",
    "message": "There is no entity Transaction with id = 7d1f3a52-0c4e-4b8a-9e21-5a6b7c8d9e00!",
    "details": "null",
    "data": {
      "correlationId": "0123456789abcdef0123456789abcdef"
    },
    "validationErrors": "null"
  }
}
```

### 501

Not Implemented

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

### 500

Internal Server Error

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

### default

The request failed. The body carries the standard error envelope: a machine-readable `error.code`, a human-readable `error.message`, and `error.validationErrors` when the failure was a validation rejection. The [error reference](https://devportal.demo.winkpg.io/docs/errors.md) lists the values `error.code` can take.

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

_Example: Business rule refused the request_

The request was understood and rejected by a platform rule. This is the shape that carries a code from the catalog above, so branch on error.code rather than on the message text. The HTTP status is the one listed against the code.

```json
{
  "error": {
    "code": "Transactions:OperationNotAllowed",
    "message": "The operation 'Void' is not allowed on a Sale transaction with result 'Approved' and settlement state 'Settled'.",
    "details": "null",
    "data": {
      "correlationId": "0123456789abcdef0123456789abcdef"
    },
    "validationErrors": "null"
  }
}
```

### 429

The request was refused because a rate limit was exceeded, or because something a later retry can clear stopped it. A rate limit refusal carries an `application/problem+json` body: wait at least the interval `Retry-After` names before retrying, then back off. Limits are tuned per deployment, so read the allowance from the response headers rather than assuming a fixed ceiling. Any other refusal carries the standard error envelope as `application/json`, and its `error.code` names the cause.

**Content type:** `application/problem+json`

Schema: [`RateLimitProblemDetails`](https://devportal.demo.winkpg.io/docs/api/models/RateLimitProblemDetails.md)

Properties:
- `type` (string) required: The problem type identifier. Always the same value: the failure is the status code itself,  so there is no sub-type for a caller to branch on. (nullable)
- `title` (string) required: A short, human-readable summary of the problem type. (nullable)
- `status` (integer(int32)) required: The HTTP status code, repeated in the body as the problem-details format defines.
- `detail` (string) required: A human-readable explanation of this occurrence of the problem. (nullable)
- `retryAfterSeconds` (integer(int32)) required: How long to wait before retrying, in whole seconds, carrying the same figure as the  `Retry-After` header. Always at least one: a value of zero would invite an immediate  retry that is certain to be rejected again.

**Content type:** `application/json`

Schema: [`RemoteServiceErrorResponse`](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorResponse.md)

Properties:
- `error` ([RemoteServiceErrorInfo](https://devportal.demo.winkpg.io/docs/api/models/RemoteServiceErrorInfo.md))

## Example request

Every block below sends the same request. Replace {{BASE_URL}} with the address of the API you are calling and {{API_KEY}} with your own key.

The request body is a AddStoredPaymentMethodInput. See the Request body section below for its fields.

These blocks send the Add Card example. The other examples follow under Other request examples.

Adds a credit/debit card to the customer's stored payment methods. Set IsDefault = true to mark this as the customer's default payment method (any prior default is automatically demoted server-side).

### cURL

```bash
curl -X POST "{{BASE_URL}}/api/customers/add-stored-payment-method-async" \
  -H "api-key: {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
  "paymentMethodType": "Card",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationDate": "2028-10-22",
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "None",
    "billingAddress": {
      "address1": "456 Oak Ave",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "isDefault": true,
  "customName": "Personal Visa"
}'
```

### PowerShell

```powershell
$headers = @{
    'api-key' = '{{API_KEY}}'
}

$body = @'
{
  "paymentMethodType": "Card",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationDate": "2028-10-22",
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "None",
    "billingAddress": {
      "address1": "456 Oak Ave",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "isDefault": true,
  "customName": "Personal Visa"
}
'@

$response = Invoke-RestMethod -Method POST -Uri '{{BASE_URL}}/api/customers/add-stored-payment-method-async' `
    -Headers $headers -ContentType 'application/json' -Body $body
```

### TypeScript (SDK)

```bash
npm install @winkpg/winkpg-api
```

```typescript
import { Configuration, CustomersApi } from '@winkpg/winkpg-api';

const api = new CustomersApi(new Configuration({
  basePath: '{{BASE_URL}}',
  apiKey: '{{API_KEY}}',
}));

const { data } = await api.customersAddStoredPaymentMethod({
  "paymentMethodType": "Card",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationDate": "2028-10-22",
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "None",
    "billingAddress": {
      "address1": "456 Oak Ave",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "isDefault": true,
  "customName": "Personal Visa"
});
```

### TypeScript (raw HTTP)

```typescript
const response = await fetch('{{BASE_URL}}/api/customers/add-stored-payment-method-async', {
  method: 'POST',
  headers: {
    "api-key": "{{API_KEY}}",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "paymentMethodType": "Card",
    "cardData": {
      "cardNumber": "4111111111111111",
      "expirationDate": "2028-10-22",
      "cardVerificationValue": "123",
      "nameOnCard": "Jane Smith",
      "entryMode": "Manual",
      "cvPresence": "None",
      "billingAddress": {
        "address1": "456 Oak Ave",
        "city": "Reno",
        "state": "NV",
        "zip": "89501",
        "country": "USA"
      }
    },
    "isDefault": true,
    "customName": "Personal Visa"
  }),
});

const data = await response.json();
```

### C# (SDK)

```bash
dotnet add package WinkPg.Api.Client
```

```csharp
using WinkPg.Api.Client.Api;
using WinkPg.Api.Client.Client;
using System.Text.Json;

var config = new Configuration { BasePath = "{{BASE_URL}}" };
config.AddApiKey("api-key", "{{API_KEY}}");

var api = new CustomersApi(config);
var body = JsonSerializer.Deserialize<AddStoredPaymentMethodInput>("""
    {
      "paymentMethodType": "Card",
      "cardData": {
        "cardNumber": "4111111111111111",
        "expirationDate": "2028-10-22",
        "cardVerificationValue": "123",
        "nameOnCard": "Jane Smith",
        "entryMode": "Manual",
        "cvPresence": "None",
        "billingAddress": {
          "address1": "456 Oak Ave",
          "city": "Reno",
          "state": "NV",
          "zip": "89501",
          "country": "USA"
        }
      },
      "isDefault": true,
      "customName": "Personal Visa"
    }
    """);

var result = await api.CustomersAddStoredPaymentMethodAsync(body);
```

### C# (raw HTTP)

```csharp
using System.Text;

using var http = new HttpClient { BaseAddress = new Uri("{{BASE_URL}}") };

var request = new HttpRequestMessage(new HttpMethod("POST"), "/api/customers/add-stored-payment-method-async");
request.Headers.Add("api-key", "{{API_KEY}}");

request.Content = new StringContent("""
    {
      "paymentMethodType": "Card",
      "cardData": {
        "cardNumber": "4111111111111111",
        "expirationDate": "2028-10-22",
        "cardVerificationValue": "123",
        "nameOnCard": "Jane Smith",
        "entryMode": "Manual",
        "cvPresence": "None",
        "billingAddress": {
          "address1": "456 Oak Ave",
          "city": "Reno",
          "state": "NV",
          "zip": "89501",
          "country": "USA"
        }
      },
      "isDefault": true,
      "customName": "Personal Visa"
    }
    """, Encoding.UTF8, "application/json");

var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
```

### Python (SDK)

```bash
pip install winkpg-api
```

```python
import winkpg_api

configuration = winkpg_api.Configuration(host="{{BASE_URL}}")
configuration.api_key["ApiKey"] = "{{API_KEY}}"

with winkpg_api.ApiClient(configuration) as client:
    api = winkpg_api.CustomersApi(client)
    body = winkpg_api.AddStoredPaymentMethodInput.from_dict({
      "paymentMethodType": "Card",
      "cardData": {
        "cardNumber": "4111111111111111",
        "expirationDate": "2028-10-22",
        "cardVerificationValue": "123",
        "nameOnCard": "Jane Smith",
        "entryMode": "Manual",
        "cvPresence": "None",
        "billingAddress": {
          "address1": "456 Oak Ave",
          "city": "Reno",
          "state": "NV",
          "zip": "89501",
          "country": "USA"
        }
      },
      "isDefault": True,
      "customName": "Personal Visa"
    })
    result = api.customers_add_stored_payment_method(body)
```

### Python (raw HTTP)

```bash
pip install requests
```

```python
import requests

headers = {
    "api-key": "{{API_KEY}}",
    "Content-Type": "application/json",
}

body = {
  "paymentMethodType": "Card",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationDate": "2028-10-22",
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "None",
    "billingAddress": {
      "address1": "456 Oak Ave",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "isDefault": True,
  "customName": "Personal Visa"
}

response = requests.request(
    "POST",
    "{{BASE_URL}}/api/customers/add-stored-payment-method-async",
    headers=headers,
    json=body,
)
response.raise_for_status()
data = response.json()
```

## Other request examples

Each example below is one request, shown in every language with the same placeholders.

### Add ACH / eCheck

Adds a US checking or savings account for ACH debits/credits. Routing + account numbers are required; the account is tokenized server-side.

#### cURL

```bash
curl -X POST "{{BASE_URL}}/api/customers/add-stored-payment-method-async" \
  -H "api-key: {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
  "paymentMethodType": "Check",
  "checkData": {
    "nameOnCheck": "Acme Corp",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkType": "Business",
    "accountType": "Checking"
  },
  "customName": "Operating Account"
}'
```

#### PowerShell

```powershell
$headers = @{
    'api-key' = '{{API_KEY}}'
}

$body = @'
{
  "paymentMethodType": "Check",
  "checkData": {
    "nameOnCheck": "Acme Corp",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkType": "Business",
    "accountType": "Checking"
  },
  "customName": "Operating Account"
}
'@

$response = Invoke-RestMethod -Method POST -Uri '{{BASE_URL}}/api/customers/add-stored-payment-method-async' `
    -Headers $headers -ContentType 'application/json' -Body $body
```

#### TypeScript (SDK)

```bash
npm install @winkpg/winkpg-api
```

```typescript
import { Configuration, CustomersApi } from '@winkpg/winkpg-api';

const api = new CustomersApi(new Configuration({
  basePath: '{{BASE_URL}}',
  apiKey: '{{API_KEY}}',
}));

const { data } = await api.customersAddStoredPaymentMethod({
  "paymentMethodType": "Check",
  "checkData": {
    "nameOnCheck": "Acme Corp",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkType": "Business",
    "accountType": "Checking"
  },
  "customName": "Operating Account"
});
```

#### TypeScript (raw HTTP)

```typescript
const response = await fetch('{{BASE_URL}}/api/customers/add-stored-payment-method-async', {
  method: 'POST',
  headers: {
    "api-key": "{{API_KEY}}",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "paymentMethodType": "Check",
    "checkData": {
      "nameOnCheck": "Acme Corp",
      "routingNumber": "021000021",
      "accountNumber": "123456789",
      "checkType": "Business",
      "accountType": "Checking"
    },
    "customName": "Operating Account"
  }),
});

const data = await response.json();
```

#### C# (SDK)

```bash
dotnet add package WinkPg.Api.Client
```

```csharp
using WinkPg.Api.Client.Api;
using WinkPg.Api.Client.Client;
using System.Text.Json;

var config = new Configuration { BasePath = "{{BASE_URL}}" };
config.AddApiKey("api-key", "{{API_KEY}}");

var api = new CustomersApi(config);
var body = JsonSerializer.Deserialize<AddStoredPaymentMethodInput>("""
    {
      "paymentMethodType": "Check",
      "checkData": {
        "nameOnCheck": "Acme Corp",
        "routingNumber": "021000021",
        "accountNumber": "123456789",
        "checkType": "Business",
        "accountType": "Checking"
      },
      "customName": "Operating Account"
    }
    """);

var result = await api.CustomersAddStoredPaymentMethodAsync(body);
```

#### C# (raw HTTP)

```csharp
using System.Text;

using var http = new HttpClient { BaseAddress = new Uri("{{BASE_URL}}") };

var request = new HttpRequestMessage(new HttpMethod("POST"), "/api/customers/add-stored-payment-method-async");
request.Headers.Add("api-key", "{{API_KEY}}");

request.Content = new StringContent("""
    {
      "paymentMethodType": "Check",
      "checkData": {
        "nameOnCheck": "Acme Corp",
        "routingNumber": "021000021",
        "accountNumber": "123456789",
        "checkType": "Business",
        "accountType": "Checking"
      },
      "customName": "Operating Account"
    }
    """, Encoding.UTF8, "application/json");

var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
```

#### Python (SDK)

```bash
pip install winkpg-api
```

```python
import winkpg_api

configuration = winkpg_api.Configuration(host="{{BASE_URL}}")
configuration.api_key["ApiKey"] = "{{API_KEY}}"

with winkpg_api.ApiClient(configuration) as client:
    api = winkpg_api.CustomersApi(client)
    body = winkpg_api.AddStoredPaymentMethodInput.from_dict({
      "paymentMethodType": "Check",
      "checkData": {
        "nameOnCheck": "Acme Corp",
        "routingNumber": "021000021",
        "accountNumber": "123456789",
        "checkType": "Business",
        "accountType": "Checking"
      },
      "customName": "Operating Account"
    })
    result = api.customers_add_stored_payment_method(body)
```

#### Python (raw HTTP)

```bash
pip install requests
```

```python
import requests

headers = {
    "api-key": "{{API_KEY}}",
    "Content-Type": "application/json",
}

body = {
  "paymentMethodType": "Check",
  "checkData": {
    "nameOnCheck": "Acme Corp",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkType": "Business",
    "accountType": "Checking"
  },
  "customName": "Operating Account"
}

response = requests.request(
    "POST",
    "{{BASE_URL}}/api/customers/add-stored-payment-method-async",
    headers=headers,
    json=body,
)
response.raise_for_status()
data = response.json()
```

## See also

- [All documentation](https://devportal.demo.winkpg.io/llms.txt): the machine-readable index of every public page on this site.
