Giter Club home page Giter Club logo

payform's Introduction


Do you use webpack?

Wish your team made reducing the size of your webpack builds a priority? Want to know how the changes you're making impact your asset profile for every pull request?

Check it out at packtracker.io.


payform

Build Status Dependencies

A general purpose library for building credit card forms, validating inputs, and formatting numbers.

Supported card types:

  • Visa
  • MasterCard
  • American Express
  • Diners Club
  • Discover
  • UnionPay
  • JCB
  • Visa Electron
  • Maestro
  • Forbrugsforeningen
  • Dankort

(Custom card types are also supported)

Works in IE8+ and all other modern browsers.

Demo

Installation / Usage

npm (Node and Browserify)

npm install payform --save
var payform = require('payform');

// Format input for card number entry
var input = document.getElementById('ccnum');
payform.cardNumberInput(input)

// Validate a credit card number
payform.validateCardNumber('4242 4242 4242 4242'); //=> true

// Get card type from number
payform.parseCardType('4242 4242 4242 4242'); //=> 'visa'

AMD / Require.js

require.config({
    paths: { "payform": "path/to/payform" }
});

require(["payform"], function (payform) {
  // Format input for card number entry
  var input = document.getElementById('ccnum');
  payform.cardNumberInput(input)

  // Validate a credit card number
  payform.validateCardNumber('4242 4242 4242 4242'); //=> true

  // Get card type from number
  payform.parseCardType('4242 4242 4242 4242'); //=> 'visa'
});

Direct script include / Bower

Optionally via bower (or simply via download)

bower install payform --save
<script src="path/to/payform/dist/payform.js"></script>
<script>
  // Format input for card number entry
  var input = document.getElementById('ccnum');
  payform.cardNumberInput(input)

  // Validate a credit card number
  payform.validateCardNumber('4242 4242 4242 4242'); //=> true

  // Get card type from number
  payform.parseCardType('4242 4242 4242 4242'); //=> 'visa'
</script>

jQuery Plugin (also supports Zepto)

This library also includes a jquery plugin. The primary payform object can be found at $.payform, and there are jquery centric ways to utilize the browser input formatters.

<script src="path/to/payform/dist/jquery.payform.js"></script>
<script>
  // Format input for card number entry
  $('input.ccnum').payform('formatCardNumber');

  // Validate a credit card number
  $.payform.validateCardNumber('4242 4242 4242 4242'); //=> true

  // Get card type from number
  $.payform.parseCardType('4242 4242 4242 4242'); //=> 'visa'
</script>

API

General Formatting and Validation

payform.validateCardNumber(number)

Validates a card number:

  • Validates numbers
  • Validates Luhn algorithm
  • Validates length

Example:

payform.validateCardNumber('4242 4242 4242 4242'); //=> true

payform.validateCardExpiry(month, year)

Validates a card expiry:

  • Validates numbers
  • Validates in the future
  • Supports year shorthand

Example:

payform.validateCardExpiry('05', '20'); //=> true
payform.validateCardExpiry('05', '2015'); //=> true
payform.validateCardExpiry('05', '05'); //=> false

payform.validateCardCVC(cvc, type)

Validates a card CVC:

  • Validates number
  • Validates length to 4

Example:

payform.validateCardCVC('123'); //=> true
payform.validateCardCVC('123', 'amex'); //=> true
payform.validateCardCVC('1234', 'amex'); //=> true
payform.validateCardCVC('12344'); //=> false

payform.parseCardType(number)

Returns a card type. Either:

  • visa
  • mastercard
  • amex
  • dinersclub
  • discover
  • unionpay
  • jcb
  • visaelectron
  • maestro
  • forbrugsforeningen
  • dankort

The function will return null if the card type can't be determined.

Example:

payform.parseCardType('4242 4242 4242 4242'); //=> 'visa'
payform.parseCardType('hello world?'); //=> null

payform.parseCardExpiry(string)

Parses a credit card expiry in the form of MM/YYYY, returning an object containing the month and year. Shorthand years, such as 13 are also supported (and converted into the longhand, e.g. 2013).

payform.parseCardExpiry('03 / 2025'); //=> {month: 3: year: 2025}
payform.parseCardExpiry('05 / 04'); //=> {month: 5, year: 2004}

This function doesn't perform any validation of the month or year; use payform.validateCardExpiry(month, year) for that.

Browser <input> formatting helpers

These methods are specifically for use in the browser to attach <input> formatters.

(alternate jQuery Plugin syntax is also provided)

