#mfwgenerics
1 messages · Page 1 of 1 (latest)
Hi 👋 can you tell me more about your use case that requires you create an off-session payment and not immediately confirm it, that sounds a bit unusual?
I agree, it is a bit unusual. it's a "place order" button that charges the user immediately using saved payment details. the payment is not truly offline since the user must be told at this point whether the charge has succeeded or failed. currently there is an issue with our system where the Stripe charge can be created without the corresponding order being entered into our database (for example if the transaction fails due to high contention - which does happen)
currently the only way I can think to solve this in a way that is acceptable to the client involves creating a charge first, saving its ID as "pending", then confirming it. but this is not supported for off_session usage
to be clear: I understand this is fundamentally the wrong way to handle checkout flows with Stripe. I inherited the design and do not have the option of fixing it at this stage
Two things:
-
If it's a single button click to make the payment, then that sounds like a single request to create and confirm the payment is the right path. Are you thinking of separating the authorization and capture steps (rather than separating creation and confirmation)
https://stripe.com/docs/payments/place-a-hold-on-a-payment-method -
If the customer is on session, then setting
off_sessiontofalsedoes sound like the better fit.
re: 2. are there any downsides to setting off_session: false here? for example, could a payment end up requiring extra manual steps from the user that wouldn't have otherwise been required?
The payment could require additional verification regardless of how that is set, it is ultimately up to the issuing bank to decide if authentication is required for any payment. We request exemptions but the issuing bank decides whether to grant them.
I don't think separating authorization/capture distinction is what I need here. the 2 step create + confirm I need here is purely for resilience in the face of transient DB outages/unavailability we face. 99% of the time charges would be confirmed immediately after they are created
I know idempotency keys can provide resilience for offline payment processing. but in this case, I don't want to idempotently retry the payment in a recovery situation. I just want to check if the payment was originally successful - if that makes sense
Our idemptotency doesn't retry for payment success, it retries for request completion purposes. Idempotent requests will provide the same response as the original request they're replaying, so if the payment failed the idempotent request will contain that failure.
Sorry, I'm still not really grasping what you're trying to solve for by separating the creation and confirmation pieces. Typically they're separated for flows where you create the Intent server-side and then confirm the Intent client-side when the customer provides payment method details, but for off session payments where everything is handled server-side there isn't a need to separate those so we don't offer that.
thanks for your patience here. I'll try to explain the situation a bit more. at the moment, our "place order" endpoint does the following:
- creates an offline charge against the user's card
- saves an entry into the database saying "user placed an order"
if a problem occurs like a crash, network congestion, db contention or other outage, it can result in a situation where the user is charged without an order being placed and no clear way to recover. in a recovery situation I can't go back and check for "half finished" charges
what I'm hoping to do instead is something like the following:
- create an offline charge in an unconfirmed state
- save the charge id to a "pending orders" table
- confirm the charge
- save the "placed an order" entry
with this process I could look at my pending orders table in the event of a crash, then recover the status of the charge and complete the order
Won't that approach double the number of calls to your DB, and if that's the connection you're worried about breaking double the chances the flow won't complete?
It also doesn't seem like it would recover if Step 4 of the new flow is the part that fails. (edited, typed too fast)
that is true to an extent. but it transforms the system from an inconsistent one to an eventually consistent one
if step 4 fails, the record remaining in "pending orders" won't be cleared and we will still end up retrying it. step 4 can be done idempotently, so it's no problemo
Then this sounds more streamlined (but you know your system best, so please feel free to ignore if this doesn't make sense in your context, keeping in mind there is no way to separate the creation and confirmation steps for off-session payments).
- Create off-session Payment Intent, response includes indication of whether the payment was successful (assuming you're using payment methods with immediate notification)
- Save the ID of the Payment Intent in some payments_without_orders table
- Create the order entry and tie it to the previously created payment
but if step 2 experiences a transient failure there, we could end up with a charge that goes unrecorded, no? the thing that the 2 step flow enables is saving the method of identifying the payment before you create any "real world" effects
Good point, it does seem like a possibility.
But you can't separate the creation and confirmation of off-session Payment Intents, so they can't be used with the approach you're describing.
it is true. thanks for your time today. I think I will make a case to the client that we aren't using Stripe in its intended way. maybe I can get some extra budget to rework the whole checkout process