From 1282d044ec870d06edc5d2f820e2576c936e3b1e Mon Sep 17 00:00:00 2001 From: BlockChyp SDK Builder Date: Wed, 18 Sep 2024 15:38:11 +0000 Subject: [PATCH] Merge pull request #278 from blockchyp/feature/CHYP-3573 Card Metadata and HSA/EBT --- README.md | 47 ++++ src/BlockChyp/Client/BlockChypClient.cs | 43 ++++ .../Entities/AuthorizationRequest.cs | 28 ++- .../Entities/AuthorizationResponse.cs | 6 + src/BlockChyp/Entities/CardMetaData.cs | 88 ++++++++ src/BlockChyp/Entities/CardMetadataRequest.cs | 208 ++++++++++++++++++ .../Entities/CardMetadataResponse.cs | 134 +++++++++++ src/BlockChyp/Entities/EnrollRequest.cs | 6 + src/BlockChyp/Entities/EnrollResponse.cs | 6 + src/BlockChyp/Entities/HealthcareMetadata.cs | 36 +++ src/BlockChyp/Entities/RefundRequest.cs | 10 +- .../Entities/TokenMetadataResponse.cs | 6 + 12 files changed, 614 insertions(+), 4 deletions(-) create mode 100644 src/BlockChyp/Entities/CardMetaData.cs create mode 100644 src/BlockChyp/Entities/CardMetadataRequest.cs create mode 100644 src/BlockChyp/Entities/CardMetadataResponse.cs create mode 100644 src/BlockChyp/Entities/HealthcareMetadata.cs diff --git a/README.md b/README.md index 9c22a1a..b84711f 100644 --- a/README.md +++ b/README.md @@ -354,6 +354,53 @@ Console.WriteLine(response); ``` +#### Card Metadata + + + +* **API Credential Types:** Merchant +* **Required Role:** Payment API Access + +This API allows you to retrieve card metadata. + +Card metadata requests can use a payment terminal to retrieve metadata or +use a previously enrolled payment token. + +**Terminal Transactions** + +For terminal transactions, make sure you pass in the terminal name using the `terminalName` property. + +**Token Transactions** + +If you have a payment token, omit the `terminalName` property and pass in the token with the `token` +property instead. + +**Card Numbers and Mag Stripes** + +You can also pass in PANs and Mag Stripes, but you probably shouldn't, as this will +put you in PCI scope and the most common vector for POS breaches is keylogging. +If you use terminals for manual card entry, you'll bypass any keyloggers that +might be maliciously running on the point-of-sale system. + + + + +```c# +// Populate request parameters. +CardMetadataRequest request = new CardMetadataRequest +{ + Test = true, + TerminalName = "Test Terminal", +}; + +// Run the transaction. +CardMetadataResponse response = await blockchyp.CardMetadataAsync(request); + +// View the result. +Console.WriteLine(response); + +``` + #### Time Out Reversal diff --git a/src/BlockChyp/Client/BlockChypClient.cs b/src/BlockChyp/Client/BlockChypClient.cs index 739aa1a..d8f8f9c 100644 --- a/src/BlockChyp/Client/BlockChypClient.cs +++ b/src/BlockChyp/Client/BlockChypClient.cs @@ -351,6 +351,49 @@ public EnrollResponse Enroll(EnrollRequest request) .ConfigureAwait(false).GetAwaiter().GetResult(); } + /// + /// Retrieves card metadata. + /// + /// The request details. + public async Task CardMetadataAsync(CardMetadataRequest request) + { + ISignatureRequest signatureRequest = request as ISignatureRequest; + if (signatureRequest != null) + { + PopulateSignatureOptions(signatureRequest); + } + + CardMetadataResponse response; + if (await IsTerminalRouted(request.TerminalName).ConfigureAwait(false)) + { + response = await TerminalRequestAsync(HttpMethod.Post, "/api/card-metadata", request.TerminalName, request) + .ConfigureAwait(false); + } + else + { + response = await GatewayRequestAsync(HttpMethod.Post, "/api/card-metadata", request, null, request.Test, relay: true) + .ConfigureAwait(false); + } + + ISignatureResponse signatureResponse = response as ISignatureResponse; + if (signatureRequest != null && signatureResponse != null) + { + DumpSignatureFile(signatureRequest, signatureResponse); + } + + return response; + } + + /// + /// Synchronous form of . + /// + /// The request details. + public CardMetadataResponse CardMetadata(CardMetadataRequest request) + { + return CardMetadataAsync(request) + .ConfigureAwait(false).GetAwaiter().GetResult(); + } + /// /// Activates or recharges a gift card. /// diff --git a/src/BlockChyp/Entities/AuthorizationRequest.cs b/src/BlockChyp/Entities/AuthorizationRequest.cs index 67b7e88..1b47c1f 100644 --- a/src/BlockChyp/Entities/AuthorizationRequest.cs +++ b/src/BlockChyp/Entities/AuthorizationRequest.cs @@ -389,8 +389,8 @@ public class AuthorizationRequest : BaseEntity, ITimeoutRequest, ICoreRequest, I /// /// Details for HSA/FSA transactions. /// - [JsonProperty(PropertyName = "healthcare")] - public Healthcare Healthcare { get; set; } + [JsonProperty(PropertyName = "healthcareMetadata")] + public HealthcareMetadata HealthcareMetadata { get; set; } /// /// That the transaction should be a cryptocurrency transaction. Value should be a @@ -455,5 +455,29 @@ public class AuthorizationRequest : BaseEntity, ITimeoutRequest, ICoreRequest, I /// [JsonProperty(PropertyName = "passthroughSurcharge")] public string PassthroughSurcharge { get; set; } + + /// + /// Marks a transaction as HSA/FSA. + /// + [JsonProperty(PropertyName = "healthcare")] + public bool Healthcare { get; set; } + + /// + /// The total amount to process as healthcare. + /// + [JsonProperty(PropertyName = "healthcareTotal")] + public string HealthcareTotal { get; set; } + + /// + /// The total amount to process as ebt. + /// + [JsonProperty(PropertyName = "ebtTotal")] + public string EbtTotal { get; set; } + + /// + /// That this transaction will include a card metadata lookup. + /// + [JsonProperty(PropertyName = "cardMetadataLookup")] + public bool CardMetadataLookup { get; set; } } } diff --git a/src/BlockChyp/Entities/AuthorizationResponse.cs b/src/BlockChyp/Entities/AuthorizationResponse.cs index e59d389..6abb757 100644 --- a/src/BlockChyp/Entities/AuthorizationResponse.cs +++ b/src/BlockChyp/Entities/AuthorizationResponse.cs @@ -360,5 +360,11 @@ public class AuthorizationResponse : BaseEntity, IAbstractAcknowledgement, IAppr /// [JsonProperty(PropertyName = "status")] public string Status { get; set; } + + /// + /// Details about a payment card derived from its BIN/IIN. + /// + [JsonProperty(PropertyName = "cardMetadata")] + public CardMetadata CardMetadata { get; set; } } } diff --git a/src/BlockChyp/Entities/CardMetaData.cs b/src/BlockChyp/Entities/CardMetaData.cs new file mode 100644 index 0000000..b4ac070 --- /dev/null +++ b/src/BlockChyp/Entities/CardMetaData.cs @@ -0,0 +1,88 @@ +// Copyright 2019-2024 BlockChyp, Inc. All rights reserved. Use of this code is +// governed by a license that can be found in the LICENSE file. +// +// This file was generated automatically by the BlockChyp SDK Generator. Changes +// to this file will be lost every time the code is regenerated. + +using Newtonsoft.Json; + +namespace BlockChyp.Entities +{ + /// + /// Essential information about a payment card derived from its BIN/IIN. + /// + public class CardMetadata : BaseEntity + { + /// + /// The brand or network of the card (e.g., Visa, Mastercard, Amex). + /// + [JsonProperty(PropertyName = "cardBrand")] + public string CardBrand { get; set; } + + /// + /// The name of the financial institution that issued the card. + /// + [JsonProperty(PropertyName = "issuerName")] + public string IssuerName { get; set; } + + /// + /// Whether the card supports Level 3 processing for detailed transaction data. + /// + [JsonProperty(PropertyName = "l3")] + public bool L3 { get; set; } + + /// + /// Whether the card supports Level 2 processing for additional transaction data. + /// + [JsonProperty(PropertyName = "l2")] + public bool L2 { get; set; } + + /// + /// The general category or type of the card product. + /// + [JsonProperty(PropertyName = "productType")] + public string ProductType { get; set; } + + /// + /// The specific name or designation of the card product. + /// + [JsonProperty(PropertyName = "productName")] + public string ProductName { get; set; } + + /// + /// Whether the card is an Electronic Benefit Transfer (EBT) card. + /// + [JsonProperty(PropertyName = "ebt")] + public bool Ebt { get; set; } + + /// + /// Whether the card is a debit card. + /// + [JsonProperty(PropertyName = "debit")] + public bool Debit { get; set; } + + /// + /// Whether the card is a healthcare-specific payment card. + /// + [JsonProperty(PropertyName = "healthcare")] + public bool Healthcare { get; set; } + + /// + /// Whether the card is a prepaid card. + /// + [JsonProperty(PropertyName = "prepaid")] + public bool Prepaid { get; set; } + + /// + /// The geographical region associated with the card's issuer. + /// + [JsonProperty(PropertyName = "region")] + public string Region { get; set; } + + /// + /// The country associated with the card's issuer. + /// + [JsonProperty(PropertyName = "country")] + public string Country { get; set; } + } +} diff --git a/src/BlockChyp/Entities/CardMetadataRequest.cs b/src/BlockChyp/Entities/CardMetadataRequest.cs new file mode 100644 index 0000000..7e88a38 --- /dev/null +++ b/src/BlockChyp/Entities/CardMetadataRequest.cs @@ -0,0 +1,208 @@ +// Copyright 2019-2024 BlockChyp, Inc. All rights reserved. Use of this code is +// governed by a license that can be found in the LICENSE file. +// +// This file was generated automatically by the BlockChyp SDK Generator. Changes +// to this file will be lost every time the code is regenerated. + +using Newtonsoft.Json; + +namespace BlockChyp.Entities +{ + /// + /// Retrieves card metadata. + /// + public class CardMetadataRequest : BaseEntity, ITimeoutRequest, ICoreRequest, IPaymentMethod, ITerminalReference + { + /// + /// The request timeout in seconds. + /// + [JsonProperty(PropertyName = "timeout")] + public int Timeout { get; set; } + + /// + /// Whether or not to route transaction to the test gateway. + /// + [JsonProperty(PropertyName = "test")] + public bool Test { get; set; } + + /// + /// A user-assigned reference that can be used to recall or reverse transactions. + /// + [JsonProperty(PropertyName = "transactionRef")] + public string TransactionRef { get; set; } + + /// + /// That the transaction reference was autogenerated and should be ignored for the + /// purposes of duplicate detection. + /// + [JsonProperty(PropertyName = "autogeneratedRef")] + public bool AutogeneratedRef { get; set; } + + /// + /// Defers the response to the transaction and returns immediately. Callers + /// should retrive the transaction result using the Transaction Status API. + /// + [JsonProperty(PropertyName = "async")] + public bool Async { get; set; } + + /// + /// Adds the transaction to the queue and returns immediately. Callers should + /// retrive the transaction result using the Transaction Status API. + /// + [JsonProperty(PropertyName = "queue")] + public bool Queue { get; set; } + + /// + /// Whether or not the request should block until all cards have been removed from + /// the card reader. + /// + [JsonProperty(PropertyName = "waitForRemovedCard")] + public bool WaitForRemovedCard { get; set; } + + /// + /// Override any in-progress transactions. + /// + [JsonProperty(PropertyName = "force")] + public bool Force { get; set; } + + /// + /// An identifier from an external point of sale system. + /// + [JsonProperty(PropertyName = "orderRef")] + public string OrderRef { get; set; } + + /// + /// The settlement account for merchants with split settlements. + /// + [JsonProperty(PropertyName = "destinationAccount")] + public string DestinationAccount { get; set; } + + /// + /// Can include a code used to trigger simulated conditions for the purposes of + /// testing and certification. Valid for test merchant accounts only. + /// + [JsonProperty(PropertyName = "testCase")] + public string TestCase { get; set; } + + /// + /// The payment token to be used for this transaction. This should be used for + /// recurring transactions. + /// + [JsonProperty(PropertyName = "token")] + public string Token { get; set; } + + /// + /// Track 1 magnetic stripe data. + /// + [JsonProperty(PropertyName = "track1")] + public string Track1 { get; set; } + + /// + /// Track 2 magnetic stripe data. + /// + [JsonProperty(PropertyName = "track2")] + public string Track2 { get; set; } + + /// + /// The primary account number. We recommend using the terminal or e-commerce + /// tokenization libraries instead of passing account numbers in directly, as + /// this would put your application in PCI scope. + /// + [JsonProperty(PropertyName = "pan")] + public string Pan { get; set; } + + /// + /// The ACH routing number for ACH transactions. + /// + [JsonProperty(PropertyName = "routingNumber")] + public string RoutingNumber { get; set; } + + /// + /// The cardholder name. Only required if the request includes a primary account + /// number or track data. + /// + [JsonProperty(PropertyName = "cardholderName")] + public string CardholderName { get; set; } + + /// + /// The card expiration month for use with PAN based transactions. + /// + [JsonProperty(PropertyName = "expMonth")] + public string ExpMonth { get; set; } + + /// + /// The card expiration year for use with PAN based transactions. + /// + [JsonProperty(PropertyName = "expYear")] + public string ExpYear { get; set; } + + /// + /// The card CVV for use with PAN based transactions. + /// + [JsonProperty(PropertyName = "cvv")] + public string Cvv { get; set; } + + /// + /// The cardholder address for use with address verification. + /// + [JsonProperty(PropertyName = "address")] + public string Address { get; set; } + + /// + /// The cardholder postal code for use with address verification. + /// + [JsonProperty(PropertyName = "postalCode")] + public string PostalCode { get; set; } + + /// + /// That the payment entry method is a manual keyed transaction. If this is true, no + /// other payment method will be accepted. + /// + [JsonProperty(PropertyName = "manualEntry")] + public bool ManualEntry { get; set; } + + /// + /// The key serial number used for DUKPT encryption. + /// + [JsonProperty(PropertyName = "ksn")] + public string Ksn { get; set; } + + /// + /// The encrypted pin block. + /// + [JsonProperty(PropertyName = "pinBlock")] + public string PinBlock { get; set; } + + /// + /// Designates categories of cards: credit, debit, EBT. + /// + [JsonProperty(PropertyName = "cardType")] + public CardType CardType { get; set; } + + /// + /// Designates brands of payment methods: Visa, Discover, etc. + /// + [JsonProperty(PropertyName = "paymentType")] + public string PaymentType { get; set; } + + /// + /// The name of the target payment terminal. + /// + [JsonProperty(PropertyName = "terminalName")] + public string TerminalName { get; set; } + + /// + /// Forces the terminal cloud connection to be reset while a transactions is in + /// flight. This is a diagnostic settings that can be used only for test + /// transactions. + /// + [JsonProperty(PropertyName = "resetConnection")] + public bool ResetConnection { get; set; } + + /// + /// Marks a transaction as HSA/FSA. + /// + [JsonProperty(PropertyName = "healthcare")] + public bool Healthcare { get; set; } + } +} diff --git a/src/BlockChyp/Entities/CardMetadataResponse.cs b/src/BlockChyp/Entities/CardMetadataResponse.cs new file mode 100644 index 0000000..6119475 --- /dev/null +++ b/src/BlockChyp/Entities/CardMetadataResponse.cs @@ -0,0 +1,134 @@ +// Copyright 2019-2024 BlockChyp, Inc. All rights reserved. Use of this code is +// governed by a license that can be found in the LICENSE file. +// +// This file was generated automatically by the BlockChyp SDK Generator. Changes +// to this file will be lost every time the code is regenerated. + +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace BlockChyp.Entities +{ + /// + /// The response to a card metadata request. + /// + public class CardMetadataResponse : BaseEntity, IAbstractAcknowledgement, IPaymentMethodResponse + { + /// + /// Whether or not the request succeeded. + /// + [JsonProperty(PropertyName = "success")] + public bool Success { get; set; } + + /// + /// The error, if an error occurred. + /// + [JsonProperty(PropertyName = "error")] + public string Error { get; set; } + + /// + /// A narrative description of the transaction result. + /// + [JsonProperty(PropertyName = "responseDescription")] + public string ResponseDescription { get; set; } + + /// + /// The payment token, if the payment was enrolled in the vault. + /// + [JsonProperty(PropertyName = "token")] + public string Token { get; set; } + + /// + /// The entry method for the transaction (CHIP, MSR, KEYED, etc). + /// + [JsonProperty(PropertyName = "entryMethod")] + public string EntryMethod { get; set; } + + /// + /// The card brand (VISA, MC, AMEX, DEBIT, etc). + /// + [JsonProperty(PropertyName = "paymentType")] + public string PaymentType { get; set; } + + /// + /// Provides network level detail on how a transaction was routed, especially for + /// debit transactions. + /// + [JsonProperty(PropertyName = "network")] + public string Network { get; set; } + + /// + /// Identifies the card association based on bin number. Used primarily used to + /// indicate the major logo on a card, even when debit transactions are routed on a + /// different network. + /// + [JsonProperty(PropertyName = "logo")] + public string Logo { get; set; } + + /// + /// The masked primary account number. + /// + [JsonProperty(PropertyName = "maskedPan")] + public string MaskedPan { get; set; } + + /// + /// The BlockChyp public key if the user presented a BlockChyp payment card. + /// + [JsonProperty(PropertyName = "publicKey")] + public string PublicKey { get; set; } + + /// + /// That the transaction did something that would put the system in PCI scope. + /// + [JsonProperty(PropertyName = "ScopeAlert")] + public bool ScopeAlert { get; set; } + + /// + /// The cardholder name. + /// + [JsonProperty(PropertyName = "cardHolder")] + public string CardHolder { get; set; } + + /// + /// The card expiration month in MM format. + /// + [JsonProperty(PropertyName = "expMonth")] + public string ExpMonth { get; set; } + + /// + /// The card expiration year in YY format. + /// + [JsonProperty(PropertyName = "expYear")] + public string ExpYear { get; set; } + + /// + /// Address verification results if address information was submitted. + /// + [JsonProperty(PropertyName = "avsResponse")] + public AvsResponse AvsResponse { get; set; } + + /// + /// Suggested receipt fields. + /// + [JsonProperty(PropertyName = "receiptSuggestions")] + public ReceiptSuggestions ReceiptSuggestions { get; set; } + + /// + /// Customer data, if any. Preserved for reverse compatibility. + /// + [JsonProperty(PropertyName = "customer")] + public Customer Customer { get; set; } + + /// + /// Customer data, if any. + /// + [JsonProperty(PropertyName = "customers")] + public List Customers { get; set; } + + /// + /// Details about a payment card derived from its BIN/IIN. + /// + [JsonProperty(PropertyName = "cardMetadata")] + public CardMetadata CardMetadata { get; set; } + } +} diff --git a/src/BlockChyp/Entities/EnrollRequest.cs b/src/BlockChyp/Entities/EnrollRequest.cs index 3936a57..2892249 100644 --- a/src/BlockChyp/Entities/EnrollRequest.cs +++ b/src/BlockChyp/Entities/EnrollRequest.cs @@ -223,5 +223,11 @@ public class EnrollRequest : BaseEntity, ITimeoutRequest, ICoreRequest, IPayment /// [JsonProperty(PropertyName = "subscription")] public bool Subscription { get; set; } + + /// + /// That this transaction will include a card metadata lookup. + /// + [JsonProperty(PropertyName = "cardMetadataLookup")] + public bool CardMetadataLookup { get; set; } } } diff --git a/src/BlockChyp/Entities/EnrollResponse.cs b/src/BlockChyp/Entities/EnrollResponse.cs index b47d5a9..74862b8 100644 --- a/src/BlockChyp/Entities/EnrollResponse.cs +++ b/src/BlockChyp/Entities/EnrollResponse.cs @@ -206,5 +206,11 @@ public class EnrollResponse : BaseEntity, IAbstractAcknowledgement, IApprovalRes /// [JsonProperty(PropertyName = "sigFile")] public string SigFile { get; set; } + + /// + /// Details about a payment card derived from its BIN/IIN. + /// + [JsonProperty(PropertyName = "cardMetadata")] + public CardMetadata CardMetadata { get; set; } } } diff --git a/src/BlockChyp/Entities/HealthcareMetadata.cs b/src/BlockChyp/Entities/HealthcareMetadata.cs new file mode 100644 index 0000000..cf3c4fa --- /dev/null +++ b/src/BlockChyp/Entities/HealthcareMetadata.cs @@ -0,0 +1,36 @@ +// Copyright 2019-2024 BlockChyp, Inc. All rights reserved. Use of this code is +// governed by a license that can be found in the LICENSE file. +// +// This file was generated automatically by the BlockChyp SDK Generator. Changes +// to this file will be lost every time the code is regenerated. + +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace BlockChyp.Entities +{ + /// + /// Fields for HSA/FSA transactions. + /// + public class HealthcareMetadata : BaseEntity + { + /// + /// A list of healthcare categories in the transaction. + /// + [JsonProperty(PropertyName = "types")] + public List Types { get; set; } + + /// + /// That the purchased items were verified against an Inventory Information + /// Approval System (IIAS). + /// + [JsonProperty(PropertyName = "iiasVerified")] + public bool IiasVerified { get; set; } + + /// + /// That the transaction is exempt from IIAS verification. + /// + [JsonProperty(PropertyName = "iiasExempt")] + public bool IiasExempt { get; set; } + } +} diff --git a/src/BlockChyp/Entities/RefundRequest.cs b/src/BlockChyp/Entities/RefundRequest.cs index 671335a..f9d8266 100644 --- a/src/BlockChyp/Entities/RefundRequest.cs +++ b/src/BlockChyp/Entities/RefundRequest.cs @@ -280,8 +280,8 @@ public class RefundRequest : BaseEntity, ITimeoutRequest, ICoreRequest, IPayment /// /// Details for HSA/FSA transactions. /// - [JsonProperty(PropertyName = "healthcare")] - public Healthcare Healthcare { get; set; } + [JsonProperty(PropertyName = "healthcareMetadata")] + public HealthcareMetadata HealthcareMetadata { get; set; } /// /// Instructs the terminal to simulate a post auth chip rejection that would @@ -314,5 +314,11 @@ public class RefundRequest : BaseEntity, ITimeoutRequest, ICoreRequest, IPayment /// [JsonProperty(PropertyName = "mit")] public bool Mit { get; set; } + + /// + /// That this transaction will include a card metadata lookup. + /// + [JsonProperty(PropertyName = "cardMetadataLookup")] + public bool CardMetadataLookup { get; set; } } } diff --git a/src/BlockChyp/Entities/TokenMetadataResponse.cs b/src/BlockChyp/Entities/TokenMetadataResponse.cs index bbaa285..51735c9 100644 --- a/src/BlockChyp/Entities/TokenMetadataResponse.cs +++ b/src/BlockChyp/Entities/TokenMetadataResponse.cs @@ -36,5 +36,11 @@ public class TokenMetadataResponse : BaseEntity, IAbstractAcknowledgement /// [JsonProperty(PropertyName = "token")] public CustomerToken Token { get; set; } + + /// + /// Details about a payment card derived from its BIN/IIN. + /// + [JsonProperty(PropertyName = "cardMetadata")] + public CardMetadata CardMetadata { get; set; } } }