Skip to content

Commit 9433c5b

Browse files
mirek26stainless-app[bot]
authored andcommitted
fix(api): fix webhook parsing logic
1 parent de45c08 commit 9433c5b

File tree

63 files changed

+701
-3107
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+701
-3107
lines changed

README.md

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -200,27 +200,47 @@ card = client.cards.create(
200200
)
201201
```
202202

203-
## Webhook Verification
203+
## Webhooks
204204

205-
We provide helper methods for verifying that a webhook request came from Lithic, and not a malicious third party.
205+
Lithic uses webhooks to notify your application when events happen. The library provides signature verification via the optional `standardwebhooks` package.
206206

207-
You can use `lithic.webhooks.verify_signature(body: string, headers, secret?) -> None` or `lithic.webhooks.unwrap(body: string, headers, secret?) -> Payload`,
208-
both of which will raise an error if the signature is invalid.
207+
### Parsing and verifying webhooks
209208

210-
Note that the "body" parameter must be the raw JSON string sent from the server (do not parse it first).
211-
The `.unwrap()` method can parse this JSON for you into a `Payload` object.
209+
```py
210+
from lithic.types import CardCreatedWebhookEvent
211+
212+
# Verifies signature and returns typed event
213+
event = client.webhooks.parse(
214+
request.body, # raw request body as string
215+
headers=request.headers,
216+
secret=os.environ["LITHIC_WEBHOOK_SECRET"] # optional, reads from env by default
217+
)
218+
219+
# Use isinstance to narrow the type
220+
if isinstance(event, CardCreatedWebhookEvent):
221+
print(f"Card created: {event.card_token}")
222+
```
223+
224+
### Parsing without verification
225+
226+
```py
227+
# Parse only - skips signature verification (not recommended for production)
228+
event = client.webhooks.parse_unsafe(request.body)
229+
```
212230

213-
For example, in [FastAPI](https://fastapi.tiangolo.com/):
231+
### Verifying signatures only
214232

215233
```py
216-
@app.post('/my-webhook-handler')
217-
async def handler(request: Request):
218-
body = await request.body()
219-
secret = os.environ['LITHIC_WEBHOOK_SECRET'] # env var used by default; explicit here.
220-
payload = client.webhooks.unwrap(body, request.headers, secret)
221-
print(payload)
222-
223-
return {'ok': True}
234+
# Verify signature without parsing (raises exception if invalid)
235+
client.webhooks.verify_signature(request.body, headers=request.headers, secret=secret)
236+
```
237+
238+
### Installing standardwebhooks (optional)
239+
240+
To use signature verification, install the webhooks extra:
241+
242+
```sh
243+
pip install lithic[webhooks]
224244
```
225245

226246
## Handling errors

api.md

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ Methods:
522522

523523
- <code>client.webhooks.<a href="./src/lithic/resources/webhooks.py">unwrap</a>(\*args) -> object</code>
524524
- <code>client.webhooks.<a href="./src/lithic/resources/webhooks.py">verify_signature</a>(\*args) -> None</code>
525+
- <code>client.webhooks.<a href="./src/lithic/resources/webhooks.py">parse</a>(body, headers, secret) -> ParsedWebhookEvent</code>
526+
- <code>client.webhooks.<a href="./src/lithic/resources/webhooks.py">parse_unsafe</a>(body) -> ParsedWebhookEvent</code>
525527

526528
# ExternalBankAccounts
527529

@@ -881,61 +883,6 @@ from lithic.types import (
881883
TokenizationUpdatedWebhookEvent,
882884
DisputeTransactionCreatedWebhookEvent,
883885
DisputeTransactionUpdatedWebhookEvent,
884-
AccountHolderCreatedWebhookEvent,
885-
AccountHolderUpdatedWebhookEvent,
886-
AccountHolderVerificationWebhookEvent,
887-
AccountHolderDocumentUpdatedWebhookEvent,
888-
AsaRequestWebhookEvent,
889-
TokenizationDecisioningRequestWebhookEvent,
890-
AuthRulesBacktestReportCreatedWebhookEvent,
891-
BalanceUpdatedWebhookEvent,
892-
BookTransferTransactionCreatedWebhookEvent,
893-
BookTransferTransactionUpdatedWebhookEvent,
894-
CardCreatedWebhookEvent,
895-
CardConvertedWebhookEvent,
896-
CardRenewedWebhookEvent,
897-
CardReissuedWebhookEvent,
898-
CardShippedWebhookEvent,
899-
CardTransactionUpdatedWebhookEvent,
900-
CardTransactionEnhancedDataCreatedWebhookEvent,
901-
CardTransactionEnhancedDataUpdatedWebhookEvent,
902-
DigitalWalletTokenizationApprovalRequestWebhookEvent,
903-
DigitalWalletTokenizationResultWebhookEvent,
904-
DigitalWalletTokenizationTwoFactorAuthenticationCodeWebhookEvent,
905-
DigitalWalletTokenizationTwoFactorAuthenticationCodeSentWebhookEvent,
906-
DigitalWalletTokenizationUpdatedWebhookEvent,
907-
DisputeUpdatedWebhookEvent,
908-
DisputeEvidenceUploadFailedWebhookEvent,
909-
ExternalBankAccountCreatedWebhookEvent,
910-
ExternalBankAccountUpdatedWebhookEvent,
911-
ExternalPaymentCreatedWebhookEvent,
912-
ExternalPaymentUpdatedWebhookEvent,
913-
FinancialAccountCreatedWebhookEvent,
914-
FinancialAccountUpdatedWebhookEvent,
915-
FundingEventCreatedWebhookEvent,
916-
LoanTapeCreatedWebhookEvent,
917-
LoanTapeUpdatedWebhookEvent,
918-
ManagementOperationCreatedWebhookEvent,
919-
ManagementOperationUpdatedWebhookEvent,
920-
InternalTransactionCreatedWebhookEvent,
921-
InternalTransactionUpdatedWebhookEvent,
922-
NetworkTotalCreatedWebhookEvent,
923-
NetworkTotalUpdatedWebhookEvent,
924-
PaymentTransactionCreatedWebhookEvent,
925-
PaymentTransactionUpdatedWebhookEvent,
926-
SettlementReportUpdatedWebhookEvent,
927-
StatementsCreatedWebhookEvent,
928-
ThreeDSAuthenticationCreatedWebhookEvent,
929-
ThreeDSAuthenticationUpdatedWebhookEvent,
930-
ThreeDSAuthenticationChallengeWebhookEvent,
931-
TokenizationApprovalRequestWebhookEvent,
932-
TokenizationResultWebhookEvent,
933-
TokenizationTwoFactorAuthenticationCodeWebhookEvent,
934-
TokenizationTwoFactorAuthenticationCodeSentWebhookEvent,
935-
TokenizationUpdatedWebhookEvent,
936-
DisputeTransactionCreatedWebhookEvent,
937-
DisputeTransactionUpdatedWebhookEvent,
938-
UnwrapTypedWebhookEvent,
939-
UnwrapUnsafeWebhookEvent,
886+
ParsedWebhookEvent,
940887
)
941888
```

0 commit comments

Comments
 (0)