payform.cardNumberInput(input)

jQuery plugin: $(...).payform('formatCardNumber')

Formats card numbers:

  • Includes a space between every 4 digits
  • Restricts input to numbers
  • Limits to 16 numbers
  • Supports American Express formatting

Example:

var input = document.getElementById('ccnum');
payform.cardNumberInput(input);

payform.expiryInput(input)

jQuery plugin: $(...).payform('formatCardExpiry')

Formats card expiry:

  • Includes a / between the month and year
  • Restricts input to numbers
  • Restricts length

Example:

var input = document.getElementById('expiry');
payform.expiryInput(input);

payform.cvcInput(input)

jQuery plugin: $(...).payform('formatCardCVC')

Formats card CVC:

  • Restricts length to 4 numbers
  • Restricts input to numbers

Example:

var input = document.getElementById('cvc');
payform.cvcInput(input);

payform.numericInput(input)

jQuery plugin: $(...).payform('formatNumeric')

General numeric input restriction.

Example:

var input = document.getElementById('numeric');
payform.numericInput(input);

Detaching formatting helpers from <input>

Once you have used the formatting helpers available, you might also want to remove them from your input elements. Being able to remove them is especially useful in a Single Page Application (SPA) environment where you want to make sure you're properly unsubscribing events from elements before removing them from the DOM. Detaching events will assure you will not encounter any memory leaks while using this library.

These methods are specifically for use in the browser to detach <input> formatters.

payform.detachCardNumberInput(input)

jQuery plugin: $(...).payform('detachFormatCardNumber')

Example:

var input = document.getElementById('ccnum');
// now you're able to detach:
payform.detachCardNumberInput(input);

payform.detachExpiryInput(input)

jQuery plugin: $(...).payform('detachFormatCardExpiry')

Example:

var input = document.getElementById('expiry');
payform.expiryInput(input);
// now you're able to detach:
payform.detachExpiryInput(input);

payform.detachCvcInput(input)

jQuery plugin: $(...).payform('detachFormatCardCVC')

Example:

var input = document.getElementById('cvc');
payform.cvcInput(input);
// now you're able to detach:
payform.detachCvcInput(input);

payform.detachNumericInput(input)

jQuery plugin: $(...).payform('detachFormatNumeric')

Example:

var input = document.getElementById('numeric');
payform.numericInput(input);
// now you're able to detach:
payform.detachNumericInput(input);

Custom Cards

payform.cards

Array of objects that describe valid card types. Each object should contain the following fields:

{
  // Card type, as returned by payform.parseCardType.
  type: 'mastercard',
  // Regex used to identify the card type. For the best experience, this should be
  // the shortest pattern that can guarantee the card is of a particular type.
  pattern: /^5[0-5]/,
  // Array of valid card number lengths.
  length: [16],
  // Array of valid card CVC lengths.
  cvcLength: [3],
  // Boolean indicating whether a valid card number should satisfy the Luhn check.
  luhn: true,
  // Regex used to format the card number. Each match is joined with a space.
  format: /(\d{1,4})/g
}

When identifying a card type, the array is traversed in order until the card number matches a pattern. For this reason, patterns with higher specificity should appear towards the beginning of the array.

Development

Please see CONTRIBUTING.md.

Autocomplete recommendations

We recommend you turn autocomplete on for credit card forms, except for the CVC field (which should never be stored). You can do this by setting the autocomplete attribute:

<form autocomplete="on">
  <input class="cc-number">
  <input class="cc-cvc" autocomplete="off">
</form>

You should also mark up your fields using the Autofill spec. These are respected by a number of browsers, including Chrome.

<input type="tel" class="cc-number" autocomplete="cc-number">

Set autocomplete to cc-number for credit card numbers and cc-exp for credit card expiry.

Mobile recommendations

We recommend you to use <input type="tel"> which will cause the numeric keyboard to be displayed on mobile devices:

<input type="tel" class="cc-number">

A derived work

This library is derived from a lot of great work done on jquery.payment by the folks at Stripe. This aims to build upon that work, in a module that can be consumed in more diverse situations.

payform's People

Contributors

ajlai avatar alex-stripe avatar buzzedword avatar byroot avatar ddayguerrero avatar emostar avatar esaborit4code avatar fishrock123 avatar glebm avatar gsamokovarov avatar jamesreggio avatar joe4mg avatar jondavidjohn avatar kenany avatar kennethormandy avatar kjc-stripe avatar kulte avatar kyleconroy avatar maccman avatar mathiasbynens avatar michaelvillar avatar mikemaccana avatar rmm5t avatar rodovich avatar ryancooley avatar sergiocruz avatar slexaxton avatar toolmantim avatar tyrantkhan avatar voronianski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

