From f85dab5f0fc1265c23c1155c5c636d3631197ed9 Mon Sep 17 00:00:00 2001 From: Winston Hoy Date: Wed, 7 Feb 2024 15:29:38 -0500 Subject: [PATCH 1/5] LinkCard.billingAddress type fix to reflect most attributes being optional configure package to build exports when installed --- lib/cards.js | 20 +++++++++++++------- package.json | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/cards.js b/lib/cards.js index ae73e70..6464bef 100644 --- a/lib/cards.js +++ b/lib/cards.js @@ -92,6 +92,12 @@ export const CARD_VERIFICATION_STATUS = { * * @tag Cards */ + + /** @template T + * @template K {extends keyof T} + * @typedef {Pick, K> & Omit} Optional + */ + /** * Card information collected for acquisition. * @typedef LinkCard @@ -99,7 +105,7 @@ export const CARD_VERIFICATION_STATUS = { * @property {CardExpiration} expiration - Card expiration date * @property {string} cardCvv - 3-4 digit card verification value * @property {string} holderName - Full name of the card holder - * @property {CardBillingAddress} billingAddress - The billing address of the card + * @property {Optional} billingAddress - The billing address of the card * * @tag Cards */ @@ -141,7 +147,7 @@ export const CARD_VERIFICATION_STATUS = { * @property {CardVerficationStatuses} cardVerfication - The results of submitting cardholder data to a card network for verification * @property {string} issuer - The name of the issuer * @property {string} issuerCountry - The country of the issuer - * + * * @example * { "cardID": "ec7e1848-dc80-4ab0-8827-dd7fc0737b43", @@ -171,7 +177,7 @@ export const CARD_VERIFICATION_STATUS = { "issuer": "GRINGOTTS BANK", "issuerCountry": "US" } - * + * * @tag Cards */ @@ -187,7 +193,7 @@ export class Cards { /** * Retrieves details for the card with the specified ID. * The `CARDS_READ` scope enum is required when making a request from the browser. - * + * * @param {string} accountID - Account to query * @param {string} cardID - Card to query * @returns {Promise} @@ -210,7 +216,7 @@ export class Cards { /** * Lists all the cards associated with a particular Moov account. * The `CARDS_READ` scope enum is required when making a request from the browser. - * + * * @param {string} accountID - Account to query * @returns {Promise} * @tag Cards @@ -232,7 +238,7 @@ export class Cards { * Links a card to a Moov account. Only use this endpoint if you have provided Moov with a * copy of your PCI attestation of compliance. * The `CARDS_WRITE` scope enum is required when making a request from the browser. - * + * * @param {string} accountID - Account to link * @param {LinkCard} card - Card information * @returns {Promise} @@ -256,7 +262,7 @@ export class Cards { /** * Disables a card with the specified ID. * The `CARDS_WRITE` scope enum is required when making a request from the browser. - * + * * @param {string} accountID - Account to query * @param {string} cardID - Card to query * @returns {Promise} diff --git a/package.json b/package.json index bc4ab3e..16c7471 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "docs": "node ./scripts/generateDocs.cjs", "docs-watch": "watch \"npm run docs\" ./docs/templates", "docs-clean": "rm ./docs/output/*.*", + "prepare": "npm run build", "test": "ava ./lib/**/*.test.js", "generate-types": "tsc", "test-watch": "ava --watch ./lib/**/*.test.js" From a3e35f3766eafc88b8596f8ebcda7ed149efc2dd Mon Sep 17 00:00:00 2001 From: Winston Hoy Date: Tue, 27 Feb 2024 12:52:11 -0500 Subject: [PATCH 2/5] Card typedef update --- lib/cards.js | 73 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/lib/cards.js b/lib/cards.js index 6464bef..835c9db 100644 --- a/lib/cards.js +++ b/lib/cards.js @@ -1,6 +1,8 @@ import { check, checkString } from "./helpers/checks.js"; import { Err } from "./helpers/errors.js"; +/** @typedef {import('./paymentMethods.js').PaymentMethod} PaymentMethod */ + /** @external Promise */ /** @@ -147,35 +149,54 @@ export const CARD_VERIFICATION_STATUS = { * @property {CardVerficationStatuses} cardVerfication - The results of submitting cardholder data to a card network for verification * @property {string} issuer - The name of the issuer * @property {string} issuerCountry - The country of the issuer + * @property {string} merchantAccountID + * @property {PaymentMethod[]} paymentMethods * * @example * { - "cardID": "ec7e1848-dc80-4ab0-8827-dd7fc0737b43", - "fingerprint": "9948962d92a1ce40c9f918cd9ece3a22bde62fb325a2f1fe2e833969de672ba3", - "brand": "American Express", - "cardType": "debit", - "lastFourCardNumber": "1234", - "bin": "123456", - "expiration": { - "month": "01", - "year": "21" - }, - "holderName": "Jules Jackson", - "billingAddress": { - "addressLine1": "123 Main Street", - "addressLine2": "Apt 302", - "city": "Boulder", - "stateOrProvince": "CO", - "postalCode": "80301", - "country": "US" - }, - "cardVerification": { - "cvv": "match", - "addressLine1": "match", - "postalCode": "match" - }, - "issuer": "GRINGOTTS BANK", - "issuerCountry": "US" + "billingAddress": { + "addressLine1": "123 Main Street", + "addressLine2": "Apt 302", + "city": "Boulder", + "country": "US", + "postalCode": "80301", + "stateOrProvince": "CO" + }, + "bin": "123456", + "brand": "Discover", + "cardAccountUpdater": { + "updateType": "number-update", + "updatedOn": "2019-08-24T14:15:22Z" + }, + "cardID": "ec7e1848-dc80-4ab0-8827-dd7fc0737b43", + "cardOnFile": true, + "cardType": "debit", + "cardVerification": { + "addressLine1": "match", + "cvv": "match", + "postalCode": "match" + }, + "domesticPushToCard": "fast-funds", + "expiration": { + "month": "01", + "year": "21" + }, + "fingerprint": "9948962d92a1ce40c9f918cd9ece3a22bde62fb325a2f1fe2e833969de672ba3", + "holderName": "Jules Jackson", + "issuer": "GRINGOTTS BANK", + "issuerCountry": "US", + "lastFourCardNumber": "1234", + "merchantAccountID": "50469144-f859-46dc-bdbd-9587c2fa7b42", + "paymentMethods": [ + { + "paymentMethodID": "9506dbf6-4208-44c3-ad8a-e4431660e1f2", + "paymentMethodType": "card-payment" + }, + { + "paymentMethodID": "3f9969cf-a1f3-4d83-8ddc-229a506651cf", + "paymentMethodType": "push-to-card" + } + ] } * * @tag Cards From e111fc647ab3d6198f4c2b907f02b25f24cb3d8f Mon Sep 17 00:00:00 2001 From: Winston Hoy Date: Tue, 27 Feb 2024 14:36:25 -0500 Subject: [PATCH 3/5] add support for paymentMethods in card link response --- lib/cards.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/cards.js b/lib/cards.js index 835c9db..b9c20d9 100644 --- a/lib/cards.js +++ b/lib/cards.js @@ -150,7 +150,7 @@ export const CARD_VERIFICATION_STATUS = { * @property {string} issuer - The name of the issuer * @property {string} issuerCountry - The country of the issuer * @property {string} merchantAccountID - * @property {PaymentMethod[]} paymentMethods + * @property {PaymentMethod[]} [paymentMethods] * * @example * { @@ -262,16 +262,21 @@ export class Cards { * * @param {string} accountID - Account to link * @param {LinkCard} card - Card information + * @param {boolean} [waitForPaymentMethods = false] whether to wait for payment methods to be created and included in response * @returns {Promise} * @tag Cards */ - async link(accountID, card) { + async link(accountID, card, waitForPaymentMethods = false) { checkString(accountID).or(Err.MISSING_ACCOUNT_ID); check(card).or(Err.MISSING_CARD); + const headers = {}; + if (waitForPaymentMethods) headers['X-Wait-For'] = 'payment-method' + const result = await this.moov .got({ url: `accounts/${accountID}/cards`, + headers, method: "POST", json: card, }) From cf497338de87e2ac6b2536927437e96d2c905af0 Mon Sep 17 00:00:00 2001 From: Winston Hoy Date: Fri, 29 Mar 2024 13:54:42 -0400 Subject: [PATCH 4/5] Update cards.js Add cardOnFile attribute to LinkCard typedef --- lib/cards.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cards.js b/lib/cards.js index b9c20d9..f9e8f38 100644 --- a/lib/cards.js +++ b/lib/cards.js @@ -108,6 +108,7 @@ export const CARD_VERIFICATION_STATUS = { * @property {string} cardCvv - 3-4 digit card verification value * @property {string} holderName - Full name of the card holder * @property {Optional} billingAddress - The billing address of the card + * @property {boolean} [ cardOnFile = false ] - Indicates cardholder has authorized card to be stored for future payments. Only cards marked as card-on-file are eligible for automatic updates via card account updater * * @tag Cards */ From f5a7ee8932066e5bbfc16a4fca869dddcc3158e9 Mon Sep 17 00:00:00 2001 From: Zach Balder Date: Tue, 20 Aug 2024 15:18:10 -0400 Subject: [PATCH 5/5] add update method --- lib/cards.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/cards.js b/lib/cards.js index f9e8f38..e30acae 100644 --- a/lib/cards.js +++ b/lib/cards.js @@ -112,6 +112,17 @@ export const CARD_VERIFICATION_STATUS = { * * @tag Cards */ + +/** + * Card information that can be updated. + * @typedef UpdateCard + * @property {CardExpiration} expiration - Card expiration date + * @property {string} cardCvv - 3-4 digit card verification value + * @property {Optional} billingAddress - The billing address of the card +* + * @tag Cards + */ + /** * Card billing address * @typedef CardBillingAddress @@ -286,6 +297,33 @@ export class Cards { return result; } + /** + * Updates a card in a Moov account. Only use this endpoint if you have provided Moov with a + * copy of your PCI attestation of compliance. + * The `CARDS_WRITE` scope enum is required when making a request from the browser. + * + * @param {string} accountID - Account linked to card + * @param {string} cardID - Card to update + * @param {UpdateCard} cardUpdates - Card information + * @returns {Promise} + * @tag Cards + */ + async update(accountID, cardID, cardUpdates) { + checkString(accountID).or(Err.MISSING_ACCOUNT_ID); + checkString(cardID).or(Err.MISSING_CARD_ID); + check(cardUpdates).or(Err.MISSING_CARD); + + const result = await this.moov + .got({ + url: `accounts/${accountID}/cards/${cardID}`, + method: "PATCH", + json: cardUpdates, + }) + .json(); + + return result; + } + /** * Disables a card with the specified ID. * The `CARDS_WRITE` scope enum is required when making a request from the browser.