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

Add Paydirekt provider #155

Open
wants to merge 49 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
22f49c4
capture is not neccessary final
devkral Oct 6, 2017
5ab5c68
improve documentation, fix logic and add return values
devkral Oct 6, 2017
7a0f2e4
split logic and model, replace address data with function
devkral Oct 6, 2017
0dc734e
split address into get_billing_address, get_shipping_address function…
devkral Oct 6, 2017
380ac73
don't crash if a signal client crashes but log error
devkral Oct 6, 2017
d014dbf
fix wrong initial value in test
devkral Oct 6, 2017
dfe71b6
fix inverted calculation
devkral Oct 6, 2017
ec5428e
Merge branch 'split_logic' into bogo_providers
devkral Oct 6, 2017
2f712e8
add test for robust signal handling
devkral Oct 7, 2017
b618a42
remove superfluous newlines
devkral Oct 7, 2017
03eb55c
don't test with assertLogs if not available
devkral Oct 7, 2017
932467a
add not well tested but not failing paydirekt provider
devkral Oct 7, 2017
5b6f807
paydirekt fixes, add item support
devkral Oct 8, 2017
52fb423
fix tests and missing simplejson dependency
devkral Oct 8, 2017
7d12afd
Merge branch 'split_logic' into paydirekt_branch
devkral Oct 8, 2017
49cc6ad
improve paydirekt api, add tests
devkral Oct 8, 2017
736e16a
simplejson only required from paydirekt, and a comma is missing
devkral Oct 8, 2017
a8051d0
Merge branch 'split_logic' into paydirekt_branch
devkral Oct 8, 2017
cd6ab1c
python2 support, fix tests, enable additional address informations
devkral Oct 8, 2017
cee3967
speed up extract_streetnr, fix possible regex attack
devkral Oct 8, 2017
5fa9635
Merge branch 'split_logic' into paydirekt_branch
devkral Oct 8, 2017
9ded5b6
fix order test
devkral Oct 8, 2017
815361f
tests and bugfixes for paydirekt
devkral Oct 9, 2017
579d287
fix retrieving transaction, make it thread safe, better handling of o…
devkral Oct 9, 2017
dacb622
fixes for paydirekt, update paydirekt tests
devkral Oct 9, 2017
fdcef46
fix change_status logic: send only signal if status changes
devkral Oct 9, 2017
68c1b99
Merge branch 'better_methods' into paydirekt_branch
devkral Oct 9, 2017
6ce254a
fix refund logic
devkral Oct 9, 2017
888b725
Merge branch 'fix_signals' into better_methods
devkral Oct 9, 2017
646552d
Merge branch 'better_methods' into paydirekt_branch
devkral Oct 9, 2017
fb0a31e
fix string instead Decimal bug for empty values
devkral Oct 9, 2017
6f29120
remove unneeded authentification
devkral Oct 9, 2017
bea26ac
ignore invalid callbacks, improve and fix paydirekt provider, test ag…
devkral Oct 11, 2017
281bae1
fix refund all
devkral Oct 12, 2017
386cc30
set refund limit to 100%
devkral Oct 12, 2017
5019c9e
allow responses without transaction_id and delay in case none is avai…
devkral Oct 12, 2017
8e06926
fix tests, bug only existed there
devkral Oct 12, 2017
5ca8e1a
ignore invalid requests again
devkral Oct 12, 2017
9316a12
use umlauts instead escape sequence
devkral Oct 12, 2017
fc9551e
update documentation
devkral Oct 12, 2017
cec94bb
Merge branch 'better_methods' into paydirekt_branch
devkral Oct 12, 2017
0ec5816
replace extract_streetnr with split_streetnr
devkral Oct 12, 2017
df6b6d9
Merge branch 'split_logic' into paydirekt_branch
devkral Oct 12, 2017
42c62e5
use split_streetnr instead extract_streetnr (cleaner results)
devkral Oct 12, 2017
91923e4
fix use before create
devkral Oct 12, 2017
598ff9a
protect against lingering connections
devkral Oct 17, 2017
fae58f2
fix generation of tokens
devkral Oct 17, 2017
2dfc994
improve ordering, Timeouts, fix 3 second hole
devkral Oct 17, 2017
823028e
fix token generation
devkral Oct 17, 2017
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
18 changes: 9 additions & 9 deletions payments/authorizenet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@ def __init__(self, login_id, transaction_key,
'Authorize.Net does not support pre-authorization.')