payform's Issues

Integrate some form of automated browser testing

Currently there is good test coverage for the library methods for formatting and validating card information, but there is no testing setup for actual functional tests for the input handlers that take care of input restrictions and formatting.

Would love to get some form of automated browser testing in place.

Setting default value of field does not format properly

When either setting the value of the input when loading the DOM or setting the value of the input via javascript platform does not format the car number or the expiry based on the set values...

For example if I have this:

<input value="4111111111111111" id="ccnum"/>

When I initialize the field using

$('#ccnum').payform('formatCardNumber');

I would expect it to format the value of the input as if I had typed it in..

Problem with Visa cards?

It appears that Visa cards (starting with 4) are not validating properly if I include cardNumberInput. It formats the card number properly but when I tab out after entering 16 digits it removes the last digit. If I add a space at the end it validates the card number. If I remove the cardNumberInput setting it validates after 16 digits without error. And, without formatting, obviously.

If I test with MasterCard it works as expected including formatting.

Thanks for looking at this.

Maestro cards pattern

Hi!
Taking examples from adyen test cards the latest changes on the pattern for maestro cards will make these evaluate false for valid cards.
For example: 6771 7980 2100 0008 or 6771 8300 0000 0000 006.
Was this change taken from any official source?
According to this document - Page 73
BINs for maestro cards should be on the ranges between 639000 to 639099 and 670000 to 679999

Bancontact (BCMC) credit card support

Hello,

I tried to use the information on how to add a "custom cards" validation but I must be missing something.

I am trying to add Bancontact support.

Cards number example:

  • 6703 4444 4444 4449
  • 6703 0000 0000 0000 003

CVC: none
Not sure about the length, I found 13 to 19 in some other validators.

Here is the code I am using to add the card declaration.

window.payform.cards.push({
// Card type, as returned by payform.parseCardType.
type: 'BCMC',
// Regex used to identify the card type. For the best experience, this should be
// the shortest pattern that can guarantee the card is of a particular type.
pattern: /^6703/,
// Array of valid card number lengths.
length: [13,14,15,16,17,18,19],
// Array of valid card CVC lengths.
cvcLength: [0],
// Boolean indicating whether a valid card number should satisfy the Luhn check.
luhn: true,
// Regex used to format the card number. Each match is joined with a space.
format: /(\d{1,4})/g
});

By default, Bancontact cards are matching Maestro cards, but that's not OK because of the CVC at the least.

Selected text is not always cleared when typing

There is a use-case pattern when user presses Ctrl+A and then Backspace to clear the input. However it doesn't work around delimiters.

How to reproduce:

  1. Enter 5213, then space is automatically inserted: 5213 .
  2. Press Ctrl+A and then Backspace.

It will remove only the last character, instead of entire string.


Also, there is another failing pattern:

Enter 123, then press Ctrl+A, then start to type the replacement number. It will not clear the selected text.

Credit Card field issues on Android

On Android is seems that the caret is reset to the beginning of the input when typing and it makes the credit card number enter backwards into the input. Here is the information that I have so far on the issue:

  • in chrome on android 4.3 and 5.1
  • on android 4.3, all numbers are entered backwards
  • on android 5.1, only the first and next number after a space is reversed

This also happens in the web view inside of apps on android. Has anyone else seen the issues of this? Is there a way we could detect that it won't work and abort payform on these devices that don't support it.

Thanks to everyone that contributes to this library it is awesome!

Cannot assign to read only property 'target' of object KeyboardEvent and InputEvent

What is the issue?

Validation and formatting are not triggered because of uncaught errors thrown in the _eventNormalize function on keyboard and input events. There is an attempt to assign values to readonly properties.

This occurs on latest Chrome, Firefox, and Safari.

_eventNormalize = function(listener) {
      return function(e) {
        if (e == null) {
          e = window.event;
        }
        e.target = e.target || e.srcElement; // Uncaught TypeError thrown here
        e.which = e.which || e.keyCode; // Uncaught TypeError thrown here too
        if (e.preventDefault == null) {
          e.preventDefault = function() {
            return this.returnValue = false;
          };
        }
        return listener(e);
      };
    };

Error Log:

Uncaught TypeError: Cannot assign to read only property 'target' of object '#<KeyboardEvent>'
    at HTMLInputElement.<anonymous> (payform.js:43)
