velocity-python 0.0.232__tar.gz → 0.0.233__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 (160) hide show
  1. {velocity_python-0.0.232/src/velocity_python.egg-info → velocity_python-0.0.233}/PKG-INFO +1 -1
  2. {velocity_python-0.0.232 → velocity_python-0.0.233}/pyproject.toml +1 -1
  3. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/__init__.py +1 -1
  4. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/demo_profiles.py +78 -29
  5. {velocity_python-0.0.232 → velocity_python-0.0.233/src/velocity_python.egg-info}/PKG-INFO +1 -1
  6. {velocity_python-0.0.232 → velocity_python-0.0.233}/LICENSE +0 -0
  7. {velocity_python-0.0.232 → velocity_python-0.0.233}/README.md +0 -0
  8. {velocity_python-0.0.232 → velocity_python-0.0.233}/setup.cfg +0 -0
  9. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/__init__.py +0 -0
  10. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/invoices.py +0 -0
  11. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/orders.py +0 -0
  12. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/payments.py +0 -0
  13. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/purchase_orders.py +0 -0
  14. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/tests/__init__.py +0 -0
  15. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/tests/test_email_processing.py +0 -0
  16. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/tests/test_payment_profile_sorting.py +0 -0
  17. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/app/tests/test_spreadsheet_functions.py +0 -0
  18. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/__init__.py +0 -0
  19. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/amplify.py +0 -0
  20. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/amplify_build.py +0 -0
  21. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/__init__.py +0 -0
  22. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/base_handler.py +0 -0
  23. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/context.py +0 -0
  24. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/context_factory.py +0 -0
  25. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/exceptions.py +0 -0
  26. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/lambda_handler.py +0 -0
  27. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/mixins/__init__.py +0 -0
  28. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/mixins/data_service.py +0 -0
  29. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/mixins/web_handler.py +0 -0
  30. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/perf.py +0 -0
  31. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/response.py +0 -0
  32. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/handlers/sqs_handler.py +0 -0
  33. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/tests/__init__.py +0 -0
  34. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
  35. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
  36. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/aws/tests/test_response.py +0 -0
  37. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/__init__.py +0 -0
  38. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/__init__.py +0 -0
  39. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/column.py +0 -0
  40. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/database.py +0 -0
  41. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/decorators.py +0 -0
  42. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/engine.py +0 -0
  43. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/result.py +0 -0
  44. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/row.py +0 -0
  45. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/sequence.py +0 -0
  46. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/table.py +0 -0
  47. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/transaction.py +0 -0
  48. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/core/view.py +0 -0
  49. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/exceptions.py +0 -0
  50. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/__init__.py +0 -0
  51. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/base/__init__.py +0 -0
  52. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/base/initializer.py +0 -0
  53. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/base/operators.py +0 -0
  54. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/base/sql.py +0 -0
  55. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/base/types.py +0 -0
  56. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/mysql/__init__.py +0 -0
  57. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/mysql/operators.py +0 -0
  58. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/mysql/reserved.py +0 -0
  59. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/mysql/sql.py +0 -0
  60. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/mysql/types.py +0 -0
  61. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/postgres/__init__.py +0 -0
  62. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/postgres/operators.py +0 -0
  63. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/postgres/reserved.py +0 -0
  64. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/postgres/sql.py +0 -0
  65. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/postgres/types.py +0 -0
  66. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlite/__init__.py +0 -0
  67. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlite/operators.py +0 -0
  68. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlite/reserved.py +0 -0
  69. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlite/sql.py +0 -0
  70. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlite/types.py +0 -0
  71. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
  72. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlserver/operators.py +0 -0
  73. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
  74. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlserver/sql.py +0 -0
  75. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/sqlserver/types.py +0 -0
  76. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/servers/tablehelper.py +0 -0
  77. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/__init__.py +0 -0
  78. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/common_db_test.py +0 -0
  79. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/__init__.py +0 -0
  80. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/common.py +0 -0
  81. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_column.py +0 -0
  82. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_connections.py +0 -0
  83. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_database.py +0 -0
  84. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_engine.py +0 -0
  85. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
  86. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_imports.py +0 -0
  87. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_result.py +0 -0
  88. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_row.py +0 -0
  89. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
  90. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
  91. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
  92. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
  93. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
  94. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_table.py +0 -0
  95. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
  96. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
  97. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/sql/__init__.py +0 -0
  98. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/sql/common.py +0 -0
  99. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
  100. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
  101. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
  102. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_db_utils.py +0 -0
  103. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_postgres.py +0 -0
  104. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
  105. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
  106. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_result_caching.py +0 -0
  107. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
  108. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
  109. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
  110. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
  111. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_sql_builder.py +0 -0
  112. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_tablehelper.py +0 -0
  113. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/tests/test_view_helper.py +0 -0
  114. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/db/utils.py +0 -0
  115. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/logging.py +0 -0
  116. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/__init__.py +0 -0
  117. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/conv/__init__.py +0 -0
  118. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/conv/iconv.py +0 -0
  119. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/conv/oconv.py +0 -0
  120. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/db.py +0 -0
  121. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/export.py +0 -0
  122. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/format.py +0 -0
  123. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/mail.py +0 -0
  124. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/merge.py +0 -0
  125. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/__init__.py +0 -0
  126. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_db.py +0 -0
  127. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_fix.py +0 -0
  128. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_format.py +0 -0
  129. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_iconv.py +0 -0
  130. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_merge.py +0 -0
  131. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_oconv.py +0 -0
  132. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_original_error.py +0 -0
  133. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tests/test_timer.py +0 -0
  134. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/timer.py +0 -0
  135. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/misc/tools.py +0 -0
  136. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/__init__.py +0 -0
  137. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/authorizenet_adapter.py +0 -0
  138. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/base_adapter.py +0 -0
  139. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/braintree_adapter.py +0 -0
  140. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/profiles.py +0 -0
  141. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/router.py +0 -0
  142. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity/payment/stripe_adapter.py +0 -0
  143. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity_python.egg-info/SOURCES.txt +0 -0
  144. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity_python.egg-info/dependency_links.txt +0 -0
  145. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity_python.egg-info/requires.txt +0 -0
  146. {velocity_python-0.0.232 → velocity_python-0.0.233}/src/velocity_python.egg-info/top_level.txt +0 -0
  147. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_amplify_build.py +0 -0
  148. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_decorators.py +0 -0
  149. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_iconv_money_to_cents.py +0 -0
  150. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_lambda_handler.py +0 -0
  151. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_lambda_handler_auth.py +0 -0
  152. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_mixins_import.py +0 -0
  153. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_payment_braintree_adapter.py +0 -0
  154. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_payment_demo_profiles.py +0 -0
  155. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_payment_profiles.py +0 -0
  156. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_payment_router.py +0 -0
  157. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_payment_stripe_adapter.py +0 -0
  158. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_sys_modified_count_postgres_demo.py +0 -0
  159. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_table_alter.py +0 -0
  160. {velocity_python-0.0.232 → velocity_python-0.0.233}/tests/test_where_clause_validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.232
