boilpayment 0.2.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 (148) hide show
  1. boilpayment-0.2.0/.gitignore +13 -0
  2. boilpayment-0.2.0/LICENSE +21 -0
  3. boilpayment-0.2.0/PKG-INFO +104 -0
  4. boilpayment-0.2.0/README.md +82 -0
  5. boilpayment-0.2.0/pyproject.toml +28 -0
  6. boilpayment-0.2.0/src/boilpayment/__init__.py +337 -0
  7. boilpayment-0.2.0/src/boilpayment/core.py +310 -0
  8. boilpayment-0.2.0/src/boilpayment/credits.py +70 -0
  9. boilpayment-0.2.0/src/boilpayment/cs.py +183 -0
  10. boilpayment-0.2.0/src/boilpayment/lifecycle.py +116 -0
  11. boilpayment-0.2.0/src/boilpayment/notify.py +43 -0
  12. boilpayment-0.2.0/src/boilpayment/polar.py +29 -0
  13. boilpayment-0.2.0/src/boilpayment/portone.py +30 -0
  14. boilpayment-0.2.0/src/boilpayment/postgres.py +56 -0
  15. boilpayment-0.2.0/src/boilpayment/refund.py +49 -0
  16. boilpayment-0.2.0/src/boilpayment/stripe.py +32 -0
  17. boilpayment-0.2.0/src/boilpayment/toss.py +35 -0
  18. boilpayment-0.2.0/src/boilpayment/usage.py +54 -0
  19. boilpayment-0.2.0/src/boilpayment/webhook.py +50 -0
  20. boilpayment-0.2.0/src/boilpayment_core/__init__.py +72 -0
  21. boilpayment-0.2.0/src/boilpayment_core/attempt_review.py +67 -0
  22. boilpayment-0.2.0/src/boilpayment_core/clock.py +44 -0
  23. boilpayment-0.2.0/src/boilpayment_core/idempotent.py +224 -0
  24. boilpayment-0.2.0/src/boilpayment_core/keys.py +64 -0
  25. boilpayment-0.2.0/src/boilpayment_core/logger.py +134 -0
  26. boilpayment-0.2.0/src/boilpayment_core/memory.py +416 -0
  27. boilpayment-0.2.0/src/boilpayment_core/money.py +102 -0
  28. boilpayment-0.2.0/src/boilpayment_core/payment_refs.py +37 -0
  29. boilpayment-0.2.0/src/boilpayment_core/period.py +180 -0
  30. boilpayment-0.2.0/src/boilpayment_core/policy.py +148 -0
  31. boilpayment-0.2.0/src/boilpayment_core/store.py +104 -0
  32. boilpayment-0.2.0/src/boilpayment_core/types.py +981 -0
  33. boilpayment-0.2.0/src/boilpayment_credits/__init__.py +26 -0
  34. boilpayment-0.2.0/src/boilpayment_credits/clawback.py +111 -0
  35. boilpayment-0.2.0/src/boilpayment_credits/consume.py +69 -0
  36. boilpayment-0.2.0/src/boilpayment_credits/expire.py +63 -0
  37. boilpayment-0.2.0/src/boilpayment_credits/grant.py +489 -0
  38. boilpayment-0.2.0/src/boilpayment_credits/notify_expiring.py +131 -0
  39. boilpayment-0.2.0/src/boilpayment_credits/rollover.py +131 -0
  40. boilpayment-0.2.0/src/boilpayment_cs/__init__.py +187 -0
  41. boilpayment-0.2.0/src/boilpayment_cs/apply_purchased_grant.py +70 -0
  42. boilpayment-0.2.0/src/boilpayment_cs/cases.py +195 -0
  43. boilpayment-0.2.0/src/boilpayment_cs/checkout_support.py +189 -0
  44. boilpayment-0.2.0/src/boilpayment_cs/churn.py +71 -0
  45. boilpayment-0.2.0/src/boilpayment_cs/complete_checkout.py +154 -0
  46. boilpayment-0.2.0/src/boilpayment_cs/dispute.py +435 -0
  47. boilpayment-0.2.0/src/boilpayment_cs/evidence.py +558 -0
  48. boilpayment-0.2.0/src/boilpayment_cs/export_customer.py +101 -0
  49. boilpayment-0.2.0/src/boilpayment_cs/finish_refund_cases.py +71 -0
  50. boilpayment-0.2.0/src/boilpayment_cs/metrics.py +263 -0
  51. boilpayment-0.2.0/src/boilpayment_cs/purchase_snapshot.py +178 -0
  52. boilpayment-0.2.0/src/boilpayment_cs/reconcile.py +128 -0
  53. boilpayment-0.2.0/src/boilpayment_cs/recover_missing_grant.py +269 -0
  54. boilpayment-0.2.0/src/boilpayment_cs/refund_assist.py +341 -0
  55. boilpayment-0.2.0/src/boilpayment_cs/regrant.py +190 -0
  56. boilpayment-0.2.0/src/boilpayment_cs/request_refund.py +128 -0
  57. boilpayment-0.2.0/src/boilpayment_cs/settlement_report.py +107 -0
  58. boilpayment-0.2.0/src/boilpayment_cs/store_purchase.py +319 -0
  59. boilpayment-0.2.0/src/boilpayment_cs/support.py +192 -0
  60. boilpayment-0.2.0/src/boilpayment_cs/timeline.py +700 -0
  61. boilpayment-0.2.0/src/boilpayment_cs/widget.py +87 -0
  62. boilpayment-0.2.0/src/boilpayment_lifecycle/__init__.py +54 -0
  63. boilpayment-0.2.0/src/boilpayment_lifecycle/backfill.py +351 -0
  64. boilpayment-0.2.0/src/boilpayment_lifecycle/cancel.py +218 -0
  65. boilpayment-0.2.0/src/boilpayment_lifecycle/charge_attempt.py +465 -0
  66. boilpayment-0.2.0/src/boilpayment_lifecycle/downgrade.py +185 -0
  67. boilpayment-0.2.0/src/boilpayment_lifecycle/dunning.py +560 -0
  68. boilpayment-0.2.0/src/boilpayment_lifecycle/held.py +216 -0
  69. boilpayment-0.2.0/src/boilpayment_lifecycle/internal.py +125 -0
  70. boilpayment-0.2.0/src/boilpayment_lifecycle/legacy_attempts.py +207 -0
  71. boilpayment-0.2.0/src/boilpayment_lifecycle/missed_periods.py +96 -0
  72. boilpayment-0.2.0/src/boilpayment_lifecycle/period.py +10 -0
  73. boilpayment-0.2.0/src/boilpayment_lifecycle/reactivate.py +296 -0
  74. boilpayment-0.2.0/src/boilpayment_lifecycle/renewal.py +195 -0
  75. boilpayment-0.2.0/src/boilpayment_lifecycle/retry.py +37 -0
  76. boilpayment-0.2.0/src/boilpayment_lifecycle/scheduler.py +319 -0
  77. boilpayment-0.2.0/src/boilpayment_lifecycle/start.py +176 -0
  78. boilpayment-0.2.0/src/boilpayment_lifecycle/trial.py +177 -0
  79. boilpayment-0.2.0/src/boilpayment_lifecycle/upgrade.py +410 -0
  80. boilpayment-0.2.0/src/boilpayment_lifecycle/upgrade_charge.py +115 -0
  81. boilpayment-0.2.0/src/boilpayment_notify/__init__.py +33 -0
  82. boilpayment-0.2.0/src/boilpayment_notify/composite.py +24 -0
  83. boilpayment-0.2.0/src/boilpayment_notify/outbox.py +86 -0
  84. boilpayment-0.2.0/src/boilpayment_notify/resend.py +68 -0
  85. boilpayment-0.2.0/src/boilpayment_notify/slack.py +34 -0
  86. boilpayment-0.2.0/src/boilpayment_notify/smtp.py +81 -0
  87. boilpayment-0.2.0/src/boilpayment_notify/templates.py +160 -0
  88. boilpayment-0.2.0/src/boilpayment_polar/__init__.py +642 -0
  89. boilpayment-0.2.0/src/boilpayment_portone/__init__.py +856 -0
  90. boilpayment-0.2.0/src/boilpayment_refund/__init__.py +36 -0
  91. boilpayment-0.2.0/src/boilpayment_refund/evaluate.py +313 -0
  92. boilpayment-0.2.0/src/boilpayment_refund/execute.py +119 -0
  93. boilpayment-0.2.0/src/boilpayment_refund/execute_request.py +106 -0
  94. boilpayment-0.2.0/src/boilpayment_refund/execute_settle.py +178 -0
  95. boilpayment-0.2.0/src/boilpayment_refund/external.py +362 -0
  96. boilpayment-0.2.0/src/boilpayment_refund/reason.py +38 -0
  97. boilpayment-0.2.0/src/boilpayment_refund/util.py +82 -0
  98. boilpayment-0.2.0/src/boilpayment_schema_postgres/__init__.py +38 -0
  99. boilpayment-0.2.0/src/boilpayment_schema_postgres/audit_log.py +59 -0
  100. boilpayment-0.2.0/src/boilpayment_schema_postgres/consistency.py +57 -0
  101. boilpayment-0.2.0/src/boilpayment_schema_postgres/ledger_store.py +437 -0
  102. boilpayment-0.2.0/src/boilpayment_schema_postgres/mapping.py +115 -0
  103. boilpayment-0.2.0/src/boilpayment_schema_postgres/migrate.py +205 -0
  104. boilpayment-0.2.0/src/boilpayment_schema_postgres/repo.py +731 -0
  105. boilpayment-0.2.0/src/boilpayment_schema_postgres/retention.py +106 -0
  106. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0001_core.sql +144 -0
  107. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0002_credits.sql +159 -0
  108. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0003_usage.sql +48 -0
  109. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0004_webhook.sql +49 -0
  110. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0005_refund.sql +33 -0
  111. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0006_cs.sql +64 -0
  112. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0007_subscription_provider_ref_nullable.sql +3 -0
  113. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0008_iap.sql +15 -0
  114. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0009_ledger_idempotency_per_customer.sql +7 -0
  115. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0010_usage_idempotency_per_customer.sql +5 -0
  116. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0011_subscription_status_paused_incomplete.sql +6 -0
  117. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0012_subscription_currency.sql +4 -0
  118. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0013_ledger_consume_key.sql +10 -0
  119. boilpayment-0.2.0/src/boilpayment_schema_postgres/sql/0014_subscription_billing_customer_ref.sql +6 -0
  120. boilpayment-0.2.0/src/boilpayment_schema_postgres/tx.py +136 -0
  121. boilpayment-0.2.0/src/boilpayment_stripe/__init__.py +1000 -0
  122. boilpayment-0.2.0/src/boilpayment_toss/__init__.py +869 -0
  123. boilpayment-0.2.0/src/boilpayment_usage/__init__.py +47 -0
  124. boilpayment-0.2.0/src/boilpayment_usage/billing_currency.py +27 -0
  125. boilpayment-0.2.0/src/boilpayment_usage/check.py +167 -0
  126. boilpayment-0.2.0/src/boilpayment_usage/close_period.py +68 -0
  127. boilpayment-0.2.0/src/boilpayment_usage/flush_outbox.py +93 -0
  128. boilpayment-0.2.0/src/boilpayment_usage/period.py +15 -0
  129. boilpayment-0.2.0/src/boilpayment_usage/prepare_settlement.py +199 -0
  130. boilpayment-0.2.0/src/boilpayment_usage/record.py +121 -0
  131. boilpayment-0.2.0/src/boilpayment_usage/report_period.py +63 -0
  132. boilpayment-0.2.0/src/boilpayment_usage/reservation.py +343 -0
  133. boilpayment-0.2.0/src/boilpayment_usage/resettle_period.py +99 -0
  134. boilpayment-0.2.0/src/boilpayment_usage/settle_due_periods.py +98 -0
  135. boilpayment-0.2.0/src/boilpayment_usage/settle_period.py +150 -0
  136. boilpayment-0.2.0/src/boilpayment_usage/settlement_period.py +46 -0
  137. boilpayment-0.2.0/src/boilpayment_usage/settlement_types.py +62 -0
  138. boilpayment-0.2.0/src/boilpayment_webhook/__init__.py +32 -0
  139. boilpayment-0.2.0/src/boilpayment_webhook/attempt_row.py +37 -0
  140. boilpayment-0.2.0/src/boilpayment_webhook/correlation.py +62 -0
  141. boilpayment-0.2.0/src/boilpayment_webhook/grants.py +33 -0
  142. boilpayment-0.2.0/src/boilpayment_webhook/handlers.py +493 -0
  143. boilpayment-0.2.0/src/boilpayment_webhook/http.py +47 -0
  144. boilpayment-0.2.0/src/boilpayment_webhook/identity.py +69 -0
  145. boilpayment-0.2.0/src/boilpayment_webhook/payment_ref.py +103 -0
  146. boilpayment-0.2.0/src/boilpayment_webhook/process.py +189 -0
  147. boilpayment-0.2.0/src/boilpayment_webhook/receive.py +98 -0
  148. boilpayment-0.2.0/src/boilpayment_webhook/refund.py +113 -0