(anonymous) @ payform.js:43
payform.js:43 Uncaught TypeError: Cannot assign to read only property 'target' of object '#<InputEvent>'
    at HTMLInputElement.<anonymous> (payform.js:43)

How to reproduce the issue?

  • Vendor the payform.js file
  • Reference the file using ES6 import (e.g. import payform from '../vendor/payform.js';)
  • Type a valid a credit card number and notice that the value will not format itself
  • See error logs in the browser console

Discussion

This behaviour only occurs when vendoring the distribution file. No errors are thrown if we install the package via npm and use require.

From what I understand, the _eventNormalize function was introduced to modify the event for legacy browser support (e.g. IE8).

According to MDN, the keyCode attribute is deprecated and should not be used when handling the keyboard event types (e.g. keydown) handled in payform.

Here is what I suggest to allow users to vendor payform:
1- Recreate a new event and assign target and which attributes
2- Drop support for legacy browsers?

What do you think? 🙂

DinersClub Validation

Hi All,
with the 1.3.0 version it does not validate the DinesClub starts with 309....

Example number 30932281347102
Checking into the code the regex has been changed.

Thanks,
Francesco

Amex credit card validation failure

Hi,

My credit card service provider has given me some test card numbers and the Amex card number is failing validation... is this an error with payform?

The number is 34343434343434

Thanks
Liam

How to detach events

Hello there! I started using payform today and thanks for all the hard work that has been put into this so far, it's really good!

I'm using the library in an SPA environment (React), and I've noticed that there is no way to detach event listeners from elements before removing them from the DOM.

Is this something that has been discussed before? I'm happy to take a stab at opening a PR for adding a couple of new methods to the payform API but I wanted to run it by you first to see if the interest was there and what kind of approach you'd prefer.

Thanks!

EDIT: To clarify, I'm currently using this: payform.cardNumberInput(input)

Caret moved to the end of input after change

Steps to reproduce

  • set up a card number input with auto formatting
  • begin to type in a card number, with enough digits to trigger formatting (eg 4242 42)
  • move caret position somewhere before the last digit, can be anywhere (eg 424|2 42)
  • delete a digit (for instance the second 4 of the example: 42|2 42)

Caret is then moved to the end of input (eg. 4224 2|).

(Edit) The same goes when adding a digit in the middle of the current value

  • set up a card number input with auto formatting
  • begin to type in a card number, with enough digits to trigger formatting (eg 4242 42)
  • move caret position somewhere before the last digit, can be anywhere (eg 424|2 42)
  • add a digit (eg. 4248|2 42)

Caret is then moved to the end of input (eg. 4248 242|).

Reproduced on https://jondavidjohn.github.io/payform/

This bug occurs as long as there are enough digits to trigger the formatting. If there is fewer chars (id est, only three digits), the caret position is not changed

Expected behavior

Caret position should not change

Inconsistent full-width to half-width mapping in Safari

What is the issue?

Inconsistency between an element's input value and Input Method Editor (IME) editor when using full-width to half-width character mapping on desktop Safari. This feature works fine on latest Chrome and Firefox.

How to reproduce the issue?

1- Go on Payform's demo page on desktop Safari

2- Select Hiragana as your input source name.

3- Begin typing digits in any of the fields restricted to numeric input.

4- Notice how the IME value is different from the target's input value (i.e. 5338 vs 5535 3353 38)

Small GIF demonstrating the inconsistency between the input field and the value in IME:
Japanese IME bug

Discussion