def get_transactions_data(self, payment):
data = {
billing = payment.get_billing_address()
return {
'x_amount': payment.total,
'x_currency_code': payment.currency,
'x_description': payment.description,
'x_first_name': payment.billing_first_name,
'x_last_name': payment.billing_last_name,
'x_address': "%s, %s" % (payment.billing_address_1,
payment.billing_address_2),
'x_city': payment.billing_city,
'x_zip': payment.billing_postcode,
'x_country': payment.billing_country_area
'x_first_name': billing["first_name"],
'x_last_name': billing["last_name"],
'x_address': "%s, %s" % (billing["address_1"],
billing["address_2"]),
'x_city': billing["city"],
'x_zip': billing["postcode"],
'x_country': billing["country_area"]
}
return data

def get_product_data(self, payment, extra_data=None):
data = self.get_transactions_data(payment)
Expand Down
27 changes: 6 additions & 21 deletions payments/authorizenet/test_authorizenet.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from __future__ import unicode_literals
from unittest import TestCase
from mock import patch, MagicMock, Mock
try:
from unittest.mock import patch, MagicMock
except ImportError:
from mock import patch, MagicMock

from . import AuthorizeNetProvider
from .. import PaymentStatus, RedirectNeeded
from ..testcommon import create_test_payment


LOGIN_ID = 'abcd1234'
Expand All @@ -18,26 +22,7 @@
STATUS_CONFIRMED = '1'


class Payment(Mock):
id = 1
variant = 'authorizenet'
currency = 'USD'
total = 100
status = PaymentStatus.WAITING
transaction_id = None
captured_amount = 0

def get_process_url(self):
return 'http://example.com'

def get_failure_url(self):
return 'http://cancel.com'

def get_success_url(self):
return 'http://success.com'

def change_status(self, status):
self.status = status
Payment = create_test_payment()



Expand Down
22 changes: 12 additions & 10 deletions payments/braintree/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,22 @@ def get_credit_card_clean_data(self):
'expiration_year': self.cleaned_data.get('expiration').year}

def get_billing_data(self):
billing = self.payment.get_billing_address()
return {
'first_name': self.payment.billing_first_name,
'last_name': self.payment.billing_last_name,
'street_address': self.payment.billing_address_1,
'extended_address': self.payment.billing_address_2,
'locality': self.payment.billing_city,
'region': self.payment.billing_country_area,
'postal_code': self.payment.billing_postcode,
'country_code_alpha2': self.payment.billing_country_code}
'first_name': billing["first_name"],
'last_name': billing["last_name"],
'street_address': billing["address_1"],
'extended_address': billing["address_2"],
'locality': billing["city"],
'region': billing["country_area"],
'postal_code': billing["postcode"],
'country_code_alpha2': billing["country_code"]}

def get_customer_data(self):
billing = self.payment.get_billing_address()
return {
'first_name': self.payment.billing_first_name,
'last_name': self.payment.billing_last_name}
'first_name': billing["first_name"],
'last_name': billing["last_name"]}

def save(self):
braintree.Transaction.submit_for_settlement(self.transaction_id)
Expand Down
27 changes: 6 additions & 21 deletions payments/braintree/test_braintree.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from __future__ import unicode_literals
from unittest import TestCase
from mock import patch, MagicMock, Mock
try:
from unittest.mock import patch, MagicMock
except ImportError:
from mock import patch, MagicMock

from . import BraintreeProvider
from .. import PaymentStatus, RedirectNeeded
from ..testcommon import create_test_payment


MERCHANT_ID = 'test11'
Expand All @@ -18,26 +22,7 @@
'cvv2': '1234'}


class Payment(Mock):
id = 1
variant = 'braintree'
currency = 'USD'
total = 100
status = PaymentStatus.WAITING
transaction_id = None
captured_amount = 0

def get_process_url(self):
return 'http://example.com'

def get_failure_url(self):
return 'http://cancel.com'

def get_success_url(self):
return 'http://success.com'

def change_status(self, status):
self.status = status
Payment = create_test_payment()


class TestBraintreeProvider(TestCase):
Expand Down
35 changes: 6 additions & 29 deletions payments/coinbase/test_coinbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
import json
from decimal import Decimal
from unittest import TestCase
try:
from unittest.mock import patch, MagicMock
except ImportError:
from mock import patch, MagicMock

from django.http import HttpResponse, HttpResponseForbidden
from mock import MagicMock, patch

from .. import PaymentStatus
from . import CoinbaseProvider
from ..testcommon import create_test_payment

PAYMENT_TOKEN = '5a4dae68-2715-4b1e-8bb2-2c2dbe9255f6'
KEY = 'abc123'
Expand All @@ -23,34 +27,7 @@
PAYMENT_TOKEN, KEY)).encode('utf-8')).hexdigest()}}


class Payment(object):

id = 1
description = 'payment'
currency = 'BTC'
total = Decimal(100)
status = PaymentStatus.WAITING
token = PAYMENT_TOKEN
variant = VARIANT

def change_status(self, status):
self.status = status

def get_failure_url(self):
return 'http://cancel.com'

def get_process_url(self):
return 'http://example.com'

def get_purchased_items(self):
return []

def save(self):
return self

def get_success_url(self):
return 'http://success.com'

Payment = create_test_payment(variant=VARIANT, token=PAYMENT_TOKEN, description='payment', currency='BTC', total=Decimal(100))

class TestCoinbaseProvider(TestCase):

Expand Down
9 changes: 6 additions & 3 deletions payments/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ def get_base_url():
"""
Returns host url according to project settings. Protocol is chosen by
checking PAYMENT_USES_SSL variable.
If PAYMENT_HOST is not specified, gets domain from Sites.
Otherwise checks if it's callable and returns it's result. If it's not a
If PAYMENT_HOST is not specified, gets domain from Sites.
Otherwise checks if it's callable and returns it's result. If it's not a
callable treats it as domain.
"""
protocol = 'https' if PAYMENT_USES_SSL else 'http'
Expand Down Expand Up @@ -92,13 +92,16 @@ def get_return_url(self, payment, extra_data=None):
return url + '?' + qs
return url

def capture(self, payment, amount=None):
def capture(self, payment, amount=None, final=True):
''' Capture a fraction of the total amount of a payment. Return amount captured or None '''
raise NotImplementedError()

def release(self, payment):
''' Annilates captured payment '''
raise NotImplementedError()

def refund(self, payment, amount=None):
''' Refund payment, return amount which was refunded or None '''
raise NotImplementedError()


Expand Down
19 changes: 10 additions & 9 deletions payments/cybersource/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def charge(self, payment, data):
self._set_proper_payment_status_from_reason_code(
payment, response.reasonCode)

def capture(self, payment, amount=None):
def capture(self, payment, amount=None, final=True):
if amount is None:
amount = payment.total
params = self._prepare_capture(payment, amount=amount)
Expand Down Expand Up @@ -366,15 +366,16 @@ def _prepare_card_data(self, data):
return card

