mangopay4-python-sdk 3.53.0__tar.gz → 3.54.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/PKG-INFO +1 -1
  2. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/fields.py +132 -2
  3. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/resources.py +92 -16
  4. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/utils.py +124 -5
  5. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay4_python_sdk.egg-info/PKG-INFO +1 -1
  6. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay4_python_sdk.egg-info/SOURCES.txt +2 -1
  7. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/setup.py +1 -1
  8. mangopay4_python_sdk-3.54.0/tests/resources/settlement_sample.csv +8 -0
  9. mangopay4_python_sdk-3.54.0/tests/resources/settlement_sample_bad.csv +8 -0
  10. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_base.py +57 -0
  11. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_conversion.py +13 -2
  12. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_payins.py +130 -7
  13. mangopay4_python_sdk-3.54.0/tests/test_settlements.py +60 -0
  14. mangopay4_python_sdk-3.53.0/tests/resources/settlement_sample.csv +0 -8
  15. mangopay4_python_sdk-3.53.0/tests/test_settlements.py +0 -38
  16. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/DESCRIPTION.md +0 -0
  17. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/LICENSE +0 -0
  18. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/MANIFEST.in +0 -0
  19. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/Makefile +0 -0
  20. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/README.md +0 -0
  21. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/__init__.py +0 -0
  22. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/api.py +0 -0
  23. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/auth.py +0 -0
  24. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/base.py +0 -0
  25. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/compat.py +0 -0
  26. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/constants.py +0 -0
  27. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/exceptions.py +0 -0
  28. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/page.py +0 -0
  29. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/query.py +0 -0
  30. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/ratelimit.py +0 -0
  31. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay/signals.py +0 -0
  32. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay4_python_sdk.egg-info/dependency_links.txt +0 -0
  33. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay4_python_sdk.egg-info/entry_points.txt +0 -0
  34. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay4_python_sdk.egg-info/requires.txt +0 -0
  35. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/mangopay4_python_sdk.egg-info/top_level.txt +0 -0
  36. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/setup.cfg +0 -0
  37. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/__init__.py +0 -0
  38. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/card.json +0 -0
  39. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/cardregistrations.json +0 -0
  40. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/cardregistrations_update.json +0 -0
  41. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/declarative_user.json +0 -0
  42. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/legal_user.json +0 -0
  43. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/legal_user_wallet.json +0 -0
  44. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/legal_user_wallet_89.json +0 -0
  45. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/legal_user_wallet_99.json +0 -0
  46. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/list_ubo_declarations.json +0 -0
  47. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/natural_user.json +0 -0
  48. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/natural_user_wallet.json +0 -0
  49. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/natural_user_wallet_9.json +0 -0
  50. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/ubo.json +0 -0
  51. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/ubo_declaration.json +0 -0
  52. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/ubo_declaration_submit.json +0 -0
  53. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/ubo_update.json +0 -0
  54. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/user_list_2_per_page.json +0 -0
  55. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/user_list_2_per_page_page1.json +0 -0
  56. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/user_list_3_per_page_page2.json +0 -0
  57. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/user_list_full.json +0 -0
  58. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/user_list_page1.json +0 -0
  59. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/fixtures/user_wallet.json +0 -0
  60. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/images/image.jpg +0 -0
  61. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/mocks.py +0 -0
  62. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/resources/TestKycPageFile.png +0 -0
  63. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/resources.py +0 -0
  64. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/settings.py +0 -0
  65. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_bankaccounts.py +0 -0
  66. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_banking_aliases.py +0 -0
  67. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_cards.py +0 -0
  68. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_client_wallets.py +0 -0
  69. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_clients.py +0 -0
  70. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_country_authorizations.py +0 -0
  71. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_deposits.py +0 -0
  72. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_disputes.py +0 -0
  73. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_documentconsult.py +0 -0
  74. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_emoney.py +0 -0
  75. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_idempotency.py +0 -0
  76. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_identity_verification.py +0 -0
  77. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_kyc_document.py +0 -0
  78. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_kycs.py +0 -0
  79. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_mandates.py +0 -0
  80. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_notifications.py +0 -0
  81. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_payouts.py +0 -0
  82. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_preauthorizations.py +0 -0
  83. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_rate_limit.py +0 -0
  84. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_recipients.py +0 -0
  85. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_refunds.py +0 -0
  86. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_reports.py +0 -0
  87. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_reports_v2.py +0 -0
  88. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_repudiations.py +0 -0
  89. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_tokens.py +0 -0
  90. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_transactions.py +0 -0
  91. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_transfers.py +0 -0
  92. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_ubos.py +0 -0
  93. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_users.py +0 -0
  94. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_utils.py +0 -0
  95. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_virtual_account.py +0 -0
  96. {mangopay4_python_sdk-3.53.0 → mangopay4_python_sdk-3.54.0}/tests/test_wallets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mangopay4-python-sdk