3
+ Version: 0.0.233
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "velocity-python"
7
- version = "0.0.232"
7
+ version = "0.0.233"
8
8
  authors = [
9
9
  { name="Velocity Team", email="info@codeclubs.org" },
10
10
  ]
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.0.232"
1
+ __version__ = version = "0.0.233"
2
2
 
3
3
  from . import aws
4
4
  from . import db
@@ -1,16 +1,23 @@
1
1
  """Demo-only payment profile helpers for charging copied production users safely."""
2
2
 
3
+ import hashlib
3
4
  import os
4
5
  from typing import Dict, List, Optional
5
6
 
6
7
  from .profiles import get_payment_profile_sources, upsert_payment_profile
7
8
  from .router import get_processor_config
8
9
 
9
- _DEMO_BRAINTREE_NONCE = "fake-valid-nonce"
10
10
  _DEMO_STRIPE_TOKEN = "tok_visa"
11
11
  _DEMO_AUTHORIZE_CARD_NUMBER = "4111111111111111"
12
12
  _DEMO_AUTHORIZE_EXPIRATION = "2030-12"
13
13
  _DEMO_AUTHORIZE_CARD_CODE = "123"
14
+ _DEMO_BRAINTREE_CARD_NUMBERS = [
15
+ "4111111111111111",
16
+ "4012888888881881",
17
+ "5555555555554444",
18
+ "6011000991300009",
19
+ "378282246310005",
20
+ ]
14
21
 
