Python SDK package for invoq server APIs and webhook verification.
Project description
invoq Python SDK
Python SDK for invoq server APIs and webhook verification. Create stablecoin invoices from your backend and fulfill orders with signed webhooks.
Use this package only on your server. It accepts secret keys and must not be bundled into browser code.
Installation
python -m pip install invoq
Requires Python 3.9 or newer.
Get your keys
- Sign in to the invoq dashboard and create a project.
- On the API keys page, create a secret key. Test keys start with
sk_test_, live keys withsk_live_. - In your project's webhooks settings, save your webhook URL and store the
webhook secret (
whsec_...) for that mode.
Add both to your server environment:
INVOQ_SECRET_KEY=sk_test_...
INVOQ_WEBHOOK_SECRET=whsec_...
Start with test keys. Switch to the live key and live webhook secret when you go to production.
Create a client
import os
from invoq import Invoq
invoq = Invoq(os.environ["INVOQ_SECRET_KEY"])
Production API default:
https://api.invoq.money
Override the API origin and request timeout during development:
invoq = Invoq(
os.environ["INVOQ_SECRET_KEY"],
api_origin="http://localhost:8787",
timeout_ms=10_000,
)
api_origin must be an absolute http or https origin with no path, query,
hash, username, or password. The SDK appends /v1/... API paths. Requests time
out after 10 seconds by default (timeout_ms).
Invoices
Create an invoice:
invoice = invoq.invoices.create({
"amount": "149",
"currency": "USD",
"description": "SaaS boilerplate",
"reference_id": "order_1234",
"return_url": "https://merchant.example/thanks",
})
Notes:
- Use a server-side amount. Do not trust client-supplied amounts.
amountis a decimal USD string from"0.01"to"999.99"with up to 2 decimal places, such as"129"or"129.99".- Use
reference_idto mapinvoice.paidwebhooks back to your order. It also makes creation retry-safe: creating again with the samereference_idand the same invoice terms returns the existing invoice instead of a duplicate, while different terms fail with a409 reference_id_conflictAPI error. - Omit
return_urlto use the project's default return URL. PassNoneto send JSONnulland create the invoice without a return URL. Onreference_idretries, passreturn_urlexplicitly when you need to assert a specific value. descriptionandreference_idmust be strings when present.
Get an invoice:
invoice = invoq.invoices.get("inv_123")
invoices.get() returns the public invoice shape used by the hosted checkout
endpoint. It includes checkout-facing fields such as amount_paid,
amount_due, payment_status, project, deposit_address,
monitoring_ends_at, and direct_onchain_rails, but does not include
reference_id. Use the create response or the invoice.paid webhook when you
need your merchant reference_id.
Create a test payment:
paid_invoice = invoq.invoices.create_test_payment("inv_123", {
"amount": "149",
"reference_id": "test_payment_001",
})
create_test_payment only works on invoices created with a sk_test_ key. When
payments reach the invoice amount, the invoice becomes paid and invoq sends a
real signed invoice.paid webhook to your test webhook URL. Partial amounts are
allowed and produce partially_paid.
Amounts in responses are normalized to 4 decimal places: create with "129" and
the invoice returns amount: "129.0000". Compare amounts numerically, not as
strings. amount_due is derived as max(amount - amount_paid, 0) and uses the
same 18-decimal scale as amount_paid.
The SDK returns the response data object directly.
Hosted checkout page
Every invoice also has a hosted checkout page at:
https://pay.invoq.money/<invoice id>
Share the link or redirect to it when an in-page checkout modal is not a fit.
Webhooks
Pass the raw request body to verify_webhook. Do not parse JSON and re-dump it
before verification.
import os
from invoq import is_invoice_paid, verify_webhook
event = verify_webhook(
raw_body,
{"invoq-signature": signature_header},
os.environ["INVOQ_WEBHOOK_SECRET"],
)
if is_invoice_paid(event):
order_id = event["data"]["invoice"]["reference_id"]
if order_id is None:
raise ValueError("Missing invoice reference_id for fulfillment.")
fulfill_order(order_id)
Use invoice.paid webhooks to fulfill orders on your server. When
is_invoice_paid(event) is true, the invoice is ready for automatic
fulfillment; use the invoice reference_id to find and fulfill your order. The
helper accepts paid-equivalent invoice statuses (paid, settling, or
settled) and rejects review_required.
Important:
- Pass the raw request body as a string or bytes.
- Pass a header mapping with the
invoq-signatureheader. - Do not parse JSON and re-dump it before verification.
verify_webhookdoes not requireInvoq(...)or your invoq API secret key.- Use your webhook secret, not
INVOQ_SECRET_KEY. - Fulfill idempotently. Failed webhook deliveries are retried.
- Respond with a 2xx quickly. Other statuses count as failed deliveries.
Webhook verification failures raise InvoqSignatureVerificationError. The
signature header is:
invoq-signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
Errors
from invoq import InvoqApiError, InvoqError
try:
invoq.invoices.create({"amount": "0.001", "currency": "USD"})
except InvoqApiError as error:
print(error.status)
print(error.code)
print(error.fields)
except InvoqError:
raise
Non-2xx API responses raise InvoqApiError, which has status, code,
fields, meta, and the raw payload. Connection failures, timeouts, response
parse failures, and invalid SDK inputs raise InvoqError.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file invoq-0.1.0.tar.gz.
File metadata
- Download URL: invoq-0.1.0.tar.gz
- Upload date:
- Size: 17.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
018ac3a4d6f371a4a719d09493724c61988fd9b666771a957e04f64c0c52a37a
|
|
| MD5 |
baa20979450b469bbae37c6c007c77bf
|
|
| BLAKE2b-256 |
b2aaeb8411db9198989feacb6eda0863c71b2adf88c55a94de7ef74d737acc93
|
File details
Details for the file invoq-0.1.0-py3-none-any.whl.
File metadata
- Download URL: invoq-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
460dbc6c43f1efdbb45dcdf50fe24d33f4490300d5ccf53c2e196af3eaa9271b
|
|
| MD5 |
c23d7c1ae52d6d8861ea4047b8474d63
|
|
| BLAKE2b-256 |
521e4a78d728a5847d87591783116912b89332c45e860bc15f75026c9b3bbd9a
|