3
- Version: 3.53.0
3
+ Version: 3.54.0
4
4
  Summary: A client library written in python to work with mangopay v2 api
5
5
  Home-page: https://github.com/Mangopay/mangopay2-python-sdk
6
6
  Author: Mangopay (www.mangopay.com)
@@ -14,7 +14,8 @@ from .utils import timestamp_from_datetime, timestamp_from_date, Money, DebitedB
14
14
  VirtualAccountCapabilities, PaymentRef, PendingUserAction, LegalRepresentative, IndividualRecipient, \
15
15
  BusinessRecipient, RecipientPropertySchema, IndividualRecipientPropertySchema, BusinessRecipientPropertySchema, \
16
16
  CompanyNumberValidation, ReportFilter, PayInIntentExternalData, PayInIntentBuyer, SupportedBank, \
17
- VerificationOfPayee, ConsentScope
17
+ VerificationOfPayee, PayInIntentRefund, PayInIntentCapture, PayInIntentDispute, CustomFees, MarginsResponse, \
18
+ UserMargin, ConsentScope
18
19
 
19
20
 
20
21
  class FieldDescriptor(object):
@@ -1346,6 +1347,135 @@ class VerificationOfPayeeField(Field):
1346
1347
  return value
1347
1348
 
1348
1349
 
1350
+ class PayInIntentRefundField(Field):
1351
+ def python_value(self, value):
1352
+ if value is not None:
1353
+ return PayInIntentRefund(id=value.get('Id', None))
1354
+
1355
+ return value
1356
+
1357
+ def api_value(self, value):
1358
+ value = super(PayInIntentRefundField, self).api_value(value)
1359
+
1360
+ if isinstance(value, PayInIntentRefund):
1361
+ result = {}
1362
+ if value.id is not None:
1363
+ result['Id'] = value.id
1364
+ return result
1365
+
1366
+ return value
1367
+
1368
+
1369
+ class PayInIntentCaptureField(Field):
1370
+ def python_value(self, value):
1371
+ if value is not None:
1372
+ return PayInIntentCapture(id=value.get('Id', None))
1373
+
1374
+ return value
1375
+
1376
+ def api_value(self, value):
1377
+ value = super(PayInIntentCaptureField, self).api_value(value)
1378
+
1379
+ if isinstance(value, PayInIntentCapture):
1380
+ result = {}
1381
+ if value.id is not None:
1382
+ result['Id'] = value.id
1383
+ return result
1384
+
1385
+ return value
1386
+
1387
+
1388
+ class PayInIntentDisputeField(Field):
1389
+ def python_value(self, value):
1390
+ if value is not None:
1391
+ return PayInIntentDispute(id=value.get('Id', None))
1392
+
1393
+ return value
1394
+
1395
+ def api_value(self, value):
1396
+ value = super(PayInIntentDisputeField, self).api_value(value)
1397
+
1398
+ if isinstance(value, PayInIntentDispute):
1399
+ result = {}
1400
+ if value.id is not None:
1401
+ result['Id'] = value.id
1402
+ return result
1403
+
1404
+ return value
1405
+
1406
+
1407
+ class CustomFeesField(Field):
1408
+ def python_value(self, value):
1409
+ if value is not None:
1410
+ return CustomFees(amount=value.get('Amount', None),
1411
+ currency=value.get('Currency', None),
1412
+ type=value.get('Type', None),
1413
+ value=value.get('Value', None))
1414
+
1415
+ return value
1416
+
1417
+ def api_value(self, value):
1418
+ value = super(CustomFeesField, self).api_value(value)
1419
+
1420
+ if isinstance(value, CustomFees):
1421
+ result = {}
1422
+ if value.amount is not None:
1423
+ result['Amount'] = value.amount
1424
+ if value.currency is not None:
1425
+ result['Currency'] = value.currency
1426
+ if value.type is not None:
1427
+ result['Type'] = value.type
1428
+ if value.value is not None:
1429
+ result['Value'] = value.value
1430
+ return result
1431
+
1432
+ return value
1433
+
1434
+
1435
+ class MarginsResponseField(Field):
1436
+ def python_value(self, value):
1437
+ if value is not None:
1438
+ return MarginsResponse(mangopay=value.get('Mangopay', None),
1439
+ user=value.get('User', None))
1440
+
1441
+ return value
1442
+
1443
+ def api_value(self, value):
1444
+ value = super(MarginsResponseField, self).api_value(value)
1445
+
1446
+ if isinstance(value, MarginsResponse):
1447
+ result = {}
1448
+ if value.mangopay is not None:
1449
+ result['Mangopay'] = value.mangopay
1450
+ if value.user is not None:
1451
+ result['User'] = value.user
1452
+ return result
1453
+
1454
+ return value
1455
+
1456
+
1457
+ class UserMarginField(Field):
1458
+ def python_value(self, value):
1459
+ if value is not None:
1460
+ return UserMargin(type=value.get('Type', None),
1461
+ value=value.get('Value', None))
1462
+
1463
+ return value
1464
+
1465
+ def api_value(self, value):
1466
+ value = super(UserMarginField, self).api_value(value)
1467
+
1468
+ if isinstance(value, UserMargin):
1469
+ result = {}
1470
+ if value.type is not None:
1471
+ result['Type'] = value.type
1472
+ if value.value is not None:
1473
+ result['Value'] = value.value
1474
+ return result
1475
+
1476
+ return value
1477
+
1478
+
1349
1479
  class ConsentScopeField(Field):
