71 comments

[ 3.5 ms ] story [ 131 ms ] thread
The thing I love about stripe is that they're so focused on building the best customer experience and software that solves customer problems!
> The thing I love about stripe is that they're so focused on building the best customer experience and software that solves customer problems!

As long as your customer problems are not about low fees or ACH, that is.

The JS load is failing on this page. :(

  Failed to load resource: the server responded with a status of 403 (Forbidden) https://raw.github.com/stripe/jquery.payment/master/lib/jquery.payment.js
  
  Uncaught TypeError: Object [object Object] has no method 'formatCardNumber' jquery-payment:50
Refresh fixed that for me.
Hm. I'm still getting the 403. I emailed them just in case.
Same here. Might be due to serving from raw.github.com. AFAIK it's not meant to be used as a CDN.
Fixed! Thanks for the heads up.
Very nice. They just keep making it easier and easier to use their service. Good job @stripe!
EDIT 2: appears that the issue was fixed: https://github.com/stripe/jquery.payment/issues/1

Original Message: The card number is not linked to the CVV length:

343725117665768 is a valid american express number (generated from http://www.getcreditcardnumbers.com/)

Their CVV numbers are 4 digits, yet the inputs

    343725117665768
    12 / 21
    123
seems to pass ...

EDIT: filed issue: https://github.com/stripe/jquery.payment/issues/1

Also, you can enter "12/999" as expiry date, YYY. This probably just means some of the validations are done after data is submitted.
That's correct, we don't stop people entering invalid dates -- we just validate them after they do so.
We make it easy to do card type-specific CVC validation:

  $.validateCardCVC('1234', 'amex');
More at https://github.com/stripe/jquery.payment.
I would think a combined validateCardAndCVV (taking both the card number and the CVV) would be the correct approach here ...
(comment deleted)
This looks nice, but I ran into an immediate usability issue. The Card Expiry requires a leading 0 for January. It seems like bad UI to prevent a user from enter 1/13 or 1/2013 in those fields.
We don't prevent that. If you type '1/' the library turns it into '01 / '.
Fair enough, I haven't dug into the code yet. I was basing my comment on the live demo which prevents it.
Huh? If you literally type '1/13' into the live demo it works as one would expect. '113' works too, it just assumes the month is eleven, and the year starts with 3.
I was referring to the live demo at http://stripe.github.com/jquery.payment/example/. Either way, I wouldn't consider the library interpreting 113 as 11/3 as a "working".
So what do you suggest "113" should be interpreted as?
I think he's suggesting that 113 should be interpreted as 1/13. I'm not sure how simple that logic would be to implement, though.
113 is ambiguous. Its an error
There are three ways to interpret it. It is either 11/3, 1/13, or an error. Since 11/3 isn't a valid date, I think it is safe to rule that out as an incorrect interpretation. Either of the other two interpretations seem acceptable to me.
Er, since when is 11/3 not a valid date?
Not for a credit card expiration date...
How would you type in 11/30 if it blurts out a big error the moment you type 113?
The same way the system allows you to type in 0213 without blurting out a big error the moment you type 02. Just don't validate the input while the user is still inputting it.

Secondly, remember this is for credit card expirations and not normal dates. You can probably make an assumption that 11/30 (November 2030) isn't currently valid input either. I have never seen an expiration date further than 10 years in the future. Although more research on the topic would be needed to figure out the true restrictions.

I don't know why the live demo is broken, or why they even need is since there is a live demo on the main page, but the usability for all cases strikes me as exceptional on the main page where it works as intended. I am not convinced that your cherry-picked restriction improves the usability.
If you literally type '1/13' into the live demo it interprets it as '11/3' because it does not allow a '/' character to be entered as cpeterso mentioned
There are several incorrect assumptions about this library

  Cards can be up to 19 digits
  Bin ranges are constantly updated, so cardType in static code is a broken concept.
  I expect in the future American Express will issues cards longer then 15 digits.
  Minimun card length is 13 digits not 10
I don't feel like validating the luhn check, but historically I've seen systems that don't correctly handle the luhn check of variable sizes.

Edit: Reference material http://en.wikipedia.org/wiki/Bank_card_number If you are actually getting into credit card processing, please talk to your acquirer about data feeds of this type of info on bin ranges.

Edit 2: Wikipedia claims Maestro has 12 digit cards, but I've never seen one in the wild, I could be wrong about 13, but it's the assumption we've made processing international payments.

(I work at Stripe.)

Thanks. I don't think these are so much incorrect assumptions so much as things we should change if the world changes.

19-digit IINs are found on UnionPay, Maestro, and other international cards that Stripe doesn't support today. We might add support for them in the future.

As to the others (e.g. American Express cards with more than 15 digits): we'll certainly add support if this changes.

We'll get UnionPay & Maestro support added shortly.
> Thanks. I don't think these are so much incorrect assumptions so much as things we should change if the world changes.

Is that not the definition of an assumption? Something you rely on being true and not changing, and which if it does change, requires reaction?

These are incorrect assumptions. It's okay to have them, you don't have to be perfect, but don't redefine "assumption" because you're embarrassed.

> These are incorrect assumptions. It's okay to have them, you don't have to be perfect, but don't redefine "assumption" because you're embarrassed.

What is there to be embarrassed about? Seriously.

It's not a redefinition of "assumption" but rather a justification as to why these assumptions should not be qualified as "incorrect".
Gimme a break. The assumptions are correct, for now. If they become incorrect, Stripe will update the software accordingly. This is exactly how good software is written and managed. Patrick has nothing to be embarrassed about.
I took the goal of the library as general purpose, not stripe purpose. Sorry for my personal incorrect assumption.
(comment deleted)
I do give them credit for accepting credit card numbers with spaces in them. It seems 99% of websites cannot handle spaces.
I have had this discussion a few times and at least for me it's usually sticking to ridiculous TOS from the payment gateway and less in programming competency. If your gateway says you're not allowed to change anything in the input and the gateway does not accept spaces you can either break your contract or not allow spaces.
> not allowed to change anything in the input

I've never seen such a term. Have any examples?

I worked for a gift card company and wrote and maintained some client side card validation code. My suggestion for client side card validation is "don't do it". As your client gets used more and more you will see a wild variety of cards. The minimum card length I have seen is 5. The maximum is 22. Some cards have correct checksum and some don't have checksum at all. Some cards have only numbers and some cards have letters and numbers. At the end we stripped all our fancy validation code and left only a check that card length was 3 or more.

All card validation must be server side.

Gift cards aren't credit cards. The docs say "a general purpose library for building credit card forms", not "a general purpose library for building payment forms".
How does it become easier to do such validation server-side?
You can attempt to process it through your payment gateway (ie. stripe) and check for a success or failure.
That becomes expensive. The more you can do on your own, the less in fee's you'll accumulate.
This is the reason why I don't like doing any client side validation of card data (beyond the basic check for empty fields).

I would much rather incur a 2-3sec browser roundtrip by posting raw payment details to my bank/gateway and allowing them to do the validation (they're presumably much better at it than I am).

Doing client side validation is too error prone, and considering that accepting card data is done so rarely, the (minimal) performance gain of JS validation isn't worth the risk of rejecting good data by accident.

You, but whatabout a laymen user who doesnt care ehat your justifications are? They want people to build snappy mobile web apps. This creates competition and legitimacy for them
Not really sure what point you're making. Validating on the server will incur a 2-10sec penalty once when entering payment data... the rest of your app is unaffected.
You have to pay for failed authorization attempts
Do you mean pay money for each auth attempt?? I've never heard of such a charge. Maybe time for a new gateway/bank?
You actually don't pay for failed auth attempts with Stripe, but you do with most other gateways.
This may be useful with Node too. I wish it wasn't a jQuery plugin but a framework independent library.

(I'm aware I can use jQuery on the server-side, but why load jQuery only for a credit card number validation library?)

Other than that, this looks good. :)

I love that you are running server side JavaScript, but loading jQuery is the part that feels unclean to you.
Node is very lightweight and fast... jQuery requires jsdom which means loading a virtual DOM environment which is very heavy for server-side processing.
No formatting occurs when input is pasted into the field. Is this by design?
The readme shows a `$.fn.formatCardNumber()` function, so I'd guess they left whether to manipulate the user input up to you.
This is why I love Stripe, thanks for contributing bits and pieces to Open Source world!
Supporting 4 digit years might help on the usability front. I'm probably a special case, but I forgot what the format was, as it disappears immediately upon clicking on the field, and naively went with a 4 digit format. There's no helpful error message on the demo page either -- the field just highlights in red.

I don't immediately how much is just how that form was constructed vs. what's done in the JS lib.

4 digit years are supported :)
Ahh, maybe it's the demo page that doesn't support them then? They came up as an error for me.
The fields seem nice, but use the cursor keys to edit and they fall apart.
Just because I like breaking things; they've tried to stop text getting into the fields by typing/pasting in the fields. A way around it is to highlight text/characters in the browser or the address bar etc and drag them into the field.
any hope for us poor souls that dwell outside of the United States?
Isn't it bad form to add 7 functions to the jQuery plugin 'namespace' in a single plugin?