UNPKG

11.2 kBMarkdownView Raw
1# Credit Card Type [![Build Status](https://github.com/braintree/credit-card-type/workflows/Unit%20Tests/badge.svg)](https://github.com/braintree/credit-card-type/actions?query=workflow%3A%22Unit+Tests%22) [![npm version](https://badge.fury.io/js/credit-card-type.svg)](http://badge.fury.io/js/credit-card-type)
2
3Credit Card Type provides a useful utility method for determining a credit card type from both fully qualified and partial numbers. This is not a validation library but rather a smaller component to help you build your own validation or UI library.
4
5This library is designed for type-as-you-go detection (supports partial numbers) and is written in CommonJS so you can use it in Node, io.js, and the [browser](http://browserify.org).
6
7## Download
8
9To install via npm:
10
11```bash
12npm install credit-card-type
13```
14
15## Example
16
17```javascript
18var creditCardType = require("credit-card-type");
19
20// The card number provided should be normalized prior to usage here.
21var visaCards = creditCardType("4111");
22console.log(visaCards[0].type); // 'visa'
23
24var ambiguousCards = creditCardType("6");
25console.log(ambiguousCards.length); // 6
26console.log(ambiguousCards[0].niceType); // 'Discover'
27console.log(ambiguousCards[1].niceType); // 'UnionPay'
28console.log(ambiguousCards[2].niceType); // 'Maestro'
29```
30
31## API
32
33### `creditCardType(number: String)`
34
35`creditCardType` will return an array of objects, each with the following data:
36
37| Key | Type | Description |
38| ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
39| `niceType` | `String` | A pretty printed representation of the card brand.<br/>- `Visa`<br />- `Mastercard`<br />- `American Express`<br />- `Diners Club`<br />- `Discover`<br />- `JCB`<br />- `UnionPay`<br />- `Maestro`<br />- `Mir`<br />- `Elo`<br />- `Hiper`<br />- `Hipercard` |
40| `type` | `String` | A code-friendly presentation of the card brand (useful to class names in CSS). Please refer to Card Type "Constants" below for the list of possible values.<br/>- `visa`<br />- `mastercard`<br />- `american-express`<br />- `diners-club`<br />- `discover`<br />- `jcb`<br />- `unionpay`<br />- `maestro`<br />- `mir`<br /> - `elo`<br /> - `hiper`<br /> - `hipercard` |
41| `gaps` | `Array` | The expected indices of gaps in a string representation of the card number. For example, in a Visa card, `4111 1111 1111 1111`, there are expected spaces in the 4th, 8th, and 12th positions. This is useful in setting your own formatting rules. |
42| `lengths` | `Array` | The expected lengths of the card number as an array of strings (excluding spaces and `/` characters). |
43| `code` | `Object` | The information regarding the security code for the determined card. Learn more about the [code object](#code) below. |
44
45If no card types are found, this returns an empty array.
46
47_Note:_ The card number provided should be normalized ahead of time. The card number string should not contain any non-integer values (e.g. no letters or special characters)
48
49### `creditCardType.getTypeInfo(type: String)`
50
51`getTypeInfo` will return a singular object (with the same structure as `creditCardType`) corresponding with the specified `type`, or undefined if the specified `type` is invalid/unknown.
52
53### Card Type "Constants"
54
55Named variables are provided for each of the supported card types:
56
57- `AMERICAN_EXPRESS`
58- `DINERS_CLUB`
59- `DISCOVER`
60- `ELO`
61- `HIPERCARD`
62- `HIPER`
63- `JCB`
64- `MAESTRO`
65- `MASTERCARD`
66- `MIR`
67- `UNIONPAY`
68- `VISA`
69
70#### `code`
71
72Card brands provide different nomenclature for their security codes as well as varying lengths.
73
74| Brand | Name | Size |
75| ------------------ | ------ | ---- |
76| `Visa` | `CVV` | 3 |
77| `Mastercard` | `CVC` | 3 |
78| `American Express` | `CID` | 4 |
79| `Diners Club` | `CVV` | 3 |
80| `Discover` | `CID` | 3 |
81| `JCB` | `CVV` | 3 |
82| `UnionPay` | `CVN` | 3 |
83| `Maestro` | `CVC` | 3 |
84| `Mir` | `CVP2` | 3 |
85| `Elo` | `CVE` | 3 |
86| `Hiper` | `CVC` | 3 |
87| `Hipercard` | `CVC` | 4 |
88
89A full response for a `Visa` card will look like this:
90
91```json
92{
93 "niceType": "Visa",
94 "type": "visa",
95 "gaps": [4, 8, 12],
96 "lengths": [16],
97 "code": { "name": "CVV", "size": 3 }
98}
99```
100
101### Advanced Usage
102
103CommonJS:
104
105```javascript
106var creditCardType = require("credit-card-type");
107var getTypeInfo = require("credit-card-type").getTypeInfo;
108var CardType = require("credit-card-type").types;
109```
110
111ES6:
112
113```javascript
114import creditCardType, {
115 getTypeInfo,
116 types as CardType,
117} from "credit-card-type";
118```
119
120#### Filtering
121
122```javascript
123creditCardType(cardNumber).filter(function (card) {
124 return card.type === CardType.MASTERCARD || card.type === CardType.VISA;
125});
126```
127
128#### Pattern Detection
129
130Each card type has a `patterns` attribute that is an array of numbers and ranges of numbers (represented by an array of 2 values, a min and a max).
131
132If the pattern is a number, the modules compares it against the card number. Partial matches for card numbers that are shorter than the pattern also match. Given the pattern `123`, then the card numbers `1`, `12`, `123`, `1234` will all match, but `2`, `13`, and `124` will not.
133
134If the pattern is an array of numbers, then the card number is checked to be within the range of those numbers. Again, partial matches are accepted. Given the range `[100, 123]`, then the card numbers `1`, `10`, `100`, `12`, `120`,
135`123` will all match, but `2`, `13`, and `124` will not.
136
137For detection, the module loops over each card type's `patterns` array, and if a match occurs, that card type is added to the array of results.
138
139In the case where multiple matches are made, if the entirety of the pattern is matched, the card type with the stronger pattern is preferred. For instance, Visa cards match anything that starts with a 4, but there are
140some Elo cards that begin with a 4. One example is `401178`. So for the card
141numbers, `4`, `40`, `401`, `4011`, `40117`, the module will report that this
142card is _either_ a Visa or an Elo card. Once the card number becomes `401178`,
143the modules sees that an exact match for the ELO bin has been made, and the module reports
144that the card can only be an Elo card.
145
146#### Adding Card Types
147
148You can add additional card brands not supported by the module with `addCard`. Pass in the configuration object.
149
150```javascript
151creditCardType.addCard({
152 niceType: "NewCard",
153 type: "new-card",
154 patterns: [2345, 2376],
155 gaps: [4, 8, 12],
156 lengths: [16],
157 code: {
158 name: "CVV",
159 size: 3,
160 },
161});
162```
163
164If you add a card that already exists in the module, it will overwrite it.
165
166```javascript
167creditCardType.addCard({
168 niceType: "Visa with Custom Nice Type",
169 type: creditCardType.types.VISA,
170 patterns: [41111, [44, 47]],
171 gaps: [4, 8, 12],
172 lengths: [13, 16, 19], // add support for old, deprecated 13 digit visas
173 code: {
174 name: "CVV",
175 size: 3,
176 },
177});
178```
179
180Adding new cards puts them at the bottom of the priority for testing. Priority is determined by an array. By default, the priority looks like:
181
182```javascript
183[
184 creditCardType.types.VISA,
185 creditCardType.types.MASTERCARD,
186 creditCardType.types.AMERICAN_EXPRESS,
187 creditCardType.types.DINERS_CLUB,
188 creditCardType.types.DISCOVER,
189 creditCardType.types.JCB,
190 creditCardType.types.UNIONPAY,
191 creditCardType.types.MAESTRO,
192 creditCardType.types.ELO,
193 creditCardType.types.MIR,
194 creditCardType.types.HIPER,
195 creditCardType.types.HIPERCARD,
196];
197```
198
199You can adjust the order using `changeOrder`. The number you pass in as the second argument is where the card is inserted into the array. The closer to the beginning of the array, the higher priority it has.
200
201```javascript
202creditCardType.changeOrder("my-new-card", 0); // give custom card type the highest priority
203creditCardType.changeOrder("my-new-card", 3); // give it a priority at position 3 in the test order array
204```
205
206You can also remove cards with `removeCard`.
207
208```javscript
209creditCardType.removeCard(creditCardType.types.VISA);
210```
211
212If you need to reset the modifications you have created, simply call `resetModifications`:
213
214```javascript
215creditCardType.resetModifications();
216```
217
218#### Updating Card Types
219
220You can update cards with `updateCard`. Pass in the card type and the configuration object. Any properties left off will inherit from the original card object.
221
222```javascript
223creditCardType.updateCard(creditCardType.types.VISA, {
224 niceType: "Fancy Visa",
225 lengths: [11, 16],
226});
227
228var visa = creditCardType.getTypeInfo(creditCardType.types.VISA);
229
230// overwritten properties
231visa.niceType; // 'Fancy Visa'
232visa.length; // [11, 16]
233
234// unchanged properties
235visa.gaps; // [4, 8, 12]
236visa.code.name; // 'CVV'
237```
238
239If you need to reset the modifications you have created, simply call `resetModifications`:
240
241```javascript
242creditCardType.resetModifications();
243```
244
245#### Pretty Card Numbers
246
247```javascript
248function prettyCardNumber(cardNumber, cardType) {
249 var card = getTypeInfo(cardType);
250
251 if (card) {
252 var offsets = [].concat(0, card.gaps, cardNumber.length);
253 var components = [];
254
255 for (var i = 0; offsets[i] < cardNumber.length; i++) {
256 var start = offsets[i];
257 var end = Math.min(offsets[i + 1], cardNumber.length);
258 components.push(cardNumber.substring(start, end));
259 }
260
261 return components.join(" ");
262 }
263
264 return cardNumber;
265}
266
267prettyCardNumber("xxxxxxxxxx343", CardType.AMERICAN_EXPRESS); // 'xxxx xxxxxx 343'
268```
269
270### Development
271
272We use `nvm` for managing our node versions, but you do not have to. Replace any `nvm` references with the tool of your choice below.
273
274```bash
275nvm install
276npm install
277```
278
279All testing dependencies will be installed upon `npm install` and the test suite executed with `npm test`.