1350
1480
  def python_value(self, value):
1351
1481
  if value is not None:
@@ -1371,4 +1501,4 @@ class ConsentScopeField(Field):
1371
1501
  result['ViewAccountInformation'] = value.view_account_information
1372
1502
  return result
1373
1503
 
1374
- return value
1504
+ return value
@@ -20,9 +20,9 @@ from .fields import (PrimaryKeyField, EmailField, CharField,
20
20
  RecipientPropertySchemaField, IndividualRecipientPropertySchemaField,
21
21
  BusinessRecipientPropertySchemaField, CompanyNumberValidationField, ReportFilterField,
22
22
  PayInIntentExternalDataField, PayInIntentBuyerField, SupportedBanksField, VerificationOfPayeeField,
23
- ConsentScopeField)
24
- from .query import InsertQuery, UpdateQuery, SelectQuery, ActionQuery, DeleteQuery, InsertMultipartQuery, \
25
- UpdateMultipartQuery
23
+ PayInIntentRefundField, PayInIntentCaptureField, PayInIntentDisputeField, CustomFeesField,
24
+ UserMarginField, MarginsResponseField, ConsentScopeField)
25
+ from .query import InsertQuery, UpdateQuery, SelectQuery, ActionQuery, DeleteQuery
26
26
 
27
27
 
28
28
  class BaseModel(BaseApiModel):
@@ -480,6 +480,10 @@ class ConversionQuote(BaseModel):
480
480
  debited_funds = MoneyField(api_name='DebitedFunds', required=True)
481
481
  credited_funds = MoneyField(api_name='CreditedFunds', required=True)
482
482
  conversion_rate = ConversionRateField(api_name='ConversionRateResponse')
483
+ fees = CustomFeesField(api_name="Fees")
484
+ requested_fees = CustomFeesField(api_name="RequestedFees")
485
+ user_margin = UserMarginField(api_name="UserMargin")
486
+ margins_response = MarginsResponseField(api_name='MarginsResponse')
483
487
 
484
488
  def create_conversion_quote(self, **kwargs):
485
489
  insert = InsertQuery(self, **kwargs)
@@ -515,11 +519,13 @@ class Conversion(BaseModel):
515
519
  debited_funds = MoneyField(api_name='DebitedFunds', required=True)
516
520
  credited_funds = MoneyField(api_name='CreditedFunds', required=True)
517
521
  fees = MoneyField(api_name="Fees", required=True)
522
+ requested_fees = CustomFeesField(api_name="RequestedFees")
518
523
  result_code = CharField(api_name='ResultCode')
519
524
  result_message = CharField(api_name='ResultMessage')
520
525
  execution_date = DateTimeField(api_name='ExecutionDate')
521
526
  conversion_rate = ConversionRateField(api_name='ConversionRate')
522
527
  creation_date = DateTimeField(api_name='CreationDate')
528
+ margins_response = MarginsResponseField(api_name='MarginsResponse')
523
529
 
524
530
  @staticmethod
