extendvcc-cli 0.1.0__py3-none-any.whl
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.
- extendvcc/__init__.py +46 -0
- extendvcc/_exit_codes.py +24 -0
- extendvcc/_jsonl.py +35 -0
- extendvcc/_paths.py +28 -0
- extendvcc/auth.py +900 -0
- extendvcc/cards.py +761 -0
- extendvcc/cli.py +883 -0
- extendvcc/client.py +491 -0
- extendvcc/imap_otp.py +170 -0
- extendvcc/ledger.py +535 -0
- extendvcc/models.py +74 -0
- extendvcc/py.typed +0 -0
- extendvcc_cli-0.1.0.dist-info/METADATA +179 -0
- extendvcc_cli-0.1.0.dist-info/RECORD +17 -0
- extendvcc_cli-0.1.0.dist-info/WHEEL +4 -0
- extendvcc_cli-0.1.0.dist-info/entry_points.txt +2 -0
- extendvcc_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: extendvcc-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial CLI and Python client for the Extend virtual card API
|
|
5
|
+
Project-URL: Homepage, https://github.com/4LAU/extendvcc
|
|
6
|
+
Project-URL: Repository, https://github.com/4LAU/extendvcc
|
|
7
|
+
Project-URL: Issues, https://github.com/4LAU/extendvcc/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/4LAU/extendvcc/blob/main/CHANGELOG.md
|
|
9
|
+
Author: 4LAU
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cli,extend,fintech,virtual-card
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: filelock>=3.0
|
|
22
|
+
Requires-Dist: impit>=0.12.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# extendvcc
|
|
30
|
+
|
|
31
|
+
[](https://github.com/4LAU/extendvcc/actions/workflows/ci.yml)
|
|
32
|
+
[](https://pypi.org/project/extendvcc-cli/)
|
|
33
|
+
[](LICENSE)
|
|
34
|
+
[](https://pypi.org/project/extendvcc-cli/)
|
|
35
|
+
|
|
36
|
+
Unofficial CLI and Python client for the Extend virtual card API.
|
|
37
|
+
|
|
38
|
+
> **Disclaimer**
|
|
39
|
+
>
|
|
40
|
+
> This is an unofficial, independent client for Extend's private browser
|
|
41
|
+
> API (`api.paywithextend.com`). It is not affiliated with, endorsed by, or
|
|
42
|
+
> supported by Extend, Inc. Use at your own risk. Your Extend account may be
|
|
43
|
+
> suspended for running automation against their private API.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install extendvcc-cli
|
|
49
|
+
# or
|
|
50
|
+
pipx install extendvcc-cli
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Standalone binary (no Python required): download from [GitHub Releases](../../releases).
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Log in (interactive email + password, device remembered)
|
|
59
|
+
extendvcc login
|
|
60
|
+
|
|
61
|
+
# List parent cards
|
|
62
|
+
extendvcc accounts
|
|
63
|
+
|
|
64
|
+
# List virtual cards
|
|
65
|
+
extendvcc cards
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Enrolling a parent card is a three-step lifecycle: `extendvcc enroll ...` registers
|
|
69
|
+
the card and triggers an issuer verification email, you click the link in that email,
|
|
70
|
+
then `extendvcc activate <id>` pulls the card from PENDING to ACTIVE. Re-run `activate`
|
|
71
|
+
if it still reports PENDING.
|
|
72
|
+
|
|
73
|
+
## Create a One-Time Card
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
extendvcc create \
|
|
77
|
+
--credit-card-id cc_xxx \
|
|
78
|
+
--name "My Card" \
|
|
79
|
+
--balance-cents 5000 \
|
|
80
|
+
--valid-to 2026-12-31
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Create a Recurring Card
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
extendvcc create \
|
|
87
|
+
--credit-card-id cc_xxx \
|
|
88
|
+
--name "Monthly" \
|
|
89
|
+
--balance-cents 10000 \
|
|
90
|
+
--period MONTHLY \
|
|
91
|
+
--by-month-day 1 \
|
|
92
|
+
--terminator NONE
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Reveal Credentials
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Show masked card number and CVC on stdout
|
|
99
|
+
extendvcc reveal <card-id>
|
|
100
|
+
|
|
101
|
+
# Write full credentials to a file with 0600 permissions (owner-only)
|
|
102
|
+
extendvcc reveal <card-id> --json-path creds.json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`--json-path` writes the full PAN, CVC, and expiry to a file. Without it, the card number is masked on stdout. `--json` is a separate global flag that controls JSON output format; it does not write a file.
|
|
106
|
+
|
|
107
|
+
## Dry Run
|
|
108
|
+
|
|
109
|
+
Destructive commands accept `--dry-run` to preview the exact operation without
|
|
110
|
+
touching the network or mutating anything:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
extendvcc create --credit-card-id cc_x --name "Test" --balance-cents 5000 --valid-to 2026-12-31 --dry-run
|
|
114
|
+
extendvcc bulk cards.csv --credit-card-id cc_x --dry-run
|
|
115
|
+
extendvcc cancel <card-id> --dry-run
|
|
116
|
+
extendvcc close <card-id> --dry-run
|
|
117
|
+
extendvcc update <card-id> --balance-cents 9000 --dry-run
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The would-be request body (or operation descriptor) is printed as JSON to **stdout**;
|
|
121
|
+
the human-readable plan goes to **stderr**. So `extendvcc create ... --dry-run > body.json`
|
|
122
|
+
captures just the JSON. `create`/`bulk` resolve the recipient locally (from `--recipient`,
|
|
123
|
+
else the saved session) and never call the API; the preview is labelled `approximate`
|
|
124
|
+
when the recipient falls back to a placeholder. `update --dry-run` performs only the
|
|
125
|
+
read-only GET needed to show the accurate merged PUT body, with no mutation.
|
|
126
|
+
|
|
127
|
+
## Exit Codes
|
|
128
|
+
|
|
129
|
+
The CLI uses stable exit codes so scripts and CI can branch on the outcome:
|
|
130
|
+
|
|
131
|
+
| Code | Name | Meaning |
|
|
132
|
+
|------|----------------|-----------------------------------------------------------|
|
|
133
|
+
| 0 | OK | Success. |
|
|
134
|
+
| 1 | ERROR | Generic failure (library error, or an aborted confirmation). |
|
|
135
|
+
| 2 | USAGE | Bad flags or CLI input validation (e.g. missing `--valid-to`). |
|
|
136
|
+
| 3 | AUTH_REQUIRED | Login, OTP, or a saved session is required or failed. |
|
|
137
|
+
| 4 | DISABLED | Kill switch tripped (account-risk); run `clear-disabled --manual`. |
|
|
138
|
+
| 5 | API_ERROR | Extend returned an error response. |
|
|
139
|
+
|
|
140
|
+
## Environment Variables
|
|
141
|
+
|
|
142
|
+
| Variable | Purpose |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `EXTENDVCC_EMAIL` | Extend account email (overrides interactive prompt) |
|
|
145
|
+
| `EXTENDVCC_PASSWORD` | Extend account password (overrides interactive prompt) |
|
|
146
|
+
| `EXTENDVCC_IMAP_USER` | IMAP email for automatic OTP retrieval |
|
|
147
|
+
| `EXTENDVCC_IMAP_PASSWORD` | IMAP app password |
|
|
148
|
+
| `EXTENDVCC_IMAP_HOST` | IMAP server (default: `imap.gmail.com`) |
|
|
149
|
+
| `EXTENDVCC_STATE_DIR` | Override session/state directory |
|
|
150
|
+
| `EXTENDVCC_LEDGER_PATH` | Override ledger file path |
|
|
151
|
+
| `EXTENDVCC_BRAND_ID` | Override Extend brand ID |
|
|
152
|
+
|
|
153
|
+
## Python API
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from extendvcc import list_cards, get_card, create_card, reveal_card
|
|
157
|
+
|
|
158
|
+
# List all virtual cards
|
|
159
|
+
cards = list_cards()
|
|
160
|
+
|
|
161
|
+
# Get a single card by ID
|
|
162
|
+
card = get_card("card_id_here")
|
|
163
|
+
|
|
164
|
+
# Reveal card credentials (PAN, CVC, expiry)
|
|
165
|
+
creds = reveal_card("card_id_here")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
See `extendvcc.__init__` for the full list of exported functions and models.
|
|
169
|
+
|
|
170
|
+
## Security Notes
|
|
171
|
+
|
|
172
|
+
- The ledger never stores PAN or CVC data.
|
|
173
|
+
- `reveal` saves credentials with `0600` file permissions.
|
|
174
|
+
- Session tokens are stored locally with restricted permissions.
|
|
175
|
+
- All HTTP uses Chrome TLS fingerprinting via `impit`.
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
extendvcc/__init__.py,sha256=ahjmpi5W7-veQdyqGlrZ73D8DC5TzGgzOd0-yGkxuDA,882
|
|
2
|
+
extendvcc/_exit_codes.py,sha256=V2JmXpLmxoSqk62luxxRs5CN1h8KX68xW_kMgT1dJZI,1040
|
|
3
|
+
extendvcc/_jsonl.py,sha256=Bp7MZKiWTFOTDE0HvAqF_-EXboA5MIy1i6t3CJ3oRGs,1245
|
|
4
|
+
extendvcc/_paths.py,sha256=5EdfpXP93i0L-wUv7W2sP0UCEXHq0xER6vBpmmn1-x4,855
|
|
5
|
+
extendvcc/auth.py,sha256=ZKJNmYREPPDm1d8l3a8Wwjof4DWwO0jj_SOhELiVd5A,31175
|
|
6
|
+
extendvcc/cards.py,sha256=UmP3uX12en0qF9MrzfQ_dsq31pXCUJZZYfe430oyDkY,28503
|
|
7
|
+
extendvcc/cli.py,sha256=KurtPKvp3hr-a6plGQ0fzAWkJ_qN-4mn_YoEYuC78FU,32704
|
|
8
|
+
extendvcc/client.py,sha256=SnQPKOMystuxTwSDyQgbtDSP7XQ5NffqC2D660-mlyU,16044
|
|
9
|
+
extendvcc/imap_otp.py,sha256=i6ZpVRMEYug-nXpvOaVBx5ZKBVwWKAPrGwW7n74rUk8,5681
|
|
10
|
+
extendvcc/ledger.py,sha256=IAIQSkfZ8WUrb0Fa1uKanZEAob4aYQe_Ffb59F7sxz0,17504
|
|
11
|
+
extendvcc/models.py,sha256=8vj-fgbvRqSkVA5MvgFtpjrPZGhrzda6ej1UETJUaaY,2010
|
|
12
|
+
extendvcc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
extendvcc_cli-0.1.0.dist-info/METADATA,sha256=QpdsmspPcLjG9p4HhGmPHusM8hhiUOvjRY6mr9PkEIw,6319
|
|
14
|
+
extendvcc_cli-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
15
|
+
extendvcc_cli-0.1.0.dist-info/entry_points.txt,sha256=59idMYPsOCAeiK5DchQfQsB7ZCVl_3zu4CLVK2Remi0,49
|
|
16
|
+
extendvcc_cli-0.1.0.dist-info/licenses/LICENSE,sha256=-vYwHs0375p9zy6wORoz-KfSRPpQnParuWoLNe0SB_M,1079
|
|
17
|
+
extendvcc_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 extendvcc 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.
|