The following table showcases all event types raised when typing 4242 across all major browsers (see W3C's offical key event viewer):

From top to bottom: Firefox, Opera, Safari, and Chrome
ui-keyboard-events-jpn-ime

After debugging and inspecting events, Safari handles keyboard events differently while typing with Japanese IME. While the browser surfaces insertCompositionText inputType, we notice that the input field value changes despite the fact that isComposing's value is false.

Credit card numbers are displayed backwards when used in a RTL context

What is the issue?

Right-to-Left (RTL) directionality causes the credit card field formatter input value to be displayed backwards.

How to reproduce the issue?

1- Create an instance of a Payform field formatter input (i.e. credit card number)

2- Use either HTML, CSS or JS to set the element's directionality to right-to-left.

HTML: dir="rtl"

CSS: direction: rtl

JS:

const ccInput = document.querySelector("#cc"); 
ccInput.dir = "rtl"; 

3- Begin typing a credit card number. For example, typing 1234 5678 will format into 5678 1234 instead of 1234 5678.

Discussion

A lot comes into play when talking about directionality (see W3C's article on Handling RTL scripts and the official Unicode Bidirectional Algorithm documentation). I will try to explain why the current state of the inputs do not display credit card numbers correctly:

1- Numbers in RTL scripts run left-to-right within the right-to-left flow and behave differently than words. In fact numbers are known to to have weak directionality.

2- Given a native HTML input and with its directionality set to RTL:

  • Typing 12345678 will give us 12345678.
  • Typing 1234 5678 will give us 5678 1234.
  • Typing CC 1234 5678 will give us CC 1234 5678.
  • Typing 1234 5678 CC will give us CC 5678 1234.

https://codepen.io/dramosrg/pen/MBWLXa

Because of this weak directionality, numbers are seen as part of the surrounding context. Without words to provide context of the input, elements cannot determine if the number being typed should be interpreted as a credit card number.

Since users are most likely to know that they will be typing credit card numbers, I believe that it is fair to assume that their credit card number should be displayed in a left-to-right fashion.

Therefore, typing 1234 5678 in a credit card field with a RTL flow should display 1234 5678.

Stripe makes use of these conventions and displays credit card numbers similarly.

Diners Club Formatting

It seems the diners club formating is wrong.

Stripe testing has 3056 9309 0259 04 as diners club sample test card
https://stripe.com/docs/testing

I believe the format should be: /(\d{1,4})(\d{1,4})?(\d{1,4})?(\d{1,2})?/

{ type: 'dinersclub' pattern: /^3[0689]/ format: /(\d{1,4})(\d{1,6})?(\d{1,4})?/ length: [14] cvcLength: [3] luhn: true }

More maintainers?

@jondavidjohn, I was wondering if you wouldn't appreciate splitting responsibilities a little more so that the community as a whole could benefit from the hard work you put on this repo.

I find that it is pretty hard nowadays to be lucky enough to maintain a full-time job + open source project such as this one. Maybe if we had more contributors with rights to merge PRs and do releases this could help you out.

The suggestion I have for now is @ddayguerrero, who's working with me on implementing this, but highly responsible for the hands on process.

What do you think?

Incorporate changes upstream

I'm glad to see you giving a little love to the jquery.payment codebase, but confused as to why you didn't propose these changes in a Pull Request against the original repository.

I'm sure other users would benefit from the dependency reduction and addition of UMD, and we would certainly be willing to take improvements to the logistical pieces of the repo (such as the Travis CI automation you added).

Would you consider packaging these up into a PR?

uncaught typeerror $(...)payform is not a function

<script src="https://code.jquery.com/jquery-1.11.2.min.js" type="text/javascript" charset="utf-8"></script> <script src="~/payform-master/dist/jquery.payform.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> $(document).on('change', '#CreditCardNo', function () { $('#CreditCardNo').payform('formatCardNumber'); $('#expiry').payform('formatCardExpiry'); $('#CVC').payform('formatCardCVC'); $('#numeric').payform('formatNumeric'); }); </script>

asass

I am coding in ASP.NET MVC 5 and i am facing the error uncaught typeerror $(...)payform is not a function and i m stuck here i included all the libraries in my project downloaded from GitHub Jquery

Offset caret position when formatting full-width characters

What is the issue?

Caret position is offset by 1 when credit card number and/or expiry inputs are formatted while typing in full-width.
Note that this issue is related to #20.

How to reproduce the issue?

1- Set keyboard to an input source with full-width characters — any Chinese, Japanese, or Korean (CJK) input such as Hiragana will suffice.

2- Use either of the following formatting helpers on a <input> element:

  • payform.cardNumberInput(input)
  • payform.cardExpiryInput(input)

3- Start typing a valid date or credit card value (e.g. 4012 8888 8888 1881)

4- As the value gets formatted (e.g. addition of a whitespace or /), see that the caret position is offset.

How does it affect users?

  • Unable to select all input via shortcuts due to wrong selection range
  • Mistyped credit card numbers
  • Invalid card expiry values

Input event is prevented on auto-formatting

Hello!

Thank you for this great module!

However, when using auto-formatter and entering the numbers into input field, some events are prevented. This happens right before space character is automatically inserted, e.g. when entering 5213 2…:

  • 5, got events
  • 2, got events
  • 1, got events
  • 3, space is inserted, events are not fired
  • 2, got events

This makes data-binding to fail, because we can't know when value is changed (I'm integrating it with custom Angular 2+ component).

What could be done about this?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.