525
531
  def get_conversion(id, *args, **kwargs):
@@ -583,8 +589,9 @@ class InstantConversion(BaseModel):
583
589
  credited_wallet = ForeignKeyField(Wallet, api_name="CreditedWalletId")
584
590
  debited_funds = MoneyField(api_name="DebitedFunds")
585
591
  credited_funds = MoneyField(api_name="CreditedFunds")
586
- fees = MoneyField(api_name="Fees")
592
+ fees = CustomFeesField(api_name="Fees")
587
593
  tag = CharField(api_name="Tag")
594
+ user_margin = UserMarginField(api_name="UserMargin")
588
595
 
589
596
  def save(self, **kwargs):
590
597
  insert = InsertQuery(self, **kwargs)
@@ -3024,10 +3031,15 @@ class PayInIntent(BaseModel):
3024
3031
  buyer = PayInIntentBuyerField(api_name='Buyer')
3025
3032
  line_items = ListField(api_name='LineItems')
3026
3033
  captures = ListField(api_name='Captures')
3034
+ capture = PayInIntentCaptureField(api_name='Capture')
3027
3035
  refunds = ListField(api_name='Refunds')
3036
+ refund = PayInIntentRefundField(api_name='Refund')
3028
3037
  disputes = ListField(api_name='Disputes')
3038
+ dispute = PayInIntentDisputeField(api_name='Dispute')
3029
3039
  splits = ListField(api_name='Splits')
3030
3040
  settlement_id = CharField(api_name='SettlementId')
3041
+ unfunded_amount = IntegerField(api_name='UnfundedAmount')
3042
+ decision = CharField(api_name='Decision')
3031
3043
 
3032
3044
  class Meta:
3033
3045
  verbose_name = 'pay_in_intent'
@@ -3037,7 +3049,11 @@ class PayInIntent(BaseModel):
3037
3049
  'CREATE_AUTHORIZATION': '/payins/intents',
3038
3050
  'CREATE_CAPTURE': '/payins/intents/%(intent_id)s/captures',
3039
3051
  'GET': '/payins/intents',
3040
- 'CANCEL': '/payins/intents/%(intent_id)s/cancel'
3052
+ 'CANCEL': '/payins/intents/%(intent_id)s/cancel',
3053
+ 'CREATE_REFUND': '/payins/intents/%(intent_id)s/refunds',
3054
+ 'REVERSE_REFUND': '/payins/intents/%(intent_id)s/refunds/%(refund_id)s/reverse',
3055
+ 'CREATE_DISPUTE': '/payins/intents/%(intent_id)s/captures/%(capture_id)s/disputes',
3056
+ 'UPDATE_DISPUTE_OUTCOME': '/payins/intents/%(intent_id)s/captures/%(capture_id)s/disputes/%(dispute_id)s/decision',
3041
3057
  }
3042
3058
 
3043
3059
  def create_authorization(self, idempotency_key=None, **kwargs):
@@ -3066,6 +3082,34 @@ class PayInIntent(BaseModel):
3066
3082
  insert.identifier = 'CANCEL'
3067
3083
  return insert.execute(is_v3=True)
3068
3084
 
3085
+ @classmethod
3086
+ def create_refund(cls, intent_id, idempotency_key=None, **kwargs):
3087
+ path_params = {'intent_id': intent_id}
3088
+ insert = InsertQuery(PayInIntent, idempotency_key, path_params, **kwargs)
3089
+ insert.identifier = 'CREATE_REFUND'
3090
+ return insert.execute(is_v3=True)
3091
+
3092
+ @classmethod
3093
+ def reverse_refund(cls, intent_id, refund_id, idempotency_key=None, **kwargs):
3094
+ path_params = {'intent_id': intent_id, 'refund_id': refund_id}
3095
+ insert = InsertQuery(PayInIntent, idempotency_key, path_params, **kwargs)
3096
+ insert.identifier = 'REVERSE_REFUND'
3097
+ return insert.execute(is_v3=True)
3098
+
3099
+ @classmethod
3100
+ def create_dispute(cls, intent_id, capture_id, idempotency_key=None, **kwargs):
3101
+ path_params = {'intent_id': intent_id, 'capture_id': capture_id}
3102
+ insert = InsertQuery(PayInIntent, idempotency_key, path_params, **kwargs)
3103
+ insert.identifier = 'CREATE_DISPUTE'
3104
+ return insert.execute(is_v3=True)
3105
+
3106
+ @classmethod
3107
+ def update_dispute_outcome(cls, intent_id, capture_id, dispute_id, **kwargs):
3108
+ path_params = {'intent_id': intent_id, 'capture_id': capture_id, 'dispute_id': dispute_id}
3109
+ update = UpdateQuery(PayInIntent, "", path_params, **kwargs)
3110
+ update.identifier = 'UPDATE_DISPUTE_OUTCOME'
3111
+ return update.execute(is_v3=True)
3112
+
3069
3113
 
