paymenthub 0.1.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.
@@ -0,0 +1,19 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: astral-sh/setup-uv@v3
14
+ with:
15
+ python-version: "3.12"
16
+ - run: uv run --extra dev ruff check .
17
+ - run: uv run --extra dev mypy src
18
+ - run: uv run --extra dev pytest -q
19
+ - run: uv build
@@ -0,0 +1,40 @@
1
+ name: release
2
+
3
+ # Publishes `paymenthub` to PyPI. Triggered by:
4
+ # - a `v*` tag pushed to this repo, OR
5
+ # - a repository_dispatch (type `release`) fired by paymenthub-be on its own tag, OR
6
+ # - manual run.
7
+ #
8
+ # PyPI publishing uses Trusted Publishing (OIDC) — no token stored. Configure a
9
+ # trusted publisher on PyPI for this repo + this workflow.
10
+ # Required repo secret: PAYMENTHUB_TEST_KEY (a test-mode key for the CI smoke test).
11
+ on:
12
+ push:
13
+ tags: ["v*"]
14
+ repository_dispatch:
15
+ types: [release]
16
+ workflow_dispatch:
17
+
18
+ permissions:
19
+ contents: read
20
+ id-token: write # PyPI Trusted Publishing (OIDC)
21
+
22
+ jobs:
23
+ publish:
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ - uses: astral-sh/setup-uv@v3
28
+ with:
29
+ python-version: "3.12"
30
+ - run: uv run --extra dev ruff check .
31
+ - run: uv run --extra dev mypy src
32
+ - run: uv run --extra dev pytest -q
33
+ - run: uv build
34
+ # Acceptance: the built SDK completes a sandbox payment against prod.
35
+ - name: sandbox smoke test
36
+ env:
37
+ PAYMENTHUB_TEST_KEY: ${{ secrets.PAYMENTHUB_TEST_KEY }}
38
+ run: uv run python scripts/smoke.py
39
+ - name: publish to PyPI (Trusted Publishing)
40
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .mypy_cache/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .DS_Store
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: paymenthub
3
+ Version: 0.1.0
4
+ Summary: Typed Python client + webhook verification for the PaymentHub API.
5
+ Project-URL: Repository, https://github.com/ahmeddmohamed-noon/paymenthub-sdk-python
6
+ Author: PaymentHub
7
+ License-Expression: MIT
8
+ Keywords: paymenthub,payments,paymob,sdk,stripe
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: httpx>=0.27
11
+ Requires-Dist: pydantic[email]>=2.7
12
+ Provides-Extra: dev
13
+ Requires-Dist: datamodel-code-generator>=0.26; extra == 'dev'
14
+ Requires-Dist: mypy>=1.11; extra == 'dev'
15
+ Requires-Dist: pytest>=8; extra == 'dev'
16
+ Requires-Dist: ruff>=0.7; extra == 'dev'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # paymenthub (Python SDK)
20
+
21
+ Typed Python client + webhook verification for the [PaymentHub](https://github.com/ahmeddmohamed-noon/paymenthub-be) API. Models are generated from PaymentHub's published OpenAPI spec with `datamodel-code-generator`, so responses are validated pydantic models.
22
+
23
+ > Sandbox-only portfolio project.
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install paymenthub
29
+ ```
30
+
31
+ ## Quickstart
32
+
33
+ ```python
34
+ from paymenthub import PaymentHubClient, PaymentCreate
35
+
36
+ with PaymentHubClient(api_key="sk_test_…") as ph:
37
+ # One-call sandbox bootstrap (test-mode keys only):
38
+ demo = ph.seed_sandbox() # -> SandboxSeedResponse(api_key, merchant_id, sample_payment_ids)
39
+
40
+ payment = ph.create_payment(PaymentCreate(
41
+ amount_minor=1500,
42
+ currency="USD",
43
+ success_url="https://example.com/success",
44
+ cancel_url="https://example.com/cancel",
45
+ ))
46
+ print(payment.checkout_url)
47
+
48
+ detail = ph.get_payment(payment.id)
49
+ ```
50
+
51
+ `PaymentHubClient` defaults to the hosted gateway; pass `base_url=` to point elsewhere, or `http_client=` to inject a custom/mocked `httpx.Client`.
52
+
53
+ ## Webhook verification
54
+
55
+ Verify the **raw** request body server-side (don't re-serialize):
56
+
57
+ ```python
58
+ from paymenthub import verify_webhook
59
+
60
+ ok = verify_webhook(
61
+ provider="stripe", # or "paymob"
62
+ payload=raw_body, # str | bytes
63
+ signature=request.headers["x-paymenthub-signature"],
64
+ secret=WEBHOOK_SECRET,
65
+ )
66
+ ```
67
+
68
+ - **Stripe-style** (`verify_stripe_signature`): `t=<unix>,v1=<hex>` header; HMAC-SHA256 over `f"{t}.{body}"` with a replay tolerance (default 5 min).
69
+ - **Paymob-style** (`verify_paymob_hmac`): raw HMAC-SHA256 hex digest over the body.
70
+
71
+ All comparisons use `hmac.compare_digest` (constant-time).
72
+
73
+ ## Development
74
+
75
+ ```bash
76
+ uv run --extra dev ruff check .
77
+ uv run --extra dev mypy src
78
+ uv run --extra dev pytest
79
+ uv build
80
+ ```
81
+
82
+ Models live in `src/paymenthub/_models.py`, generated from the vendored `openapi.json`:
83
+
84
+ ```bash
85
+ uv run --with datamodel-code-generator datamodel-codegen \
86
+ --input openapi.json --input-file-type openapi \
87
+ --output src/paymenthub/_models.py \
88
+ --output-model-type pydantic_v2.BaseModel \
89
+ --target-python-version 3.10 --use-standard-collections --use-union-operator
90
+ ```
91
+
92
+ Refresh `openapi.json` from the backend and re-run when the API changes.
93
+
94
+ ## Releasing
95
+
96
+ `release.yml` publishes to PyPI on a `v*` tag (or a `repository_dispatch` from the backend) via **Trusted Publishing (OIDC)** — no token stored. It runs the test suite and **completes a sandbox payment against prod** before publishing. Configure a PyPI trusted publisher for this repo + workflow, and add a `PAYMENTHUB_TEST_KEY` repo secret for the smoke test.
@@ -0,0 +1,78 @@
1
+ # paymenthub (Python SDK)
2
+
3
+ Typed Python client + webhook verification for the [PaymentHub](https://github.com/ahmeddmohamed-noon/paymenthub-be) API. Models are generated from PaymentHub's published OpenAPI spec with `datamodel-code-generator`, so responses are validated pydantic models.
4
+
5
+ > Sandbox-only portfolio project.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install paymenthub
11
+ ```
12
+
13
+ ## Quickstart
14
+
15
+ ```python
16
+ from paymenthub import PaymentHubClient, PaymentCreate
17
+
18
+ with PaymentHubClient(api_key="sk_test_…") as ph:
19
+ # One-call sandbox bootstrap (test-mode keys only):
20
+ demo = ph.seed_sandbox() # -> SandboxSeedResponse(api_key, merchant_id, sample_payment_ids)
21
+
22
+ payment = ph.create_payment(PaymentCreate(
23
+ amount_minor=1500,
24
+ currency="USD",
25
+ success_url="https://example.com/success",
26
+ cancel_url="https://example.com/cancel",
27
+ ))
28
+ print(payment.checkout_url)
29
+
30
+ detail = ph.get_payment(payment.id)
31
+ ```
32
+
33
+ `PaymentHubClient` defaults to the hosted gateway; pass `base_url=` to point elsewhere, or `http_client=` to inject a custom/mocked `httpx.Client`.
34
+
35
+ ## Webhook verification
36
+
37
+ Verify the **raw** request body server-side (don't re-serialize):
38
+
39
+ ```python
40
+ from paymenthub import verify_webhook
41
+
42
+ ok = verify_webhook(
43
+ provider="stripe", # or "paymob"
44
+ payload=raw_body, # str | bytes
45
+ signature=request.headers["x-paymenthub-signature"],
46
+ secret=WEBHOOK_SECRET,
47
+ )
48
+ ```
49
+
50
+ - **Stripe-style** (`verify_stripe_signature`): `t=<unix>,v1=<hex>` header; HMAC-SHA256 over `f"{t}.{body}"` with a replay tolerance (default 5 min).
51
+ - **Paymob-style** (`verify_paymob_hmac`): raw HMAC-SHA256 hex digest over the body.
52
+
53
+ All comparisons use `hmac.compare_digest` (constant-time).
54
+
55
+ ## Development
56
+
57
+ ```bash
58
+ uv run --extra dev ruff check .
59
+ uv run --extra dev mypy src
60
+ uv run --extra dev pytest
61
+ uv build
62
+ ```
63
+
64
+ Models live in `src/paymenthub/_models.py`, generated from the vendored `openapi.json`:
65
+
66
+ ```bash
67
+ uv run --with datamodel-code-generator datamodel-codegen \
68
+ --input openapi.json --input-file-type openapi \
69
+ --output src/paymenthub/_models.py \
70
+ --output-model-type pydantic_v2.BaseModel \
71
+ --target-python-version 3.10 --use-standard-collections --use-union-operator
72
+ ```
73
+
74
+ Refresh `openapi.json` from the backend and re-run when the API changes.
75
+
76
+ ## Releasing
77
+
78
+ `release.yml` publishes to PyPI on a `v*` tag (or a `repository_dispatch` from the backend) via **Trusted Publishing (OIDC)** — no token stored. It runs the test suite and **completes a sandbox payment against prod** before publishing. Configure a PyPI trusted publisher for this repo + workflow, and add a `PAYMENTHUB_TEST_KEY` repo secret for the smoke test.