Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated 'no_shipping' and 'rm' options for PayPalPaymentsForm #21

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ Using PayPal Payments Standard IPN:
...
INSTALLED_APPS = (... 'paypal.standard.ipn', ...)
...
PAYPAL_TEST = False # sandbox or not mode and True for live mode
PAYPAL_RECEIVER_EMAIL = "[email protected]"
PAYPAL_IMAGE = 'https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif'
# default button image is http://images.paypal.com/images/x-click-but01.gif, for a list see:
# https://cms.paypal.com/cms_content/US/en_US/files/developer/paypal_button_chart_en.html

1. Create an instance of the `PayPalPaymentsForm` in the view where you would
like to collect money. Call `render` on the instance in your template to
Expand All @@ -45,6 +49,8 @@ Using PayPal Payments Standard IPN:
# What you want the button to do.
paypal_dict = {
"business": "[email protected]",
#"image": "https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif"
"image_url": "http://www.example.com/your-header-logo-image.jpg", # max height: 98px width: 794px
"amount": "10000000.00",
"item_name": "name of the item",
"invoice": "unique-invoice-id",
Expand All @@ -65,6 +71,25 @@ Using PayPal Payments Standard IPN:
<h1>Show me the money!</h1>
<!-- writes out the form tag automatically -->
{{ form.render }}

a. Alternatively you can create an intermediate view that performs pre-payment required processing and
then redirects to the PayPal processing page.

class PaymentPreProcessView(RedirectView):
""" Verifies cart is ready for payment - things like shipping cost is calculated """
permanent = False

def get_redirect_url(self, **kwargs):
""" Return the URL redirect to. URL matches are passed as kwargs"""
...
pre-payment code here
...
paypal_dict = {
"business": "[email protected]",
... }

form = PayPalPaymentsForm(initial=paypal_dict)
return form.render_as_GET_url()

1. When someone uses this button to buy something PayPal makes a HTTP POST to
your "notify_url". PayPal calls this Instant Payment Notification (IPN).
Expand Down
6 changes: 3 additions & 3 deletions paypal/pro/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


class PayPalNVPAdmin(admin.ModelAdmin):
list_display = ('user', 'ipaddress', 'method', 'flag', 'flag_code', 'created_at')
list_filter = ('flag', 'created_at')
search_fields = ('user__email', 'ip_address', 'flag', 'firstname', 'lastname')
list_display = ('user', 'ipaddress', 'method', 'flag', 'flag_code', 'created_at')
list_filter = ('flag', 'created_at')
search_fields = ('user__email', 'ip_address', 'flag', 'firstname', 'lastname')
admin.site.register(PayPalNVP, PayPalNVPAdmin)
90 changes: 45 additions & 45 deletions paypal/pro/creditcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,68 +2,68 @@
# -*- coding: utf-8 -*-
"""
Adapted from:
- http://www.djangosnippets.org/snippets/764/
- http://www.satchmoproject.com/trac/browser/satchmo/trunk/satchmo/apps/satchmo_utils/views.py
- http://tinyurl.com/shoppify-credit-cards
- http://www.djangosnippets.org/snippets/764/
- http://www.satchmoproject.com/trac/browser/satchmo/trunk/satchmo/apps/satchmo_utils/views.py
- http://tinyurl.com/shoppify-credit-cards
"""
import re


# Well known card regular expressions.
CARDS = {
'Visa': re.compile(r"^4\d{12}(\d{3})?$"),
'Mastercard': re.compile(r"^(5[1-5]\d{4}|677189)\d{10}$"),
'Dinersclub': re.compile(r"^3(0[0-5]|[68]\d)\d{11}$"),
'Amex': re.compile("^3[47]\d{13}$"),
'Discover': re.compile("^(6011|65\d{2})\d{12}$"),
'Visa': re.compile(r"^4\d{12}(\d{3})?$"),
'Mastercard': re.compile(r"^(5[1-5]\d{4}|677189)\d{10}$"),
'Dinersclub': re.compile(r"^3(0[0-5]|[68]\d)\d{11}$"),
'Amex': re.compile("^3[47]\d{13}$"),
'Discover': re.compile("^(6011|65\d{2})\d{12}$"),
}

# Well known test numbers
TEST_NUMBERS = [
"378282246310005", "371449635398431", "378734493671000", "30569309025904",
"38520000023237", "6011111111111117", "6011000990139424", "555555555554444",
"5105105105105100", "4111111111111111", "4012888888881881", "4222222222222"
"378282246310005", "371449635398431", "378734493671000", "30569309025904",
"38520000023237", "6011111111111117", "6011000990139424", "555555555554444",
"5105105105105100", "4111111111111111", "4012888888881881", "4222222222222"
]

def verify_credit_card(number):
"""Returns the card type for given card number or None if invalid."""
return CreditCard(number).verify()
"""Returns the card type for given card number or None if invalid."""
return CreditCard(number).verify()

class CreditCard(object):
def __init__(self, number):
self.number = number
def __init__(self, number):
self.number = number

def is_number(self):
"""True if there is at least one digit in number."""
self.number = re.sub(r'[^\d]', '', self.number)
return self.number.isdigit()
def is_number(self):
"""True if there is at least one digit in number."""
self.number = re.sub(r'[^\d]', '', self.number)
return self.number.isdigit()

def is_mod10(self):
"""Returns True if number is valid according to mod10."""
double = 0
total = 0
for i in range(len(self.number) - 1, -1, -1):
for c in str((double + 1) * int(self.number[i])):
total = total + int(c)
double = (double + 1) % 2
return (total % 10) == 0
def is_mod10(self):
"""Returns True if number is valid according to mod10."""
double = 0
total = 0
for i in range(len(self.number) - 1, -1, -1):
for c in str((double + 1) * int(self.number[i])):
total = total + int(c)
double = (double + 1) % 2
return (total % 10) == 0

def is_test(self):
"""Returns True if number is a test card number."""
# Note: test numbers cannot be used in the PP Pro sandbox.
# Instead, use the credit card number associated with a
# sandbox account (Test Accounts -> View Details).
return self.number in TEST_NUMBERS
def is_test(self):
"""Returns True if number is a test card number."""
# Note: test numbers cannot be used in the PP Pro sandbox.
# Instead, use the credit card number associated with a
# sandbox account (Test Accounts -> View Details).
return self.number in TEST_NUMBERS

def get_type(self):
"""Return the type if it matches one of the cards."""
for card, pattern in CARDS.iteritems():
if pattern.match(self.number):
return card
return None
def get_type(self):
"""Return the type if it matches one of the cards."""
for card, pattern in CARDS.iteritems():
if pattern.match(self.number):
return card
return None

def verify(self):
"""Returns the card type if valid else None."""
if self.is_number() and not self.is_test() and self.is_mod10():
return self.get_type()
return None
def verify(self):
"""Returns the card type if valid else None."""
if self.is_number() and not self.is_test() and self.is_mod10():
return self.get_type()
return None
Loading