22
33import logging
44from collections .abc import Callable
5- from dataclasses import dataclass , field
65from typing import Literal
76
87import httpx
2827STRIPE_TEST_TX_HASH_FAILED = "0x000000000000000000000000000000000000000000000000000000testfailed"
2928
3029
31- @dataclass
32- class SimulateCryptoDepositInput :
33- payment_intent_id : str
34- network : Literal ["tempo" , "base" , "solana" ]
35- stripe_secret_key : str
36- buyer_wallet : str | None = None
37- token_currency : str | None = None
38- transaction_hash : str | None = None
39- stripe_version : str | None = None
40- stripe_api_base : str = "https://api.stripe.com"
41- extra : dict [str , str ] = field (default_factory = dict )
42-
43-
44- async def simulate_crypto_deposit (input : SimulateCryptoDepositInput ) -> None :
30+ async def simulate_crypto_deposit (
31+ * ,
32+ payment_intent_id : str ,
33+ network : Literal ["tempo" , "base" , "solana" ],
34+ stripe_secret_key : str ,
35+ buyer_wallet : str | None = None ,
36+ token_currency : str | None = None ,
37+ transaction_hash : str | None = None ,
38+ stripe_version : str | None = None ,
39+ stripe_api_base : str = "https://api.stripe.com" ,
40+ extra : dict [str , str ] | None = None ,
41+ ) -> None :
4542 """Call Stripe's `test_helpers/payment_intents/{id}/simulate_crypto_deposit` endpoint."""
46- url = f"{ input . stripe_api_base } /v1/test_helpers/payment_intents/{ input . payment_intent_id } /simulate_crypto_deposit"
43+ url = f"{ stripe_api_base } /v1/test_helpers/payment_intents/{ payment_intent_id } /simulate_crypto_deposit"
4744 params : dict [str , str ] = {
48- "network" : input . network ,
49- "buyer_wallet" : input . buyer_wallet or DEFAULT_BUYER_WALLET .get (input . network , "" ),
45+ "network" : network ,
46+ "buyer_wallet" : buyer_wallet or DEFAULT_BUYER_WALLET .get (network , "" ),
5047 }
51- if input .token_currency :
52- params ["token_currency" ] = input .token_currency
53- if input .transaction_hash :
54- params ["transaction_hash" ] = input .transaction_hash
55- params .update (input .extra )
48+ if token_currency :
49+ params ["token_currency" ] = token_currency
50+ if transaction_hash :
51+ params ["transaction_hash" ] = transaction_hash
52+ if extra :
53+ params .update (extra )
5654 headers : dict [str , str ] = {
57- "Authorization" : f"Bearer { input . stripe_secret_key } " ,
55+ "Authorization" : f"Bearer { stripe_secret_key } " ,
5856 "Content-Type" : "application/x-www-form-urlencoded" ,
5957 }
60- if input . stripe_version :
61- headers ["Stripe-Version" ] = input . stripe_version
58+ if stripe_version :
59+ headers ["Stripe-Version" ] = stripe_version
6260 async with httpx .AsyncClient () as client :
6361 res = await client .post (url , headers = headers , content = "&" .join (f"{ k } ={ v } " for k , v in params .items ()))
6462 if res .status_code >= 300 :
6563 raise RuntimeError (f"Stripe simulate_crypto_deposit failed: { res .status_code } { res .text } " )
6664
6765
68- @dataclass
69- class SimulateDepositIfTestModeInput :
70- """Input for :func:`simulate_deposit_if_test_mode`."""
71-
72- get_payment_intent_id : Callable [[str ], str | None ]
73- deposit_address : str
74- network : Literal ["tempo" , "base" , "solana" ]
75- stripe_secret_key : str
76- buyer_wallet : str | None = None
77- token_currency : str = "usdc"
78- stripe_version : str | None = None
79-
80-
81- async def simulate_deposit_if_test_mode (input : SimulateDepositIfTestModeInput ) -> None :
66+ async def simulate_deposit_if_test_mode (
67+ * ,
68+ get_payment_intent_id : Callable [[str ], str | None ],
69+ deposit_address : str ,
70+ network : Literal ["tempo" , "base" , "solana" ],
71+ stripe_secret_key : str ,
72+ buyer_wallet : str | None = None ,
73+ token_currency : str = "usdc" , # noqa: S107 — literal default, not a secret
74+ stripe_version : str | None = None ,
75+ ) -> None :
8276 """Higher-level wrapper around :func:`simulate_crypto_deposit` for the testnet/dev path.
8377
8478 Bundles the three steps every Stripe-multichain merchant repeats:
@@ -94,34 +88,32 @@ async def simulate_deposit_if_test_mode(input: SimulateDepositIfTestModeInput) -
9488
9589 Use case is exclusively dev/testnet end-to-end — production servers (sk_live_) no-op.
9690 """
97- if not input . stripe_secret_key .startswith ("sk_test_" ):
91+ if not stripe_secret_key .startswith ("sk_test_" ):
9892 return
99- pi_id = input . get_payment_intent_id (input . deposit_address )
93+ pi_id = get_payment_intent_id (deposit_address )
10094 if not pi_id :
10195 logger .warning (
10296 "[stripe] Skipping deposit simulation — no PI cached for deposit address %s… (network=%s). "
10397 "The PI cache TTL may have expired between 402 emission and settlement." ,
104- input . deposit_address [:10 ],
105- input . network ,
98+ deposit_address [:10 ],
99+ network ,
106100 )
107101 return
108102 try :
109103 await simulate_crypto_deposit (
110- SimulateCryptoDepositInput (
111- payment_intent_id = pi_id ,
112- network = input .network ,
113- stripe_secret_key = input .stripe_secret_key ,
114- buyer_wallet = input .buyer_wallet ,
115- token_currency = input .token_currency ,
116- transaction_hash = STRIPE_TEST_TX_HASH_SUCCESS ,
117- stripe_version = input .stripe_version ,
118- )
104+ payment_intent_id = pi_id ,
105+ network = network ,
106+ stripe_secret_key = stripe_secret_key ,
107+ buyer_wallet = buyer_wallet ,
108+ token_currency = token_currency ,
109+ transaction_hash = STRIPE_TEST_TX_HASH_SUCCESS ,
110+ stripe_version = stripe_version ,
119111 )
120- logger .warning ("[stripe] ✓ Simulated %s deposit for PI %s" , input . network , pi_id )
112+ logger .warning ("[stripe] ✓ Simulated %s deposit for PI %s" , network , pi_id )
121113 except Exception as err :
122114 logger .error (
123115 "[stripe] ✗ Failed to simulate %s deposit for PI %s: %s" ,
124- input . network ,
116+ network ,
125117 pi_id ,
126118 err ,
127119 )
0 commit comments