15
22
 
16
23
  def is_demo_environment() -> bool:
@@ -39,9 +46,42 @@ def _save_payment_profile(tx, data: Dict) -> Dict:
39
46
  return data
40
47
 
41
48
 
49
+ def _stable_hash(value: str) -> int:
50
+ return int(hashlib.sha256(str(value).encode("utf-8")).hexdigest(), 16)
51
+
52
+
53
+ def _build_demo_braintree_card_spec(email_address: str) -> Dict[str, str]:
54
+ digest = _stable_hash(email_address)
55
+ card_number = _DEMO_BRAINTREE_CARD_NUMBERS[digest % len(_DEMO_BRAINTREE_CARD_NUMBERS)]
56
+ expiration_month = (digest % 12) + 1
57
+ expiration_year = 2027 + ((digest // len(_DEMO_BRAINTREE_CARD_NUMBERS)) % 3)
58
+ postal_code = f"{10000 + (digest % 89999):05d}"
59
+ return {
60
+ "number": card_number,
61
+ "expiration_date": f"{expiration_month:02d}/{expiration_year}",
62
+ "last4": card_number[-4:],
63
+ "expiration_month": f"{expiration_month:02d}",
64
+ "expiration_year": str(expiration_year),
65
+ "postal_code": postal_code,
66
+ }
67
+
68
+
69
+ def _find_matching_braintree_payment_method(customer, card_spec: Dict[str, str]):
70
+ for payment_method in customer.payment_methods:
71
+ if getattr(payment_method, "last_4", None) != card_spec["last4"]:
72
+ continue
73
+ if str(getattr(payment_method, "expiration_month", "")).zfill(2) != card_spec["expiration_month"]:
74
+ continue
75
+ if str(getattr(payment_method, "expiration_year", "")) != card_spec["expiration_year"]:
76
+ continue
77
+ return payment_method
78
+ return None
79
+
80
+
42
81
  def get_card_lookup_id(card: Dict) -> str:
43
82
  return str(
44
- card.get("sys_id")
83
+ card.get("lookup_id")
84
+ or card.get("sys_id")
45
85
  or card.get("payment_profile_id")
46
86
  or card.get("customer_profile_id")
47
87
  or card.get("src")
@@ -68,31 +108,35 @@ def _get_demo_braintree_card(tx, user: Dict) -> Dict:
68
108
  )
69
109
 
70
110
  demo_email = build_demo_profile_email(user["email_address"], "bt")
111
+ card_spec = _build_demo_braintree_card_spec(user["email_address"])
71
112
  customer = None
72
113
 
73
114
  collection = gateway.customer.search(braintree.CustomerSearch.email == demo_email)
74
115
  for existing_customer in collection.items:
75
- customer = existing_customer
76
- for payment_method in existing_customer.payment_methods:
77
- return _save_payment_profile(
78
- tx,
79
- {
80
- "src": "BT",
81
- "card_type": getattr(payment_method, "card_type", "Visa"),
82
- "card_number": getattr(payment_method, "last_4", "1111"),
83
- "expiration_date": _format_expiration_date(
84
- getattr(payment_method, "expiration_year", "2030"),
85
- getattr(payment_method, "expiration_month", "12"),
86
- ),
87
- "payment_profile_id": payment_method.token,
88
- "customer_profile_id": payment_method.customer_id,
89
- "email_address": user["email_address"],
90
- "first_name": user.get("first_name")
91
- or user["email_address"].split("@")[0],
92
- "last_name": user.get("last_name") or "Demo",
93
- "is_default": getattr(payment_method, "default", True),
94
- },
95
- )
116
+ customer = existing_customer
117
+ payment_method = _find_matching_braintree_payment_method(
118
+ existing_customer, card_spec
119
+ )
120
+ if payment_method:
121
+ return _save_payment_profile(
122
+ tx,
123
+ {
124
+ "src": "BT",
125
+ "card_type": getattr(payment_method, "card_type", "Visa"),
126
+ "card_number": getattr(payment_method, "last_4", card_spec["last4"]),
127
+ "expiration_date": _format_expiration_date(
128
+ getattr(payment_method, "expiration_year", card_spec["expiration_year"]),
129
+ getattr(payment_method, "expiration_month", card_spec["expiration_month"]),
130
+ ),
131
+ "payment_profile_id": payment_method.token,
132
+ "customer_profile_id": payment_method.customer_id,
133
+ "email_address": user["email_address"],
134
+ "first_name": user.get("first_name")
135
+ or user["email_address"].split("@")[0],
136
+ "last_name": user.get("last_name") or "Demo",
137
+ "is_default": getattr(payment_method, "default", True),
138
+ },
139
+ )
96
140
 
97
141
  if customer is None:
98
142
  result = gateway.customer.create(
@@ -107,26 +151,29 @@ def _get_demo_braintree_card(tx, user: Dict) -> Dict:
107
151
  raise RuntimeError(result.message)
108
152
  customer = result.customer
109
153
 
110
- payment_method_result = gateway.payment_method.create(
154
+ payment_method_result = gateway.credit_card.create(
111
155
  {
112
156
  "customer_id": customer.id,
113
- "payment_method_nonce": _DEMO_BRAINTREE_NONCE,
157
+ "number": card_spec["number"],
158
+ "expiration_date": card_spec["expiration_date"],
159
+ "cvv": "123",
160
+ "billing_address": {"postal_code": card_spec["postal_code"]},
114
161
  "options": {"make_default": True, "verify_card": True},
115
162
  }
116
163
  )
117
164
  if not payment_method_result.is_success:
118
165
  raise RuntimeError(payment_method_result.message)
119
166
 
120
- payment_method = payment_method_result.payment_method
167
+ payment_method = payment_method_result.credit_card
121
168
  return _save_payment_profile(
122
169
  tx,
123
170
  {
124
171
  "src": "BT",
125
172
  "card_type": getattr(payment_method, "card_type", "Visa"),
126
- "card_number": getattr(payment_method, "last_4", "1111"),
173
+ "card_number": getattr(payment_method, "last_4", card_spec["last4"]),
127
174
  "expiration_date": _format_expiration_date(
128
- getattr(payment_method, "expiration_year", "2030"),
129
- getattr(payment_method, "expiration_month", "12"),
175
+ getattr(payment_method, "expiration_year", card_spec["expiration_year"]),
176
+ getattr(payment_method, "expiration_month", card_spec["expiration_month"]),
130
177
  ),
131
178
  "payment_profile_id": payment_method.token,
132
179
  "customer_profile_id": customer.id,
@@ -289,6 +336,7 @@ def resolve_demo_charge_cards(tx, user: Dict, payment_processor: str, cards: Lis
289
336
  if demo_card:
290
337
  merged_card = dict(card)
291
338
  merged_card.update(demo_card)
339
+ merged_card["lookup_id"] = demo_card.get("payment_profile_id")
292
340
  resolved_cards.append(merged_card)
293
341
  else:
294
342
  resolved_cards.append(card)
@@ -299,6 +347,7 @@ def resolve_demo_charge_cards(tx, user: Dict, payment_processor: str, cards: Lis
299
347
  for source in get_payment_profile_sources(payment_processor):
300
348
  demo_card = get_demo_card_for_source(tx, user, source)
301
349
  if demo_card:
350
+ demo_card["lookup_id"] = demo_card.get("payment_profile_id")
302
351
  return [demo_card]
303
352
 
304
353
  return cards
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.232
3
+ Version: 0.0.233
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT