diff --git a/.travis.yml b/.travis.yml index dccf2ab..f4e4821 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,12 @@ language: python python: #- '2.7' -- '3.5' +- '3.6' install: - pip install -r requirements/base.txt - pip install -r requirements/development.txt -script: nosetests +script: +- if [ $TRAVIS_BRANCH != "release" ]; then nosetests; fi sudo: required dist: xenial deploy: @@ -17,8 +18,8 @@ deploy: repo: Mangopay/mangopay2-python-sdk branch: release tags: false - python: 3.5 - condition: $TRAVIS_PYTHON_VERSION = "3.5" + python: 3.6 + condition: $TRAVIS_PYTHON_VERSION = "3.6" env: global: - secure: eDsZz0hrnLpBmkFvHMeczHHjytOMJpOZMc21nVR/vRLnjZ7eLmXaklvdy3AQ5SJz+l1neVVihHNX6MyBJ0s63UKatLP7catl++yyqPj5/0C7C0a07ZvJHhUzqnEdYLNOMauy7p5rPMldLOiT1dgQlL1f1FG31BHJ5UkAnrhwvdU= diff --git a/CHANGELOG.md b/CHANGELOG.md index a675431..56aff1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 3.9.0 +- 3DS2 integration with Shipping and Billing objects, including FirstName and LastName fields +The objects Billing and Shipping may be included on all calls to the following endpoints: + - /preauthorizations/card/direct + - /payins/card/direct + - /payins/card/web +- Enable Instant Payment for payouts by adding a new parameter PayoutModeRequested on the following endpoint /payouts/bankwire + - The new parameter PayoutModeRequested can take two differents values : "INSTANT_PAYMENT" or "STANDARD" (STANDARD = the way we procede normaly a payout request) + - This new parameter is not mandatory and if empty or not present, the payout will be "STANDARD" by default + - Instant Payment is in beta all over Europe - SEPA region +- Changed date to dateTime and fixed tests +- Changed User-Agent +- Fixed typo on IpAddress, FirstName & LastName ## 3.8.4 - Added 'Regulatory' endpoint to allow checks of User Block Status - Added support for Regulatory -> Blocked Status Hooks diff --git a/README.md b/README.md index 91597e9..6e773a4 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,12 @@ MangopaySDK is distributed under MIT license, see LICENSE file. Contact ------------------------------------------------- -Report bugs or suggest features using [issue tracker at GitHub](https://github.com/MangoPay/mangopay2-python-sdk-v2). +Report bugs or suggest features using [issue tracker at GitHub](https://github.com/Mangopay/mangopay2-python-sdk/issues). Account creation ------------------------------------------------- -You can get yourself a [free sandbox account](https://www.mangopay.com/signup/create-sandbox/) or sign up for a [production account](https://www.mangopay.com/signup/production-account/) (note that validation of your production account can take a few days, so think about doing it in advance of when you actually want to go live). +You can get yourself a free sandbox account or sign up for a production account by [registering on the Mangopay site](https://www.mangopay.com/start/) (note that validation of your production account involves several steps, so think about doing it in advance of when you actually want to go live). Inspiration ----------- diff --git a/mangopay/api.py b/mangopay/api.py index 3e55269..6d43723 100644 --- a/mangopay/api.py +++ b/mangopay/api.py @@ -70,7 +70,7 @@ def custom_request(self, method, url, data=None, idempotency_key=None, oauth_req headers = {} if is_mangopay_request: - headers['User-Agent'] = 'MangoPay V2 SDK Python ' + str(mangopay.package_version) + headers['User-Agent'] = 'MangoPay V2 Python/' + str(mangopay.package_version) if oauth_request: headers['Authorization'] = self.auth_manager.basic_token() headers['Content-Type'] = 'application/x-www-form-urlencoded' diff --git a/mangopay/fields.py b/mangopay/fields.py index 6f72f08..75eccb0 100644 --- a/mangopay/fields.py +++ b/mangopay/fields.py @@ -232,7 +232,7 @@ def api_value(self, value): class BillingField(Field): def python_value(self, value): if value is not None: - return Billing(address=value['Address']) + return Billing(first_name=value['FirstName'], last_name=value['LastName'], address=value['Address']) return value def api_value(self, value): @@ -240,6 +240,8 @@ def api_value(self, value): if isinstance(value, Billing): value = { + 'FirstName': value.first_name, + 'LastName': value.last_name, 'Address': value.address } @@ -750,14 +752,16 @@ def api_value(self, value): class ShippingField(Field): def python_value(self, value): if value is not None: - return Shipping(address=value['Address']) + return Shipping(first_name=value['FirstName'], last_name=value['LastName'], address=value['Address']) return value def api_value(self, value): value = super(ShippingField, self).api_value(value) - if isinstance(value, Billing): + if isinstance(value, Shipping): value = { + 'FirstName': value.first_name, + 'LastName': value.last_name, 'Address': value.address } diff --git a/mangopay/resources.py b/mangopay/resources.py index bd5460f..21a63ec 100644 --- a/mangopay/resources.py +++ b/mangopay/resources.py @@ -491,7 +491,7 @@ class DirectPayIn(PayIn): billing = BillingField(api_name='Billing') security_info = SecurityInfoField(api_name='SecurityInfo') culture = CharField(api_name='Culture') - ip_address = CharField(api_name='IpAdress') + ip_address = CharField(api_name='IpAddress') browser_info = BrowserInfoField(api_name='BrowserInfo') shipping = ShippingField(api_name='Shipping') @@ -689,7 +689,7 @@ class PreAuthorization(BaseModel): billing = BillingField(api_name='Billing') security_info = SecurityInfoField(api_name='SecurityInfo') multi_capture = BooleanField(api_name='MultiCapture') - ip_address = CharField(api_name='IpAdress') + ip_address = CharField(api_name='IpAddress') browser_info = BrowserInfoField(api_name='BrowserInfo') shipping = ShippingField(api_name='Shipping') @@ -809,8 +809,9 @@ class BankWirePayOut(BaseModel): payment_type = CharField(api_name='PaymentType', choices=constants.PAYOUT_PAYMENT_TYPE, default=None) execution_type = CharField(api_name='ExecutionType', choices=constants.EXECUTION_TYPE_CHOICES, default=None) bank_wire_ref = CharField(api_name='BankWireRef') + payout_mode_requested = CharField(api_name='PayoutModeRequested') credited_user = ForeignKeyField(User, api_name='CreditedUserId') - creation_date = DateField(api_name='CreationDate') + creation_date = DateTimeField(api_name='CreationDate') def get_refunds(self, *args, **kwargs): kwargs['id'] = self.id diff --git a/mangopay/utils.py b/mangopay/utils.py index 30e83cc..70871c4 100644 --- a/mangopay/utils.py +++ b/mangopay/utils.py @@ -235,11 +235,14 @@ def __str__(self): @add_camelcase_aliases class Billing(object): - def __init__(self, address=None): + def __init__(self, first_name=None, last_name=None, address=None): + self.first_name = first_name + self.last_name = last_name self.address = address def __str__(self): - return 'Billing: %s' % self.address + return 'Billing: %s' % \ + (self.first_name, self.last_name, self.address) @add_camelcase_aliases @@ -510,11 +513,14 @@ def to_api_json(self): @add_camelcase_aliases class Shipping(object): - def __init__(self, address=None): + def __init__(self, first_name=None, last_name=None, address=None): + self.first_name = first_name + self.last_name = last_name self.address = address def __str__(self): - return 'Shipping: %s' % self.address + return 'Shipping: %s' % \ + (self.first_name, self.last_name, self.address) @add_camelcase_aliases diff --git a/setup.py b/setup.py index cf1af52..7b99f4c 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( name='mangopaysdk', - version='3.8.4', + version='3.9.0', description='A client library written in python to work with mangopay v2 api', long_description='This SDK is a client library for interacting with the Mangopay API.', url='https://github.com/Mangopay/mangopay2-python-sdk', diff --git a/tests/test_payins.py b/tests/test_payins.py index de1c230..a8a9354 100644 --- a/tests/test_payins.py +++ b/tests/test_payins.py @@ -712,7 +712,7 @@ def test_PayIns_CardDirect_CreateWithAvs(self): address.country = "FR" address.city = "Lyon" address.postal_code = "68400" - pay_in.billing = Billing(address=address) + pay_in.billing = Billing(first_name="John", last_name="Doe", address=address) result = pay_in.save() diff --git a/tests/test_payouts.py b/tests/test_payouts.py index 82615ae..2629ba0 100644 --- a/tests/test_payouts.py +++ b/tests/test_payouts.py @@ -45,6 +45,7 @@ def test_create_bank_wire_payout(self): "Id": 30047, "CreditedFunds": None, "BankWireRef": "John Doe's trousers", + "PayoutModeRequested": "INSTANT_PAYMENT", "DebitedFunds": {"Currency": "EUR", "Amount": 1000}, "BankAccountId": 6784645, "AuthorId": 6784642, @@ -82,7 +83,8 @@ def test_create_bank_wire_payout(self): "Nature": "NORMAL", "DebitedWalletId": "30025", "BankAccountId": "30027", - "BankWireRef": "John Doe's trousers" + "BankWireRef": "John Doe's trousers", + "PayoutModeRequested": "INSTANT_PAYMENT" }, 'status': 200 }]) diff --git a/tests/test_preauthorizations.py b/tests/test_preauthorizations.py index c1a6e05..36dc124 100644 --- a/tests/test_preauthorizations.py +++ b/tests/test_preauthorizations.py @@ -706,6 +706,8 @@ def test_PreAuthorizations_CreateWithAvs(self): billing.address.country = "FR" billing.address.city = "Lyon" billing.address.postal_code = "65400" + billing.last_name = "Doe" + billing.first_name = "John" pre_authorization.billing = billing saved_pre_authorization = pre_authorization.save() @@ -754,6 +756,8 @@ def test_PreAuthorizations_CreateDirect(self): billing.address.country = "FR" billing.address.city = "Lyon" billing.address.postal_code = "65400" + billing.last_name = "Doe" + billing.first_name = "John" pre_authorization.billing = billing saved_pre_authorization = pre_authorization.save() diff --git a/tests/test_transactions.py b/tests/test_transactions.py index 7f64fac..acafbb8 100644 --- a/tests/test_transactions.py +++ b/tests/test_transactions.py @@ -1,15 +1,16 @@ # -*- coding: utf-8 -*- +import time +from datetime import date, datetime + +import responses + +from mangopay.utils import Money, timestamp_from_date from tests import settings from tests.resources import Transfer, Transaction from tests.test_base import BaseTest -from mangopay.utils import Money - -from datetime import date - -import responses -import time - +today = datetime.utcnow().date() +today_timestamp = timestamp_from_date(today) class TransactionsTest(BaseTest): @responses.activate @@ -43,7 +44,7 @@ def test_retrieve_transactions(self): "Status": "SUCCEEDED", "ResultCode": "000000", "ResultMessage": "Success", - "ExecutionDate": int(time.mktime(date.today().timetuple())), + "ExecutionDate": today_timestamp, "Type": "TRANSFER", "Nature": "REGULAR", "DebitedWalletId": "1167496", @@ -74,7 +75,7 @@ def test_retrieve_transactions(self): "Status": "CREATED", "ResultCode": "000000", "ResultMessage": "Success", - "ExecutionDate": "2015-05-15", + "ExecutionDate": today_timestamp, "Type": "TRANSFER", "Nature": "REFUND", "DebitedWalletId": "1174774" @@ -106,7 +107,7 @@ def test_retrieve_transactions(self): "Status": "CREATED", "ResultCode": "000000", "ResultMessage": "Success", - "ExecutionDate": "2015-05-15", + "ExecutionDate": today_timestamp, "Type": "TRANSFER", "Nature": "REFUND", "DebitedWalletId": "1174774" @@ -138,7 +139,7 @@ def test_retrieve_transactions(self): "Status": "FAILED", "ResultCode": "000000", "ResultMessage": "Success", - "ExecutionDate": "2015-05-15", + "ExecutionDate": today_timestamp, "Type": "TRANSFER", "Nature": "REFUND", "DebitedWalletId": "1174774" @@ -172,7 +173,7 @@ def test_retrieve_transactions(self): "Status": "CREATED", "ResultCode": "000000", "ResultMessage": "Success", - "ExecutionDate": 1383156788, + "ExecutionDate": today_timestamp, "Type": "TRANSFER", "Nature": "REGULAR", "CreditedWalletId": "1167504",