3070
3114
  class Settlement(BaseModel):
3071
3115
  settlement_id = CharField(api_name='SettlementId')
@@ -3076,21 +3120,24 @@ class Settlement(BaseModel):
3076
3120
  external_processor_fees_amount = IntegerField(api_name='ExternalProcessorFeesAmount')
3077
3121
  actual_settlement_amount = IntegerField(api_name='ActualSettlementAmount')
3078
3122
  funds_missing_amount = IntegerField(api_name='FundsMissingAmount')
3123
+ file_name = CharField(api_name='FileName')
3124
+ upload_url = CharField(api_name='UploadUrl')
3079
3125
 
3080
3126
  class Meta:
3081
3127
  verbose_name = 'settlement'
3082
3128
  verbose_name_plural = 'settlements'
3083
3129
 
3084
3130
  url = {
3085
- 'UPLOAD': '/payins/intents/settlements',
3131
+ 'GENERATE_UPLOAD_URL': '/payins/intents/settlements',
3086
3132
  'GET': '/payins/intents/settlements',
3087
- 'UPDATE': '/payins/intents/settlements'
3133
+ 'GENERATE_NEW_UPLOAD_URL': '/payins/intents/settlements',
3134
+ 'CANCEL': '/payins/intents/settlements/%(settlement_id)s/cancel',
3088
3135
  }
3089
3136
 
3090
- @classmethod
3091
- def upload(cls, file, idempotency_key=None, **kwargs):
3092
- insert = InsertMultipartQuery(Settlement, file, 'settlement_file.csv', idempotency_key, **kwargs)
3093
- insert.identifier = 'UPLOAD'
3137
+ def generate_upload_url(self, idempotency_key=None, **kwargs):
3138
+ insert = InsertQuery(Settlement, idempotency_key, None, **kwargs)
3139
+ insert.insert_query = self.get_field_dict()
3140
+ insert.identifier = 'GENERATE_UPLOAD_URL'
3094
3141
  return insert.execute(is_v3=True)
3095
3142
 
3096
3143
  @classmethod
@@ -3099,12 +3146,40 @@ class Settlement(BaseModel):
3099
3146
  select.identifier = 'GET'
3100
3147
  return select.get(settlement_id, is_v3=True, *args, **kwargs)
3101
3148
 
3102
- @classmethod
3103
- def update_file(cls, settlement_id, file, **kwargs):
3104
- update = UpdateMultipartQuery(Settlement, file, 'settlement_file.csv', settlement_id, **kwargs)
3105
- update.identifier = 'UPDATE'
3149
+ def generate_new_upload_url(self, **kwargs):
3150
+ update = UpdateQuery(Settlement, self.id, None, **kwargs)
3151
+ update.update_query = self.get_field_dict()
3152
+ update.identifier = 'GENERATE_NEW_UPLOAD_URL'
3106
3153
  return update.execute(is_v3=True)
3107
3154
 
3155
+ @classmethod
3156
+ def cancel(cls, settlement_id, idempotency_key=None, *args, **kwargs):
3157
+ path_params = {'settlement_id': settlement_id}
3158
+ insert = InsertQuery(Settlement, idempotency_key, path_params, **kwargs)
3159
+ insert.identifier = 'CANCEL'
3160
+ return insert.execute(*args, is_v3=True)
3161
+
3162
+
3163
+ class SettlementValidation(BaseModel):
3164
+ footer_errors = ListField(api_name='FooterErrors')
3165
+ lines_errors = ListField(api_name='LinesErrors')
3166
+
3167
+ class Meta:
3168
+ verbose_name = 'settlement_validation'
3169
+ verbose_name_plural = 'settlement_validations'
3170
+
3171
+ url = {
3172
+ 'GET': '/payins/intents/settlements/%(settlement_id)s/validations',
3173
+ }
3174
+
3175
+ @classmethod
3176
+ def get(cls, settlement_id, *args, **kwargs):
3177
+ if kwargs.get('settlement_id') is None:
3178
+ kwargs['settlement_id'] = settlement_id
3179
+ select = SelectQuery(SettlementValidation, *args, **kwargs)
3180
+ select.identifier = 'GET'
3181
+ return select.get("", with_query_params=True, is_v3=True, *args, **kwargs)
3182
+
3108
3183
 
