[Checkins] SVN: z3c.schema/trunk/src/z3c/schema/payments/ Adding
z3c.schema.payments which provides a
Randy Crafton
randycrafton at gmail.com
Tue Dec 4 13:23:46 EST 2007
Log message for revision 82123:
Adding z3c.schema.payments which provides a
credit card schema type that validates a card
number against the ISO 7812 Card Industry standards.
This provides some level of error detection prior to
sending the card number to the payment processor.
Changed:
A z3c.schema/trunk/src/z3c/schema/payments/
A z3c.schema/trunk/src/z3c/schema/payments/README.txt
A z3c.schema/trunk/src/z3c/schema/payments/__init__.py
A z3c.schema/trunk/src/z3c/schema/payments/field.py
A z3c.schema/trunk/src/z3c/schema/payments/interfaces.py
A z3c.schema/trunk/src/z3c/schema/payments/tests.py
-=-
Added: z3c.schema/trunk/src/z3c/schema/payments/README.txt
===================================================================
--- z3c.schema/trunk/src/z3c/schema/payments/README.txt (rev 0)
+++ z3c.schema/trunk/src/z3c/schema/payments/README.txt 2007-12-04 18:23:46 UTC (rev 82123)
@@ -0,0 +1,130 @@
+===================
+z3c.schema.payments
+===================
+
+z3c.schema.payments provides some level of error detection in payment data
+prior to storing the information or sending it to a payment processor.
+Currently this module only supports validation of credit card numbers, but
+this could conceivably be extended to other payment forms
+
+
+------------
+Credit Cards
+------------
+
+Credit card numbering specifications are defined in ISO 7812-1:1983. Verifying
+that the credit card number supplied by a user conforms to the ISO standard
+provides some error checking which can catch typographical errors,
+transposition, etc. This does not validate the card against the financial
+networks as a valid account. However, verifying that the card number is well
+formed is fast and catching typographical errors in this way is much faster
+than sending the card number to a credit card processor.
+
+First, let's setup a credit card field:
+
+ >>> from z3c.schema.payments import CreditCard
+ >>> from z3c.schema.payments import interfaces
+ >>> cc = CreditCard()
+ >>> interfaces.IISO7812CreditCard.providedBy(cc)
+ True
+
+The simple restrictions are quick to check. Credit cards should be all numeric, no alpha characters allowed:
+
+ >>> cc.constraint('44444444444AAAA8')
+ False
+
+ >>> cc.constraint('4444444444444448')
+ True
+
+Also, we can't have any returns or line endings in the number:
+
+ >>> cc.constraint('444444444444\n4448')
+ False
+
+ >>> cc.constraint('44444444\r44444448')
+ False
+
+One of the first specifications of ISO 7812 is a "Major Industry Identifier,"
+which is the first number of an ISO 7812 compliant account number. Originally,
+banking, financial, and merchandizing (store account) cards were limited to
+the major industry identifiers 4, 5, and 6. However American Express, Diner's
+Club, and Carte Blanche were all assigned a major industry number 3. So a
+valid card must start with one of these numbers:
+
+ >>> cc.validate(u'0000000000000000')
+ Traceback (most recent call last):
+ ...
+ NotValidISO7812CreditCard: 0000000000000000
+
+ >>> cc.validate(u'1111111111111117')
+ Traceback (most recent call last):
+ ...
+ NotValidISO7812CreditCard: 1111111111111117
+
+ >>> cc.validate(u'2222222222222224')
+ Traceback (most recent call last):
+ ...
+ NotValidISO7812CreditCard: 2222222222222224
+
+ >>> cc.validate(u'3333333333333331')
+ >>> cc.validate(u'4444444444444448')
+ >>> cc.validate(u'5555555555555557')
+ >>> cc.validate(u'3333333333333331')
+ >>> cc.validate(u'6666666666666664')
+
+ >>> cc.validate(u'7777777777777771')
+ Traceback (most recent call last):
+ ...
+ NotValidISO7812CreditCard: 7777777777777771
+
+ >>> cc.validate(u'8888888888888888')
+ Traceback (most recent call last):
+ ...
+ NotValidISO7812CreditCard: 8888888888888888
+
+ >>> cc.validate(u'9999999999999995')
+ Traceback (most recent call last):
+ ...
+ NotValidISO7812CreditCard: 9999999999999995
+
+The ISO specification also defines a check digit which should always
+be the last digit of a card number. The check digit is calculated using the
+Luhn (Mod 10) formula. In this way, each credit card number contains its own
+CRC of sorts. This is our main validation that a credit card number is well
+formed.
+
+Validating a number with a check digit that uses the LUHN formula:
+
+Step 1:
+Starting with the next-to-last digit and moving left, double the value of
+every other digit. The calculation starts with the next-to-last digit because
+the last digit is the check digit.
+
+* When selecting every other digit, always work right-to-left and do not start
+with the rightmost digit (since that is the check digit).
+* The last digit (check digit) is considered #1 (odd number) and the
+next-to-last digit is #2 (even number). You will only double the values of the even-numbered digits.
+
+Step 2:
+Add all unaffected digits to the values obtained in Step 1.
+
+* If any of the values resulting from Step 1 are double-digits, do not add the double-digit value to the total, but rather add the two digits, and add this sum to the total.
+
+Result:
+The total obtained in Step 2 must be a number ending in zero (exactly
+divisible by 10) for the number to be valid.
+
+The validate method of z3c.schema.payments.ISO7812CreditCard does the Luhn
+calculation on the provided card number. If the calculation fails, there is
+either an error in the number or the card is simply not valid. We use in our
+tests here and above numbers that technically meet the criteria of the ISO
+specification without the risk of the number actually being a valid card
+number registered with a financial institution:
+
+ >>> cc.validate(u'4444444444444448')
+ >>> cc.validate(u'4444444444444449')
+ Traceback (most recent call last):
+ ...
+ NotValidISO7812CreditCard: 4444444444444449
+
+
\ No newline at end of file
Added: z3c.schema/trunk/src/z3c/schema/payments/__init__.py
===================================================================
--- z3c.schema/trunk/src/z3c/schema/payments/__init__.py (rev 0)
+++ z3c.schema/trunk/src/z3c/schema/payments/__init__.py 2007-12-04 18:23:46 UTC (rev 82123)
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+from z3c.schema.payments.interfaces import *
+from z3c.schema.payments.field import isValidCreditCard
+from z3c.schema.payments.field import ISO7812CreditCard
+from z3c.schema.payments.field import ISO7812CreditCard as CreditCard
\ No newline at end of file
Property changes on: z3c.schema/trunk/src/z3c/schema/payments/__init__.py
___________________________________________________________________
Name: svn:keywords
+ "Id"
Added: z3c.schema/trunk/src/z3c/schema/payments/field.py
===================================================================
--- z3c.schema/trunk/src/z3c/schema/payments/field.py (rev 0)
+++ z3c.schema/trunk/src/z3c/schema/payments/field.py 2007-12-04 18:23:46 UTC (rev 82123)
@@ -0,0 +1,61 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+import zope.interface
+import interfaces
+
+def isValidCreditCard(cardNum):
+ """Returns True if the credit card number is a valid Luhn (Mod 10) number
+ and False if not. This, of course, does not validate the number, but
+ will catch typos. There is the chance that two typographic errors could
+ return a false positive if they offset one anoter, but the likelihood
+ is low and pre-validating is fast"""
+
+ financialIndustries = ['3','4','5','6']
+ if cardNum[1] not in financialIndustries:
+ return False
+
+ total = pos = 0
+ for digit in cardNum[::-1]:
+ if pos % 2 == 0:
+ multiplier = 1
+ else:
+ multiplier = 2
+ product = int(digit) * multiplier
+ total += product / 10 + product % 10
+ pos += 1
+ if total % 10 == 0:
+ return True
+ return False
+
+class ISO7812CreditCard(zope.schema.TextLine):
+ """A valid ISO 7812 credit card number."""
+ __doc__ = interfaces.IISO7812CreditCard.__doc__
+
+ zope.interface.implements(interfaces.IISO7812CreditCard)
+
+ def constraint(self, value):
+ allDigits = True
+ for char in value[:]:
+ if not char.isdigit():
+ allDigits = False
+ return '\n' not in value and '\r' not in value and allDigits
+
+ def _validate(self, value):
+ super(ISO7812CreditCard, self)._validate(value)
+ if not isValidCreditCard(value):
+ raise interfaces.NotValidISO7812CreditCard(value)
\ No newline at end of file
Property changes on: z3c.schema/trunk/src/z3c/schema/payments/field.py
___________________________________________________________________
Name: svn:keywords
+ "Id"
Added: z3c.schema/trunk/src/z3c/schema/payments/interfaces.py
===================================================================
--- z3c.schema/trunk/src/z3c/schema/payments/interfaces.py (rev 0)
+++ z3c.schema/trunk/src/z3c/schema/payments/interfaces.py 2007-12-04 18:23:46 UTC (rev 82123)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+__docformat__ = "reStructuredText"
+
+import zope.schema
+import zope.schema.interfaces
+from z3c.schema.i18n import MessageFactory as _
+
+class IISO7812CreditCard(zope.schema.interfaces.ITextLine):
+ """A credit card with a valid check digit"""
+
+class NotValidISO7812CreditCard(zope.schema.ValidationError):
+ __doc__ = _("""The credit card number is incorrect.""")
\ No newline at end of file
Property changes on: z3c.schema/trunk/src/z3c/schema/payments/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ "Id"
Added: z3c.schema/trunk/src/z3c/schema/payments/tests.py
===================================================================
--- z3c.schema/trunk/src/z3c/schema/payments/tests.py (rev 0)
+++ z3c.schema/trunk/src/z3c/schema/payments/tests.py 2007-12-04 18:23:46 UTC (rev 82123)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+__docformat__ = "reStructuredText"
+
+import unittest
+from zope.testing import doctest
+from zope.testing.doctestunit import DocFileSuite
+
+
+def test_suite():
+ return unittest.TestSuite((
+ DocFileSuite('README.txt',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,),
+ ))
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: z3c.schema/trunk/src/z3c/schema/payments/tests.py
___________________________________________________________________
Name: svn:keywords
+ "Id"
More information about the Checkins
mailing list