#jhonsalazar1623_api
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! We typically respond in a few minutes, but in some cases we might need a bit more time (e.g., server's busy, you've got a complex question, etc.).
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1254952655751745557
๐ Have more to share? Add details, code, screenshots, videos, etc. below.
Hello! My problem is when attempt confirm
const {error} = await confirmIntent({
elements,
clientSecret: secret,
confirmParams: {
return_url: ${window.location.origin}/checkout/success?secret=${secret}&transactionId=${transactionId},
},
redirect: 'always'
});
Hi, the issue here is that you're mixing using automatic_payment_methods and also manually passing ythe payment method types. You would want to make sure that you stay consistent
where is the option automatic_payment_methods , in the backend?
my code the backend is
InvoiceCreateParams.builder()
.setCustomer(customerId)
.putMetadata("customerId", String.valueOf(customerExternalId))
.setAutomaticTax(InvoiceCreateParams.AutomaticTax.builder().setEnabled(true).build())
.putMetadata("sellerId", sellerId.toString())
.putMetadata("subscriptionId", String.valueOf(subscriptionId))
.setPaymentSettings(
InvoiceCreateParams.PaymentSettings.builder()
.setPaymentMethodTypes(
Collections.singletonList(InvoiceCreateParams.PaymentSettings.PaymentMethodType.CARD))
.build()
)
.setApplicationFeeAmount(
(total * Long.parseLong(this.fee) )
)
.setTransferData(
InvoiceCreateParams.TransferData.builder()
.setDestination(sellerStripeId)
.build()
)
.build();
Invoice invoice = this.subscriptionExternalService.createInvoice(params);
InvoiceItem.create( InvoiceItemCreateParams.builder()
.setCustomer(customerId)
.setPrice(priceId)
.setInvoice(invoiceId)
.build());
Invoice resource = Invoice.retrieve(invoice.getId());
InvoiceFinalizeInvoiceParams paymentIntent =
InvoiceFinalizeInvoiceParams.builder().addExpand("payment_intent").build();
Invoice invoiceFinalized = resource.finalizeInvoice(paymentIntent);
clientSecret = invoiceFinalized.getPaymentIntentObject().getClientSecret();
Ah sorry, you are using Billing. Let me further review this
That is expected.
I'm still looking at your integration flow
my code is based from here https://docs.stripe.com/invoicing/integration?method=elements&lang=java#accept-invoice-payme
So you can pass the payment method types when you create the invoice: https://docs.stripe.com/api/invoices/create#create_invoice-payment_settings-payment_method_types. Then, when you create the Elements, https://docs.stripe.com/js/elements_object/create_without_intent#stripe_elements_no_intent-options-paymentMethodTypes you need to pass in the same payment method types. Can you attempt this?
When you create this Stripe Elements, can you pass the card payment method type, https://docs.stripe.com/js/elements_object/create_without_intent#stripe_elements_no_intent-options-paymentMethodTypes and try again?
in my backend I'm using setPaymentMethodTypes
When you create the Elements on the Client Side, can you add the payment method types, https://docs.stripe.com/payments/accept-a-payment-deferred?platform=web&type=payment#additional-options of card?
Yes, and you're using Stripe Elements, https://docs.stripe.com/invoicing/integration?method=elements&lang=java#set-up-stripe-elements to collect the payment details right?
yeah
When you create the Elements, you want to add the card payment method types.
ok,
Is that your client side code?
yes
if so, yes
I'm trying right now
same error
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
my secret from invoice from payment intent:
pi_3PVOCkGCjaP6mkX50CPXuNR8_secret_Nc4HZix2g2BTcE8GkaLX1tTiE
Still looking here
when use payment intent works succefully with stripe element but when I use invoice with payment intent doesn't work the confirmPayment method
I suspect it is because we're looking at the payment method types on the invoice settings, https://dashboard.stripe.com/settings/billing/invoice.
So am I.. I'm almost done testing this, hang tight
So that flow worked for me.
Can you share your Elements creation code?
I know you shared your confirm function wiht me earlier but I'm looking for your code when you created the Elements
of course
`const stripePromise = loadStripe("key here...")'
const options: any = {
mode: 'payment',
amount: 1000,
currency: 'usd'
};
<Elements stripe={stripePromise} options={options} >
<Payment order={order} tabsRef={tabsRef} stripePromise={stripePromise} />
</Elements>
payment is a component:
const transactionResult = await generateTransactionInfo(transaction)
console.log("transactionResult", JSON.stringify(transactionResult));
const {transactionId, secret} = transactionResult.data;
const confirmIntent: any | undefined = stripe?.confirmPayment;
const {error} = await confirmIntent({
elements,
clientSecret: secret,
confirmParams: {
return_url: 'url here'
},
redirect: 'always'
});
const options = {
paymentMethodOrder: ['card'],
paymentMethodTypes: ['card']
}
<PaymentElement options={options} onChange={(value: any) => {
setDisabledBtn(!value.complete)
}} onLoaderStart={() => setDisabledBtn(true)}/>
< Button type='submit' disabled={!Boolean(stripe) || disabledBtn} loader={loading.showing}
onClick={doPayment}
className="w-full text-2xl bg-customGreen !py-4 text-white justify-center disabled:!bg-gray-300 disabled:cursor-not-allowed">Pagar</Button>
`
the subscription and payment intent works correctly
Just passing paymentMethodTypes: ['card'], worked for me
and if I take that away, I get the same error as you
When you use the newer API version, 2024-04-10 we deafult the payment method to be automatic. So you need to specific the payment method types explicitly. If you pass explicity payment method types on https://docs.stripe.com/api/invoices/create#create_invoice-payment_settings-payment_method_types you need to specify those on the Elements.
Otherwise, since the payment method types are coming from the invoice settings, it looks like it's breaking as the Stripe Elements defaults to automatic payment methods
Your current integration is using our defer flow, https://docs.stripe.com/payments/accept-a-payment-deferred where you can collect payment details before you have the client secret from the payment intent.
but, I need to use invoice
It can't be that I am the only person in the world who cannot integrate invoice with the stripe documentation, am I the only one?
you can still use Invoices, but just need to change the client side code
Is there an issue with this documentation https://docs.stripe.com/invoicing/integration?method=elements&lang=java#accept-invoice-payment?
I am using exactly the same code, the difference is that I use react, with subscriptions and paymen intent it works without problems, with invoice it does not work
paymentMethodTypes no found
It looks like you're rending the PaymentElement before you create the invoice. If you instead create the invoice/ finalize then, create teh PaymentElement it should work
I tested this both ways on my test code
in my backend code is what exactly I'm doing ๐ฆ
I'm using dependency in my backend:
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>24.13.0</version>
</dependency>
where is the version api?
here?
What happens if you use the 2023-08-16 on the client side, https://docs.stripe.com/libraries/set-version#typescript-usage?
It shows it in the example above:
import Stripe from 'stripe';
const stripe = new Stripe('pk_test_51***', {
apiVersion: '2023-08-16'
});
im using react...
oohh, that is right
so?
I don't understand what I have to do, I've had the same error for weeks and I can't move forward with the development
Can you try adding it in the const stripePromise = loadStripe("key here...", {
apiVersion: '2023-08-16'
})' ?
Yeah, what you're trying to do is not supported with the defer intent flow sadly
good!
I also confirm this with a teammate
same error
"Payment details were collected through Stripe Elements using automatic payment methods and cannot be confirmed with a Payment Intent configured with payment_method_types."
I also tested this end to end
I do not think so, can you share the pi_ if with me?
"pi_3PVPZwGCjaP6mkX51mNrb645"
request_log_url: "https://dashboard.stripe.com/test/logs/req_3cywkiFrRtQB8I?t=1719284277"
Let me get a teammat who has React expertise, hang tight.
From my investigation, it looks like you're loading the Elements before finalizing the invoice which is not supported. If you finalize the invoice, and the user the client_secret from the payment intent, it should work.
my code backend is
`Invoice resource = Invoice.retrieve(invoice.getId());
InvoiceFinalizeInvoiceParams paymentIntent =
InvoiceFinalizeInvoiceParams.builder().addExpand("payment_intent").build();
Invoice invoiceFinalized = resource.finalizeInvoice(paymentIntent);
clientSecret = invoiceFinalized.getPaymentIntentObject().getClientSecret();`
yes, but on the client-side, I do not see where you're fetching the client_secret from the server-side.
Potentially, since I do not have React expetise, it might be the issue.
Hang tight
uhmmm
but if I showed it to you...
const transactionResult = await `generateTransactionInfo(transaction) --> HERE return secret...
console.log("transactionResult", JSON.stringify(transactionResult));
const {transactionId, secret} = transactionResult.data;
const confirmIntent: any | undefined = stripe?.confirmPayment;
const {error} = await confirmIntent({
elements,
clientSecret: secret,
confirmParams: {
return_url: ``,
},
redirect: 'always'
});`
I'm getting help..
my integration with subscription works fine, also uses the same code
Hi @dark egret I'm taking over this thread. Give me a sec to catch up
ok, thanks!
Looks like you are using the deferred flow https://docs.stripe.com/payments/accept-a-payment-deferred?platform=web&type=subscription am I right?
Yes you are. I noticed you specify these params in the options
mode: 'payment',
amount: 1000,
currency: 'usd'
};```
yes but Im using invoice api in the backend
But you are using deferred flow in your frontend integration.
If this is not what you want to achieve, I'd suggest you remove this options from your frontend code
Yes, I tried with options and without options parameter.
I can try again
wait second
Sure, and share with me the PaymentIntent ID if you still encounter the problem.
same error:
"pi_3PVPpOGCjaP6mkX50XQ44r3Z_secret_yHJ1UDzo7ODjoIJFifNDwV7CG"
message:
"Payment details were collected through Stripe Elements using automatic payment methods and cannot be confirmed with a Payment Intent configured with payment_method_types."
Looks like you are still using the deferred flow
status: "requires_payment_method"
Can you share with me the latest frontend code?
in my payment component:
<PaymentElement onChange={(value: any) => {
setDisabledBtn(!value.complete)
}} onLoaderStart={() => setDisabledBtn(true)}/>
}
< Button type='submit' disabled={!Boolean(stripe) || disabledBtn} loader={loading.showing}
onClick={doPayment}
className="w-full text-2xl bg-customGreen !py-4 text-white justify-center disabled:!bg-gray-300 disabled:cursor-not-allowed">Pagar</Button>
Ok, I saw you removed options from Elements. Is your code saved successfully? Do you need to re-compile it?
Hmm, wait a second, It looks like you didn't pass clientSecret to Elements
IntegrationError: In order to create a payment element, you must pass a clientSecret or mode when creating the Elements group.
yes! ahahah
in my click button event
const transactionResult = await generateTransactionInfo(transaction)
console.log("transactionResult", JSON.stringify(transactionResult));
const {transactionId, secret} = transactionResult.data;
const confirmIntent: any | undefined = stripe?.confirmPayment;
const {error} = await confirmIntent({
elements,
clientSecret: secret,
confirmParams: {
return_url: $,
},
redirect: 'always'
});
I passed the secret...
No, if you are not using deferred flow, you should pass the clientSecret to the Elements
uhmmm
https://docs.stripe.com/payments/accept-a-payment?platform=web&ui=elements#add-and-configure-the-elements-provider-to-your-payment-page refer to the example code here
Great!
Is it the same for subscription integration?
since with the previous code the subscription works well
I think the example options is different...
Same. Check the integration guide here https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web&ui=elements
in this dcoumentation the options object is different
Yes, the doc that you shared is using the deferred flow.
The benefit of using deferred flow is that you can render the PaymentElement without a clientSecret. However, you need to ensure that the options that you specify in front end is consistent with the PaymentIntent that the invoice creates.