3109
3184
  class PayInIntentSplit(BaseModel):
3110
3185
  line_item_id = CharField(api_name='LineItemId')
@@ -3115,6 +3190,7 @@ class PayInIntentSplit(BaseModel):
3115
3190
  description = CharField(api_name='Description')
3116
3191
  status = CharField(api_name='Status')
3117
3192
  transfer_date = DateTimeField(api_name='TransferDate')
3193
+ split_origin_wallet_id = CharField(api_name='SplitOriginWalletId')
3118
3194
 
3119
3195
  class Meta:
3120
3196
  verbose_name = 'intent_split'
@@ -3241,4 +3317,4 @@ class ScaStatus(BaseModel):
3241
3317
  kwargs['id'] = user_id
3242
3318
  select = SelectQuery(ScaStatus, *args, **kwargs)
3243
3319
  select.identifier = 'GET'
3244
- return select.get("", *args, **kwargs)
3320
+ return select.get("", *args, **kwargs)
@@ -1442,7 +1442,7 @@ class PayInIntentLineItem(object):
1442
1442
  def __init__(self, id=None, seller=None, sku=None, name=None, description=None, quantity=None, unit_amount=None, amount=None,
1443
1443
  tax_amount=None, discount_amount=None, category=None, shipping_address=None,
1444
1444
  total_line_item_amount=None, canceled_amount=None, captured_amount=None, refunded_amount=None,
1445
- disputed_amount=None, split_amount=None):
1445
+ disputed_amount=None, split_amount=None, unfunded_seller_amount=None):
1446
1446
  self.id = id
1447
1447
  self.seller = seller
1448
1448
  self.sku = sku
@@ -1461,12 +1461,14 @@ class PayInIntentLineItem(object):
1461
1461
  self.refunded_amount = refunded_amount
1462
1462
  self.disputed_amount = disputed_amount
1463
1463
  self.split_amount = split_amount
1464
+ self.unfunded_seller_amount = unfunded_seller_amount
1464
1465
 
1465
1466
  def __str__(self):
1466
- return 'PayInIntentLineItem: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s' % \
1467
+ return 'PayInIntentLineItem: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s' % \
1467
1468
  (self.id, self.seller, self.sku, self.name, self.description, self.quantity, self.unit_amount, self.amount,
1468
1469
  self.tax_amount, self.discount_amount, self.category, self.shipping_address, self.total_line_item_amount,
1469
- self.canceled_amount, self.captured_amount, self.refunded_amount, self.disputed_amount, self.split_amount)
1470
+ self.canceled_amount, self.captured_amount, self.refunded_amount, self.disputed_amount, self.split_amount,
1471
+ self.unfunded_seller_amount)
1470
1472
 
1471
1473
  def to_api_json(self):
1472
1474
  return {
@@ -1487,7 +1489,8 @@ class PayInIntentLineItem(object):
1487
1489
  "CapturedAmount": self.captured_amount,
1488
1490
  "RefundedAmount": self.refunded_amount,
1489
1491
  "DisputedAmount": self.disputed_amount,
1490
- "SplitAmount": self.split_amount
1492
+ "SplitAmount": self.split_amount,
1493
+ "UnfundedSellerAmount": self.unfunded_seller_amount
1491
1494
  }
1492
1495
 
1493
1496
 
@@ -1582,6 +1585,80 @@ class VerificationOfPayee(object):
1582
1585
  }
1583
1586
 
1584
1587
 