@@ -0,0 +1,13 @@
1
+ node_modules/
2
+ dist/
3
+ *.tsbuildinfo
4
+ .venv/
5
+ __pycache__/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .env
10
+ .env.*
11
+ !.env.example
12
+ .DS_Store
13
+ paykit.config.json
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 boilpayment contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.5
2
+ Name: boilpayment
3
+ Version: 0.2.0
4
+ Summary: Payment kit: refunds, dunning, renewals and overage for code generated by npx boilpayment init. Part of Schift's boil series.
5
+ Project-URL: Homepage, https://github.com/schift-io/boilpayment#readme
6
+ Project-URL: Repository, https://github.com/schift-io/boilpayment.git
7
+ Project-URL: Issues, https://github.com/schift-io/boilpayment/issues
8
+ Author: boilpayment contributors
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Office/Business :: Financial
15
+ Requires-Python: >=3.11
16
+ Requires-Dist: cryptography>=43
17
+ Requires-Dist: httpx>=0.27
18
+ Requires-Dist: psycopg-pool>=3.2
19
+ Requires-Dist: psycopg[binary]>=3.2
20
+ Requires-Dist: stripe>=11
21
+ Description-Content-Type: text/markdown
22
+
23
+ # boilpayment
24
+
25
+ Single-install facade for boilpayment. Depends on all 13 `boilpayment-*`
26
+ distributions pinned to the exact version published alongside it (`==0.1.0`, not a range — a
27
+ mismatched internal version can never happen) and re-exports every one of them as a submodule, so
28
+ a project only installs and imports **one** distribution instead of thirteen.
29
+
30
+ ## Install
31
+
32
+ ```
33
+ pip install boilpayment
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ Pick your module by submodule:
39
+
40
+ ```python
41
+ from boilpayment.core import resolve_policy, InMemoryLedger, InMemoryRepo, SystemClock, UuidIdGen
42
+ from boilpayment.lifecycle import upgrade, downgrade, cancel, reactivate
43
+ from boilpayment.credits import consume, topup
44
+ from boilpayment.refund import evaluate, execute
45
+ from boilpayment.usage import record, check
46
+ from boilpayment.webhook import receive, process, default_handlers
47
+ from boilpayment.notify import resend, smtp, slack
48
+ from boilpayment.cs import open_case, escalate
49
+ from boilpayment.postgres import PostgresRepo, PostgresLedgerStore, migrate
50
+ from boilpayment.stripe import StripeProvider
51
+ from boilpayment.toss import TossProvider
52
+ from boilpayment.portone import PortoneProvider
53
+ from boilpayment.polar import PolarProvider
54
+ ```
55
+
56
+ Every submodule above (`.core`, `.credits`, `.lifecycle`, `.refund`, `.usage`, `.webhook`,
57
+ `.notify`, `.cs`, `.postgres`, `.stripe`, `.toss`, `.portone`, `.polar`) is a **full, unfiltered**
58
+ re-export of the corresponding `boilpayment-*` distribution — nothing is renamed or
59
+ dropped, and each has its own explicit `__all__` mirroring the source distribution's public
60
+ surface.
61
+
62
+ The package root (`from boilpayment import ...`, no submodule) is narrower — see below.
63
+
64
+ ## Root export & name collisions
65
+
66
+ `boilpayment` (the bare root import) re-exports the **full** surface of
67
+ `boilpayment_core` (types, `Policy`, `Clock`/`IdGen`, period/money helpers, idempotency
68
+ helpers, in-memory reference implementations, logging) plus a curated set of the most-used entry
69
+ points from the five core operation modules:
70
+
71
+ | from | names |
72
+ |---|---|
73
+ | lifecycle | `upgrade`, `downgrade`, `cancel`, `reactivate` |
74
+ | credits | `consume`, `topup` |
75
+ | refund | `evaluate`, `execute`, `on_external_refund` |
76
+ | usage | `record`, `check` |
77
+ | webhook | `receive`, `process`, `default_handlers` |
78
+
79
+ **Not** re-exported at the root — every one of these is a deliberate exclusion, not an oversight:
80
+
81
+ - **The four provider adapters** (`.stripe`, `.toss`, `.portone`, `.polar`) — they export several
82
+ same-named symbols with genuinely different shapes:
83
+ - `normalize_failure`, `normalize_subscription`, `normalize_refund`, `map_event_type`,
84
+ `to_normalized_event` — defined by **both** `boilpayment_stripe` and
85
+ `boilpayment_polar`, with different signatures.
86
+ - `CashReceiptType`, `CashReceiptStatus`, `CashReceipt` — defined by **both**
87
+ `boilpayment_toss` and `boilpayment_portone`, with different shapes.
88
+
89
+ Re-exporting any two providers at the same root would silently shadow one implementation with
90
+ the other depending on import order. Import providers from their own submodule.
91
+ - **`.refund`'s own `proration_ratio`** (and `days_between`/`apply_rounding`/
92
+ `weighted_avg_unit_price`) — `proration_ratio` is a **real** collision with
93
+ `boilpayment_core`'s own `proration_ratio` (already re-exported at the root via the core
94
+ surface). The root always resolves to core's version; refund's copy is only reachable via
95
+ `boilpayment.refund`.
96
+ - **`.notify`, `.cs`, `.postgres`** — add-on/infra modules most projects don't touch.
97
+ - **The rest of `.lifecycle`** (`convert_trial`, `retry_on_version_conflict`, the `dunning`,
98
+ `scheduler`, `period` submodules), **`.credits`** (`grant_for_period`, `rollover_on_renewal`,
99
+ `clawback`, `expire_due`, `notify_expiring`), **`.usage`** (`close_period`, `flush_outbox`),
100
+ **`.webhook`** (`process_pending`, http helpers, correlation-id helpers) — no collision, just
101
+ kept off the root to keep it short. Pull these from their submodule.
102
+
103
+ Full contract: [docs/ARCHITECTURE.md](https://github.com/schift-io/boilpayment/blob/main/docs/ARCHITECTURE.md) ·
104
+ [docs/EDGE_CASES.md](https://github.com/schift-io/boilpayment/blob/main/docs/EDGE_CASES.md).
@@ -0,0 +1,82 @@
1
+ # boilpayment
2
+
3
+ Single-install facade for boilpayment. Depends on all 13 `boilpayment-*`
4
+ distributions pinned to the exact version published alongside it (`==0.1.0`, not a range — a
5
+ mismatched internal version can never happen) and re-exports every one of them as a submodule, so
6
+ a project only installs and imports **one** distribution instead of thirteen.
7
+
8
+ ## Install
9
+
10
+ ```
11
+ pip install boilpayment
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ Pick your module by submodule:
17
+
18
+ ```python
19
+ from boilpayment.core import resolve_policy, InMemoryLedger, InMemoryRepo, SystemClock, UuidIdGen
20
+ from boilpayment.lifecycle import upgrade, downgrade, cancel, reactivate
21
+ from boilpayment.credits import consume, topup
22
+ from boilpayment.refund import evaluate, execute
23
+ from boilpayment.usage import record, check
24
+ from boilpayment.webhook import receive, process, default_handlers
25
+ from boilpayment.notify import resend, smtp, slack
26
+ from boilpayment.cs import open_case, escalate
27
+ from boilpayment.postgres import PostgresRepo, PostgresLedgerStore, migrate
28
+ from boilpayment.stripe import StripeProvider
29
+ from boilpayment.toss import TossProvider
30
+ from boilpayment.portone import PortoneProvider
31
+ from boilpayment.polar import PolarProvider
32
+ ```
33
+
34
+ Every submodule above (`.core`, `.credits`, `.lifecycle`, `.refund`, `.usage`, `.webhook`,
35
+ `.notify`, `.cs`, `.postgres`, `.stripe`, `.toss`, `.portone`, `.polar`) is a **full, unfiltered**
36
+ re-export of the corresponding `boilpayment-*` distribution — nothing is renamed or
37
+ dropped, and each has its own explicit `__all__` mirroring the source distribution's public
38
+ surface.
39
+
40
+ The package root (`from boilpayment import ...`, no submodule) is narrower — see below.
41
+
42
+ ## Root export & name collisions
43
+
44
+ `boilpayment` (the bare root import) re-exports the **full** surface of
45
+ `boilpayment_core` (types, `Policy`, `Clock`/`IdGen`, period/money helpers, idempotency
46
+ helpers, in-memory reference implementations, logging) plus a curated set of the most-used entry
47
+ points from the five core operation modules:
48
+
49
+ | from | names |
50
+ |---|---|
51
+ | lifecycle | `upgrade`, `downgrade`, `cancel`, `reactivate` |
52
+ | credits | `consume`, `topup` |
53
+ | refund | `evaluate`, `execute`, `on_external_refund` |
54
+ | usage | `record`, `check` |
55
+ | webhook | `receive`, `process`, `default_handlers` |
56
+
57
+ **Not** re-exported at the root — every one of these is a deliberate exclusion, not an oversight:
58
+
59
+ - **The four provider adapters** (`.stripe`, `.toss`, `.portone`, `.polar`) — they export several
60
+ same-named symbols with genuinely different shapes:
61
+ - `normalize_failure`, `normalize_subscription`, `normalize_refund`, `map_event_type`,
62
+ `to_normalized_event` — defined by **both** `boilpayment_stripe` and
63
+ `boilpayment_polar`, with different signatures.
64
+ - `CashReceiptType`, `CashReceiptStatus`, `CashReceipt` — defined by **both**
65
+ `boilpayment_toss` and `boilpayment_portone`, with different shapes.
66
+
67
+ Re-exporting any two providers at the same root would silently shadow one implementation with
68
+ the other depending on import order. Import providers from their own submodule.
69
+ - **`.refund`'s own `proration_ratio`** (and `days_between`/`apply_rounding`/
70
+ `weighted_avg_unit_price`) — `proration_ratio` is a **real** collision with
71
+ `boilpayment_core`'s own `proration_ratio` (already re-exported at the root via the core
72
+ surface). The root always resolves to core's version; refund's copy is only reachable via
73
+ `boilpayment.refund`.
74
+ - **`.notify`, `.cs`, `.postgres`** — add-on/infra modules most projects don't touch.
75
+ - **The rest of `.lifecycle`** (`convert_trial`, `retry_on_version_conflict`, the `dunning`,
76
+ `scheduler`, `period` submodules), **`.credits`** (`grant_for_period`, `rollover_on_renewal`,
77
+ `clawback`, `expire_due`, `notify_expiring`), **`.usage`** (`close_period`, `flush_outbox`),
78
+ **`.webhook`** (`process_pending`, http helpers, correlation-id helpers) — no collision, just
79
+ kept off the root to keep it short. Pull these from their submodule.
80
+
81
+ Full contract: [docs/ARCHITECTURE.md](https://github.com/schift-io/boilpayment/blob/main/docs/ARCHITECTURE.md) ·
82
+ [docs/EDGE_CASES.md](https://github.com/schift-io/boilpayment/blob/main/docs/EDGE_CASES.md).
@@ -0,0 +1,28 @@
1
+ [project]
2
+ name = "boilpayment"
3
+ version = "0.2.0"
4
+ description = "Payment kit: refunds, dunning, renewals and overage for code generated by npx boilpayment init. Part of Schift's boil series."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [{ name = "boilpayment contributors" }]
9
+ requires-python = ">=3.11"
10
+ dependencies = ["cryptography>=43", "httpx>=0.27", "psycopg-pool>=3.2", "psycopg[binary]>=3.2", "stripe>=11"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Developers",
14
+ "Programming Language :: Python :: 3",
15
+ "Topic :: Office/Business :: Financial",
16
+ ]
17
+
18
+ [project.urls]
19
+ Homepage = "https://github.com/schift-io/boilpayment#readme"
20
+ Repository = "https://github.com/schift-io/boilpayment.git"
21
+ Issues = "https://github.com/schift-io/boilpayment/issues"
22
+
23
+ [build-system]
24
+ requires = ["hatchling"]
25
+ build-backend = "hatchling.build"
26
+
27
+ [tool.hatch.build.targets.wheel]
28
+ packages = ["src/boilpayment_core","src/boilpayment_credits","src/boilpayment_refund","src/boilpayment_usage","src/boilpayment_webhook","src/boilpayment_notify","src/boilpayment_schema_postgres","src/boilpayment_lifecycle","src/boilpayment_cs","src/boilpayment_stripe","src/boilpayment_toss","src/boilpayment_portone","src/boilpayment_polar","src/boilpayment"]
@@ -0,0 +1,337 @@
1
+ """boilpayment -- root export.
2
+
3
+ Deliberately narrow (see ../README.md "Root export & name collisions" for the full rationale and
4
+ the two real name collisions this avoids). What's here:
5
+ 1. The full surface of boilpayment_core (types, Policy, Clock/IdGen, period/money
6
+ helpers, idempotency helpers, in-memory reference implementations, logging) -- this is what
7
+ every other module's function signatures are built from, so it's safe and expected to be
8
+ fully available at the root.
9
+ 2. A curated set of the most-used entry points from the five core operation modules
10
+ (lifecycle, credits, refund, usage, webhook), so
11
+ `from boilpayment import upgrade, consume, evaluate, record, receive` covers the
12
+ common path without picking a submodule.
13
+
14
+ NOT re-exported here -- use the dedicated submodule instead:
15
+ - `.stripe`, `.toss`, `.portone`, `.polar` -- the four provider adapters export several
16
+ same-named functions/types with DIFFERENT shapes (`normalize_failure`,
17
+ `normalize_subscription`, `normalize_refund`, `map_event_type`, `to_normalized_event` collide
18
+ between stripe/polar; `CashReceiptType`, `CashReceiptStatus`, `CashReceipt` collide between
19
+ toss/portone). Bundling any two of them at the root would silently shadow one implementation
20
+ with the other.
21
+ - `.notify`, `.cs`, `.postgres` -- add-on/infra modules, not every project uses them.
22
+ - `.refund`'s own `proration_ratio` (and `days_between`/`apply_rounding`/
23
+ `weighted_avg_unit_price`) -- `proration_ratio` is a REAL collision with core's own
24
+ `proration_ratio` (re-exported via #1 above); refund's copy is available at `.refund` only, so
25
+ `from boilpayment import ...` always gets core's version unambiguously.
26
+ - the rest of `.lifecycle` (`downgrade`/`convert_trial`/`retry_on_version_conflict`/the
27
+ `dunning`, `scheduler`, `period` submodules), `.credits` (`grant_for_period`/
28
+ `rollover_on_renewal`/`clawback`/`expire_due`/`notify_expiring`), `.usage`
29
+ (`close_period`/`flush_outbox`), `.webhook` (`process_pending`/`default_handlers`/http
30
+ helpers/correlation ids) -- deeper wiring, no collisions, just kept off the root to keep it a
31
+ short list. Pull them from their submodule.
32
+ """
33
+
34
+ from __future__ import annotations
35
+
36
+ from boilpayment_core import (
37
+ DEFAULT_POLICY,
38
+ ZERO_DECIMAL_CURRENCIES,
39
+ AnnualRefundMethod,
40
+ AppendResult,
41
+ Balance,
42
+ BankReset,
43
+ BaseLogger,
44
+ CancelCredits,
45
+ CancelMode,
46
+ CashReceiptMode,
47
+ CashReceiptRef,
48
+ CashReceiptType,
49
+ Checkout,
50
+ ClawbackShortfall,
51
+ Clock,
52
+ CollectingLogger,
53
+ CollectingNotifier,
54
+ ConsoleLogger,
55
+ ConsumeInput,
56
+ ConsumeOrder,
57
+ ConsumeResult,
58
+ CreateCheckoutInput,
59
+ CsCase,
60
+ CsCaseKind,
61
+ CsCaseStatus,
62
+ Customer,
63
+ CustomerStatus,
64
+ Deps,
65
+ DisputeOnLost,
66
+ DisputeOnOpen,
67
+ DowngradeMode,
68
+ ExpiringBucket,
69
+ FeeBearer,
70
+ FixedClock,
71
+ GrantDuringGrace,
72
+ GrantLagBehavior,
73
+ IdGen,
74
+ InMemoryLedger,
75
+ InMemoryRepo,
76
+ InsufficientBalanceError,
77
+ Interval,
78
+ IntervalChangeMode,
79
+ LedgerEntry,
80
+ LedgerKind,
81
+ LedgerReference,
82
+ LedgerSource,
83
+ LedgerStore,
84
+ Logger,
85
+ LogLevel,
86
+ MemTable,
87
+ Money,
88
+ MonthEndAnchor,
89
+ MultipleSubscriptions,
90
+ NegativeBalance,
91
+ NegativeOffset,
92
+ NewLedgerEntry,
93
+ NoopLogger,
94
+ NoopNotifier,
95
+ NormalizedEvent,
96
+ NormalizedEventType,
97
+ Notification,
98
+ Notifier,
99
+ NotifyType,
100
+ OnFinalFailure,
101
+ OnRecovery,
102
+ Operation,
103
+ OperationStatus,
104
+ OutboxItem,
105
+ Overage,
106
+ OveruseBehavior,
107
+ PauseMode,
108
+ Payment,
109
+ PaymentFailure,
110
+ PaymentKind,
111
+ PaymentKitError,
112
+ PaymentProvider,
113
+ PaymentStatus,
114
+ Period,
115
+ Plan,
116
+ PlanPrice,
117
+ Policy,
118
+ PolicyValidationError,
119
+ Pool,
120
+ PoolMode,
121
+ ProrationDenominator,
122
+ ProviderCapabilities,
123
+ ProviderError,
124
+ ProviderName,
125
+ ProviderRef,
126
+ Refund,
127
+ RefundDecision,
128
+ RefundMethod,
129
+ RefundRounding,
130
+ RefundStatus,
131
+ RegrantMode,
132
+ Repo,
133
+ RevokeShortfall,
134
+ Rollover,
135
+ RunIdempotentResult,
136
+ SequentialIdGen,
137
+ Subscription,
138
+ SubscriptionStatus,
139
+ SystemClock,
140
+ Table,
141
+ TrialAbuseGuard,
142
+ TrialCreditsOnCancel,
143
+ TrialCreditsOnConvert,
144
+ UpgradeCreditDelta,
145
+ UpgradeMode,
146
+ UsageDuringGrace,
147
+ UsageEvent,
148
+ UuidIdGen,
149
+ WebhookEventRecord,
150
+ WebhookEventStatus,
151
+ WebhookSignatureError,
152
+ add_money,
153
+ assert_same_currency,
154
+ civil_day_of,
155
+ days_in_month,
156
+ days_in_period,
157
+ deserialize_cs_case,
158
+ deserialize_ledger_entry,
159
+ deserialize_refund,
160
+ deserialize_subscription,
161
+ elapsed_ratio,
162
+ hash_payload,
163
+ money,
164
+ mul_money_ratio,
165
+ next_period,
166
+ period_containing,
167
+ proration_ratio,
168
+ redact,
169
+ resolve_policy,
170
+ serialize_cs_case,
171
+ serialize_ledger_entry,
172
+ serialize_refund,
173
+ serialize_subscription,
174
+ stable_stringify,
175
+ validate_policy,
176
+ )
177
+ from boilpayment_credits import consume, topup
178
+ from boilpayment_lifecycle import cancel, downgrade, reactivate, upgrade
179
+ from boilpayment_refund import evaluate, execute, on_external_refund
180
+ from boilpayment_usage import check, record
181
+ from boilpayment_webhook import default_handlers, process, receive
182
+
183
+ __all__ = [
184
+ "DEFAULT_POLICY",
185
+ "ZERO_DECIMAL_CURRENCIES",
186
+ "AnnualRefundMethod",
187
+ "AppendResult",
188
+ "Balance",
189
+ "BankReset",
190
+ "BaseLogger",
191
+ "CancelCredits",
192
+ "CancelMode",
193
+ "CashReceiptMode",
194
+ "CashReceiptRef",
195
+ "CashReceiptType",
196
+ "Checkout",
197
+ "ClawbackShortfall",
198
+ "Clock",
199
+ "CollectingLogger",
200
+ "CollectingNotifier",
201
+ "ConsoleLogger",
202
+ "ConsumeInput",
203
+ "ConsumeOrder",
204
+ "ConsumeResult",
205
+ "CreateCheckoutInput",
206
+ "CsCase",
207
+ "CsCaseKind",
208
+ "CsCaseStatus",
209
+ "Customer",
210
+ "CustomerStatus",
211
+ "Deps",
212
+ "DisputeOnLost",
213
+ "DisputeOnOpen",
214
+ "DowngradeMode",
215
+ "ExpiringBucket",
216
+ "FeeBearer",
217
+ "FixedClock",
218
+ "GrantDuringGrace",
219
+ "GrantLagBehavior",
220
+ "IdGen",
221
+ "InMemoryLedger",
222
+ "InMemoryRepo",
223
+ "InsufficientBalanceError",
224
+ "Interval",
225
+ "IntervalChangeMode",
226
+ "LedgerEntry",
227
+ "LedgerKind",
228
+ "LedgerReference",
229
+ "LedgerSource",
230
+ "LedgerStore",
231
+ "LogLevel",
232
+ "Logger",
233
+ "MemTable",
234
+ "Money",
235
+ "MonthEndAnchor",
236
+ "MultipleSubscriptions",
237
+ "NegativeBalance",
238
+ "NegativeOffset",
239
+ "NewLedgerEntry",
240
+ "NoopLogger",
241
+ "NoopNotifier",
242
+ "NormalizedEvent",
243
+ "NormalizedEventType",
244
+ "Notification",
245
+ "Notifier",
246
+ "NotifyType",
247
+ "OnFinalFailure",
248
+ "OnRecovery",
249
+ "Operation",
250
+ "OperationStatus",
251
+ "OutboxItem",
252
+ "Overage",
253
+ "OveruseBehavior",
254
+ "PauseMode",
255
+ "Payment",
256
+ "PaymentFailure",
257
+ "PaymentKind",
258
+ "PaymentKitError",
259
+ "PaymentProvider",
260
+ "PaymentStatus",
261
+ "Period",
262
+ "Plan",
263
+ "PlanPrice",
264
+ "Policy",
265
+ "PolicyValidationError",
266
+ "Pool",
267
+ "PoolMode",
268
+ "ProrationDenominator",
269
+ "ProviderCapabilities",
270
+ "ProviderError",
271
+ "ProviderName",
272
+ "ProviderRef",
273
+ "Refund",
274
+ "RefundDecision",
275
+ "RefundMethod",
276
+ "RefundRounding",
277
+ "RefundStatus",
278
+ "RegrantMode",
279
+ "Repo",
280
+ "RevokeShortfall",
281
+ "Rollover",
282
+ "RunIdempotentResult",
283
+ "SequentialIdGen",
284
+ "Subscription",
285
+ "SubscriptionStatus",
286
+ "SystemClock",
287
+ "Table",
288
+ "TrialAbuseGuard",
289
+ "TrialCreditsOnCancel",
290
+ "TrialCreditsOnConvert",
291
+ "UpgradeCreditDelta",
292
+ "UpgradeMode",
293
+ "UsageDuringGrace",
294
+ "UsageEvent",
295
+ "UuidIdGen",
296
+ "WebhookEventRecord",
297
+ "WebhookEventStatus",
298
+ "WebhookSignatureError",
299
+ "add_money",
300
+ "assert_same_currency",
301
+ "cancel",
302
+ "check",
303
+ "civil_day_of",
304
+ "consume",
305
+ "days_in_month",
306
+ "days_in_period",
307
+ "default_handlers",
308
+ "deserialize_cs_case",
309
+ "deserialize_ledger_entry",
310
+ "deserialize_refund",
311
+ "deserialize_subscription",
312
+ "downgrade",
313
+ "elapsed_ratio",
314
+ "evaluate",
315
+ "execute",
316
+ "hash_payload",
317
+ "money",
318
+ "mul_money_ratio",
319
+ "next_period",
320
+ "on_external_refund",
321
+ "period_containing",
322
+ "process",
323
+ "proration_ratio",
324
+ "reactivate",
325
+ "receive",
326
+ "record",
327
+ "redact",
328
+ "resolve_policy",
329
+ "serialize_cs_case",
330
+ "serialize_ledger_entry",
331
+ "serialize_refund",
332
+ "serialize_subscription",
333
+ "stable_stringify",
334
+ "topup",
335
+ "upgrade",
336
+ "validate_policy",
337
+ ]