def _prepare_billing_data(self, payment):
_billing_address = payment.get_billing_address()
billing = self.client.factory.create('data:BillTo')
billing.firstName = payment.billing_first_name
billing.lastName = payment.billing_last_name
billing.street1 = payment.billing_address_1
billing.street2 = payment.billing_address_2
billing.city = payment.billing_city
billing.postalCode = payment.billing_postcode
billing.country = payment.billing_country_code
billing.state = payment.billing_country_area
billing.firstName = _billing_address["first_name"]
billing.lastName = _billing_address["last_name"]
billing.street1 = _billing_address["address_1"]
billing.street2 = _billing_address["address_2"]
billing.city = _billing_address["city"]
billing.postalCode = _billing_address["postcode"]
billing.country = _billing_address["country_code"]
billing.state = _billing_address["country_area"]
billing.email = payment.billing_email
billing.ipAddress = payment.customer_ip_address
return billing
Expand Down
42 changes: 10 additions & 32 deletions payments/cybersource/test_cybersource.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
from decimal import Decimal
from unittest import TestCase
from django.core import signing
from mock import patch, MagicMock, Mock
try:
from unittest.mock import patch, MagicMock
except ImportError:
from mock import patch, MagicMock

from . import CyberSourceProvider, AUTHENTICATE_REQUIRED, ACCEPTED, \
TRANSACTION_SETTLED
from .. import PaymentStatus, PurchasedItem, RedirectNeeded

from ..testcommon import create_test_payment

MERCHANT_ID = 'abcd1234'
PASSWORD = '1234abdd1234abcd'
ORG_ID = 'abc'
Expand All @@ -20,40 +25,13 @@
'cvv2': '1234',
'fingerprint': 'abcd1234'}


class Payment(Mock):
id = 1
variant = 'cybersource'
currency = 'USD'
total = 100
status = PaymentStatus.WAITING
transaction_id = None
captured_amount = 0
message = ''

_Payment = create_test_payment()
class Payment(_Payment):
# MagicMock is not serializable so overwrite attrs Proxy
class attrs(object):
fingerprint_session_id = 'fake'
merchant_defined_data = {}

def get_process_url(self):
return 'http://example.com'

def get_failure_url(self):
return 'http://cancel.com'

def get_success_url(self):
return 'http://success.com'

def change_status(self, status, message=''):
self.status = status
self.message = message

def get_purchased_items(self):
return [
PurchasedItem(
name='foo', quantity=Decimal('10'), price=Decimal('20'),
currency='USD', sku='bar')]

capture = {}

class TestCybersourceProvider(TestCase):

Expand Down
25 changes: 6 additions & 19 deletions payments/dotpay/test_dotpay.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
from unittest import TestCase

from django.http import HttpResponse, HttpResponseForbidden
from mock import MagicMock, Mock
try:
from unittest.mock import MagicMock
except ImportError:
from mock import MagicMock

from .. import PaymentStatus
from .forms import ACCEPTED, REJECTED
from . import DotpayProvider
from ..testcommon import create_test_payment

VARIANT = 'dotpay'
PIN = '123'
Expand Down Expand Up @@ -45,24 +49,7 @@ def get_post_with_md5(post):
return post


class Payment(Mock):
id = 1
variant = VARIANT
currency = 'USD'
total = 100
status = PaymentStatus.WAITING

def get_process_url(self):
return 'http://example.com'

def get_failure_url(self):
return 'http://cancel.com'

def get_success_url(self):
return 'http://success.com'

def change_status(self, status):
self.status = status
Payment = create_test_payment(variant=VARIANT, id=1, currency='USD')


class TestDotpayProvider(TestCase):
Expand Down
2 changes: 1 addition & 1 deletion payments/dummy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def process_data(self, payment, request):
return HttpResponseRedirect(payment.get_success_url())
return HttpResponseRedirect(payment.get_failure_url())

def capture(self, payment, amount=None):
def capture(self, payment, amount=None, final=True):
payment.change_status(PaymentStatus.CONFIRMED)
return amount

Expand Down
Loading