1588
+ @add_camelcase_aliases
1589
+ class CustomFees(object):
1590
+ def __init__(self, amount=None, currency=None,
1591
+ type=None, value=None):
1592
+ self.currency = currency
1593
+ self.type = type
1594
+
1595
+ if amount is not None:
1596
+ self.amount = decimal.Decimal(amount)
1597
+ else:
1598
+ self.amount = None
1599
+
1600
+ if value is not None:
1601
+ self.value = decimal.Decimal(value)
1602
+ else:
1603
+ self.value = None
1604
+
1605
+ def __str__(self):
1606
+ return force_text("CustomFees: {:,.2f} {} {} {:,.2f}".format(
1607
+ self.amount if self.amount is not None else 0.0,
1608
+ self.currency or "",
1609
+ self.type or "",
1610
+ self.value if self.value is not None else 0.0)
1611
+ )
1612
+
1613
+ def to_api_json(self):
1614
+ return {
1615
+ "Amount": self.amount,
1616
+ "Currency": self.currency,
1617
+ "Type": self.type,
1618
+ "Value": self.value
1619
+ }
1620
+
1621
+
1622
+ @add_camelcase_aliases
1623
+ class MarginsResponse(object):
1624
+ def __init__(self, mangopay=None, user=None):
1625
+ self.mangopay = mangopay
1626
+ self.user = user
1627
+
1628
+ def __str__(self):
1629
+ return 'MarginsResponse: %s %s' % self.mangopay, self.user
1630
+
1631
+ def to_api_json(self):
1632
+ return {
1633
+ "Mangopay": self.mangopay,
1634
+ "User": self.user
1635
+ }
1636
+
1637
+
1638
+ @add_camelcase_aliases
1639
+ class UserMargin(object):
1640
+ def __init__(self, type=None, value=None):
1641
+ self.type = type
1642
+
1643
+ if value is not None:
1644
+ self.value = decimal.Decimal(value)
1645
+ else:
1646
+ self.value = None
1647
+
1648
+ def __str__(self):
1649
+ return force_text(
1650
+ "UserMargin: {} {:,.2f}".format(
1651
+ self.type or "",
1652
+ self.value if self.value is not None else 0.0)
1653
+ )
1654
+
1655
+ def to_api_json(self):
1656
+ return {
1657
+ "Type": self.type,
1658
+ "Value": self.value
1659
+ }
1660
+
1661
+
1585
1662
  @add_camelcase_aliases
1586
1663
  class ConsentScope(object):
