#dgsunesen-apple-pay
1 messages ยท Page 1 of 1 (latest)
Hey there! Couple things:
payment intent has expired
What is an expired Payment Intent?
Apple Pay is not stored on the user as a payment method
They can be saved on a customer, yep
So for some of our users if they initially did a payment intent maybe more than 7 days ago it would eventually expire, and when they want to do the actual payment (capture) then for those where they successfully did the payment intent with an already saved card, we can just retry/redo the thing and then we can capture and do the payment.. See screenshot for one that is expired
however, when a user chose to use Apple Pay, if the initial payment intent reaches expiration (like that specific one shown in the screenshot) we cannot retry/redo the thing (behind the scenes)... It seems like it's because the Apple Pay wasn't stored on the users as a payment intent rather like a "one time payment method"
So our app/services is a place where people put out tasks they want done, and then people can make offers on these tasks... However, the one that created the task might already days before the tasks is actually being done and completed already find the one to do the task and accept the offer.. Then when the task is actually done THEN do the actual payment.. But that can be like n days after the initial payment intent
So I guess we would somehow need to save the Apple Pay as a payment method on the user when they choose to pay that way so that we have the same capabilities of retrying if the payment intent expired, right? And I'm not sure if we can already save the Apple Pay as payment method on the user when we use presentApplePay.. I see it returns a paymentMethod so maybe we can save that on the user somehow?
Can you share an example PI where Apple Pay was attempted?
I'm curious to see how you're creating the PI as an Apple Pay payment method can be saved during auth/capture payment flows
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
this is in our test setup
here one went successfully through
Well that's a PI that's using a pre-existing PM object
Is there an example of a PI where you don't have an existing Payment Method?
Sure, ofc
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
this one.. I don't think there was any PM object there as the user does not have any credit card saved for future use.. The user only chose to use Apple Pay
and as you can see under the events and logs after it expired and the user wanted to do the payment/capture it just fails
So what we ended up doing was resetting this "task" and then the user could do a fresh and new payment intet and then pay the other user.. The new PI is this one: https://dashboard.stripe.com/payments/pi_3L0lbpIzTuemC0bB1UFWxrVn
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
Hmm, that was created with the payment_method parameter too: https://dashboard.stripe.com/logs/req_pBNfUcyii5zrnm
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
the one that failed / expired ?
Are you passing setup_future_usage on PI creation for any Apple Pay transactions?
Yep, for pi_3KxWpFIzTuemC0bB1o2bMwej
no, I don't think we do anything with setup_future_usage
not even with regular credit cards โ there it seems to just works if we retry it again after it might have expired
How are you setting up the cards for these off session payments?
using the CardField, useConfirmSetupIntent to save the card and then we use the setupIntents.create method to store the customerId and set usage to off_session
Yep, that flow won't work with Apple Pay
So that's how we store and save credit cards on the user for future use and that works.. So how do we do it with Apple Pay? ๐
do we need to use the setup_future_usage thing ?
Well, I'd recommend using the PaymentSheet instead of the CardField component for capturing payment details
(pretty sure you're using React Native, right?)
Yup
PaymentSheet will support Apple/Google Pay out of the box
So there is no way by using the presentApplePay that we can somehow store the information for later user (after e.g. expiration)
as we do it now for credit cards
Is this with a Setup Intent?
public async getSetupIntentClientSecret(customerId: string): Promise<string> {
return (
await stripe.setupIntents.create({
customer: customerId,
usage: 'off_session',
})
).client_secret;
}
And how do you confirm the Setup Intent with an Apple Pay PM?
oh, just a sec.. I think I misunderstood you
when the users accepts the user to do the task and pick apple pay, we do the PI like this
const paymentIntent = await stripe.paymentIntents.create({ amount, currency: 'dkk', customer: customerId, payment_method: paymentMethodId, metadata, // This parameter instructs Stripe to authorize the amount but not capture it capture_method: 'manual', // Indicate that the customer is not in your checkout flow during this payment attempt. // This causes the PaymentIntent to throw an error if authentication is required off_session: true, // Causes confirmation to occur immediately when the PaymentIntent is created confirm: true, // We're fulfilling the payment on behalf of the Doer, who will receive the money when captured on_behalf_of: doerStripeConnectedAccountId, transfer_data: { destination: doerStripeConnectedAccountId, }, });
and then once the capture is gonna happen we do it like so
paymentIntent = await stripe.paymentIntents.capture( task.stripePaymentIntentId, { // Round amount value because it always ends to .00000000001 amount_to_capture: Math.round( task.price * (1 + task.shouterFeePercentage), ), // Add the Shouter fee on top of the base price application_fee_amount: task.fee, }, );
is this what you're asking about? ๐
Right, but before you create the off-session payment you're creating/saving the payment method
How are you doing this for Apple Pay payment methods?
and that's the thing... We do not save the payment method on the user object (customer)... And that's why (I think) we are not able to retry, right?... I'm confused ๐
when it's for Apple Pay ๐
Yes, exactly! For an off-session payment you need a saved/authenticated PM
and that's not possible with Apple Pay ? ๐
or how should I understand this?
unless we use the PaymentSheet?
Yep, it's possible with Apple Pay (which is why I was asking if/how you were using Setup Intents for Apple Pay PMs)
public async createAndGetPaymentIntent(
customerId: string,
paymentMethodId: string,
amount: number,
doerStripeConnectedAccountId: string,
metadata?: { [metaKey: string]: string },
): Promise<PaymentIntentResponse> {
try {
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: 'dkk',
customer: customerId,
payment_method: paymentMethodId,
metadata,
// This parameter instructs Stripe to authorize the amount but not capture it
capture_method: 'manual',
// Indicate that the customer is not in your checkout flow during this payment attempt.
// This causes the PaymentIntent to throw an error if authentication is required
off_session: true,
// Causes confirmation to occur immediately when the PaymentIntent is created
confirm: true,
// We're fulfilling the payment on behalf of the Doer, who will receive the money when captured
on_behalf_of: doerStripeConnectedAccountId,
transfer_data: {
destination: doerStripeConnectedAccountId,
},
});
return {
clientSecret: paymentIntent.client_secret,
paymentIntentId: paymentIntent.id,
paymentIntentStatus: paymentIntent.status,
};
} catch (error) {
return {
// Error code will be `authentication_required` if authentication is needed
errorCode: error?.code,
clientSecret: error?.raw?.payment_intent?.client_secret,
paymentIntentId: error?.raw?.payment_intent?.id,
paymentIntentStatus: error?.raw?.payment_intent?.status,
};
}
}
Thats how we do it
And the same way we do it for credit cards
Hi ๐ jumping in as my teammate needed to step away, please bear with me a moment while I catch up on the context here.
Wallet payment methods, such as Apple Pay, are essentially the same as card payment methods. So they can be saved for future usage, and to do so you would either leverage a Setup Intent (if saving prior to payment) or a Payment Intent with setup_future_usage (if saving during a payment).