1587
1664
  def __init__(self, contact_information_update=None, recipient_registration=None,
@@ -1601,4 +1678,46 @@ class ConsentScope(object):
1601
1678
  "RecipientRegistration": self.recipient_registration,
1602
1679
  "Transfer": self.transfer,
1603
1680
  "ViewAccountInformation": self.view_account_information
1604
- }
1681
+ }
1682
+
1683
+
1684
+ @add_camelcase_aliases
1685
+ class PayInIntentRefund(object):
1686
+ def __init__(self, id=None):
1687
+ self.id = id
1688
+
1689
+ def __str__(self):
1690
+ return ('PayInIntentRefund: %s' % self.id)
1691
+
1692
+ def to_api_json(self):
1693
+ return {
1694
+ "Id": self.id
1695
+ }
1696
+
1697
+
1698
+ @add_camelcase_aliases
1699
+ class PayInIntentCapture(object):
1700
+ def __init__(self, id=None):
1701
+ self.id = id
1702
+
1703
+ def __str__(self):
1704
+ return ('PayInIntentCapture: %s' % self.id)
1705
+
1706
+ def to_api_json(self):
1707
+ return {
1708
+ "Id": self.id
1709
+ }
1710
+
1711
+
1712
+ @add_camelcase_aliases
1713
+ class PayInIntentDispute(object):
1714
+ def __init__(self, id=None):
1715
+ self.id = id
1716
+
1717
+ def __str__(self):
1718
+ return ('PayInIntentDispute: %s' % self.id)
1719
+
1720
+ def to_api_json(self):
1721
+ return {
1722
+ "Id": self.id
1723
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mangopay4-python-sdk
3
- Version: 3.53.0
3
+ Version: 3.54.0
4
4
  Summary: A client library written in python to work with mangopay v2 api
5
5
  Home-page: https://github.com/Mangopay/mangopay2-python-sdk
6
6
  Author: Mangopay (www.mangopay.com)
@@ -89,4 +89,5 @@ tests/fixtures/user_list_page1.json
89
89
  tests/fixtures/user_wallet.json
90
90
  tests/images/image.jpg
91
91
  tests/resources/TestKycPageFile.png
92
- tests/resources/settlement_sample.csv
92
+ tests/resources/settlement_sample.csv
93
+ tests/resources/settlement_sample_bad.csv
@@ -10,7 +10,7 @@ with open(path.join(here, 'DESCRIPTION.md'), encoding='utf-8') as f:
10
10
 
11
11
  setup(
12
12
  name='mangopay4-python-sdk',
13
- version='3.53.0',
13
+ version='3.54.0',
14
14
  description='A client library written in python to work with mangopay v2 api',
15
15
  long_description='This SDK is a client library for interacting with the Mangopay API.',
16
16
  url='https://github.com/Mangopay/mangopay2-python-sdk',
@@ -0,0 +1,8 @@
1
+ ExternalProviderReference,ExternalPaymentMethod,ExternalTransactionType,ExternalTransactionStatus,ExternalProcessingDate,Amount,Currency,ExternalInitialReference,ExternalProviderFees
2
+ 6TU984332A894613W,PAYPAL,PAYMENT,SETTLED,19-06-2025,1000,EUR,,0
3
+ ,,,,,,,,
4
+ SettlementDate,19-06-2025,,,,,,,
5
+ ExternalProviderName,Paypal,,,,,,,
6
+ TotalSettlementFeesAmount,0,,,,,,,
7
+ TotalNetSettlementAmount,1000,,,,,,,
8
+ SettlementCurrency,EUR,,,,,,,
@@ -0,0 +1,8 @@
1
+ ExternalProviderReference,ExternalPaymentMethod,ExternalTransactionType,ExternalTransactionStatus,ExternalProcessingDate,Amount,Currency,ExternalInitialReference,ExternalProviderFees
2
+ 6TU984332A894613W,PAYPAL,PAYMENT,SETTLED,19-06-2025,1000,EUR,,0
3
+ ,,,,,,,,
4
+ SettlementDate,19-06-2025,,,,,,,
5
+ ExternalProviderName,Paypal,,,,,,,
6
+ TotalSettlementFeesAmount,0,,,,,,,
7
+ TotalNetSettlementAmount,99999,,,,,,,
8
+ SettlementCurrency,EUR,,,,,,
@@ -809,6 +809,63 @@ class BaseTestLive(unittest.TestCase):
809
809
  intent_authorization.buyer = buyer
810
810
  return PayInIntent(**intent_authorization.create_authorization())
811
811
 
812
+ @staticmethod
813
+ def create_new_pay_in_intent_full_capture():
814
+ user = BaseTestLive.get_john()
815
+ wallet = BaseTestLive.get_johns_wallet()
816
+
817
+ external_data = PayInIntentExternalData()
818
+ external_data.external_processing_date = 1728133765
819
+ external_data.external_provider_reference = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
820
+ external_data.external_merchant_reference = 'Order-xyz-35e8490e-2ec9-4c82-978e-c712a3f5ba16'
821
+ external_data.external_provider_name = 'Stripe'
822
+ external_data.external_provider_payment_method = 'PAYPAL'
823
+
824
+ seller = PayInIntentSeller()
825
+ seller.wallet_id = wallet.id
826
+ seller.author_id = wallet.owners_ids[0]
827
+ seller.transfer_date = 1728133765
828
+
829
+ buyer = PayInIntentBuyer()
830
+ buyer.id = user.id
831
+
832
+ line_item = PayInIntentLineItem()
833
+ line_item.seller = seller
834
+ line_item.sku = 'item-123456'
835
+ line_item.quantity = 1
836
+ line_item.unit_amount = 1000
837
+ line_items = [line_item]
838
+
839
+ intent_authorization = PayInIntent()
840
+ intent_authorization.amount = 1000
841
+ intent_authorization.currency = 'EUR'
842
+ intent_authorization.external_data = external_data
843
+ intent_authorization.line_items = line_items
844
+ intent_authorization.buyer = buyer
845
+
846
+ intent = PayInIntent(**intent_authorization.create_authorization())
847
+
848
+ full_capture = PayInIntent()
849
+ full_capture.external_data = external_data
850
+
851
+ return PayInIntent(**full_capture.create_capture(intent.id))
852
+
853
+ @staticmethod
854
+ def create_new_full_pay_in_intent_refund():
855
+ full_capture = BaseTestLive.create_new_pay_in_intent_full_capture()
856
+
857
+ external_data = PayInIntentExternalData()
858
+ external_data.external_processing_date = 1727913600
859
+ external_data.external_provider_reference = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
860
+ external_data.external_merchant_reference = 'Order-xyz-35e8490e-2ec9-4c82-978e-c712a3f5ba16'
861
+ external_data.external_provider_name = 'Stripe'
862
+ external_data.external_provider_payment_method = 'PAYPAL'
863
+
864
+ refund_dto = {
865
+ 'external_data': external_data
866
+ }
867
+ return PayInIntent(**PayInIntent.create_refund(full_capture.id, **refund_dto))
868
+
812
869
  def test_handler(self):
813
870
  api_url = "test_api_url"
814
871
  sandbox_url = "test_sandbox_url"