#sxe-confirmation-method
1 messages · Page 1 of 1 (latest)
What does client_secret do in Passing the client secret to the client side
?
Can client_Secret help me fetch payment_method?
@late wind I'm sorry but that question is really vague and indicates that you are not really understanding how PaymentIntents work at all (which is totally fine)!
Can you clarify what your real question is? What are you really trying to do?
I've read many docs in last days and maybe everything is a bit vague.
And because most of the codes are in JS which language I'm not very familialised with.
My question is, I'm creating an payment intent,
You should look at Checkout instead in that case: we do everything for you: https://stripe.com/docs/payments/checkout
And payment is being accepted by stripe and is being saved in my webhook.
My question is: Does that automaticaly create an payment method?
Well you need a PaymentMethod to accept a payment so yes. But it doesn't automatically saves the PaymentMethod for future payments. Is that what you meant?
Yes. If it creates the PaymentMethod, I'm trying to hold a payment, then capture it after checking few variables in php language.
I've added this line
'capture_method' => 'manual',
In my create intent.
Which is totally fine and logic thing to do, I assume.
But, then, when I'm done with checking php variables and I'm ready to capture the sum, I'm running this code:
$intent_id = $event->data->object->id;
$intent = \Stripe\PaymentIntent::retrieve($intent_id);
$intent->capture(['amount_to_capture' => $Price*100]);
``` in webhook.php
Did I do something wrong / missed some steps yet?
Hey @late wind, stepping in here for koopajah as they needed to step away.
Hi
The above looks fine. Are you seeing an error?
Yes.
Ah wait
You need to call https://stripe.com/docs/api/payment_intents/capture?lang=php to capture
here
No you are setting $intent to the retrieved PaymentIntent
What about the second line?
Why are you retrieving the PaymentIntent here? You already have the ID. Why not just capture?
Ok. I'm capturing it rigt now.
right*
(Request req_U9LaLIxtKgaNa4) This PaymentIntent could not be captured because it has a status of requires_payment_method. Only a PaymentIntent with one of the following statuses may be captured: requires_capture.
I'm still getting this error.
You have to confirm the PaymentIntent either with an already-created PaymentMethod server-side or with a newly created PaymentMethod client-side, in order to generate the authorization, before you can capture.
How can I check if there are any PM set ?
Let's back up
What exactly are you trying to do?
You want to build out a manual capture flow?
Is this a first time payment flow?
Are you just testing this at a high level?
I'm creating a payment session where I approve or I dissaprove if a payment should be charged or not.
Should be authorized or not.
This is the scenario:
- There are 10 stocks of umbrellas
- userA adds to his basket 10 umbrellas and goes to payment page. But, the umbrellas are still on stock, because no one bought them.
- UserB adds to his basket 1 umbrella and proceeds to payment page, and buys it. I make PHP variables to check if there are stocks on umbrella. I authorize the payment.
- There are 9 umbrellas left.
- UserA places his payment on 10 umbrellas. I make PHP variables if there are 10 umbrellas on stock, but there are not, so I refuse the payment.
Yes, is a first time payment and there won't be a recurring or subscription. It's just a normal payment with a confirmation before authorizing it.
Currently I'm testing it until I will launch it on live mode.
Okay thanks
So you basically want to build out the flow here: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements, which discusses confirmation of the PaymentIntent, and then you add an extra step for manual capture.
But you need to confirm the PaymentIntent client-side using Stripe.js in order to actually create the authorization before you can capture
Otherwise you will hit the error above
Just for context,
I'm using the source-code offered by Stripe on accept-a-payment
Yes, the one you sent me.
const paymentElement = elements.create("payment");
paymentElement.mount("#payment-element");
}
``` as I can see, I'm creating Payment element on my client-side.
$stripe->paymentIntents->confirm(
'pi_3Ku9WhLKPu9R0yzS01OT3HoM',
['payment_method' => 'pm_card_visa']
);
This is the way I must confirm a payment_method
Should payment_method be always pm_card_vise ?
visa*
So what you are doing above is confirming on your server
This is okay for testing, though you can just confirm when creating the PaymentIntent, but wouldn't be the actual flow with a customer.
For testing you can just confirm when creating the PI here: https://stripe.com/docs/api/payment_intents/create#create_payment_intent-confirm
And us pm_card_visa as the PaymentMethod as you are doing above
I did not understand that, unfortunatelly.
When you actually create your flow, you have to collect card details from your customer
You do this via the Payment Element and Stripe.JS
When you call stripe.confirmPayment with Stripe.JS that will create the PaymentMethod
async function initialize() {
const { clientSecret } = await fetch("create.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ items }),
}).then((r) => r.json());
elements = stripe.elements({ clientSecret });
const paymentElement = elements.create("payment");
paymentElement.mount("#payment-element");
}
This?
Yep
I have this.
Okay and so you need a "Pay" button as well
And when it is clicked you call stripe.confirmPayment
Okay so without manual capture can you successfully create a charge with this flow?
Okay so then you need to use the above with setting manual capture on a PaymentIntent that you are using with the above flow
The original one you showed me did not go through the flow of being confirmed
The above, which one?
The one related to req_U9LaLIxtKgaNa4
Yes.
The req_U9LaLIxtKgaNa4 is set on manual.
Sorry if there are some language barrier between us.
Correct, that PaymentIntent was created with manual capture but the client_secret was not passed client-side and then used to confirm that PaymentIntent
You need to use the flow discussed above with PaymentElement, and set the PaymentIntent created in that flow to capture_method: manual
Then after the PaymentIntent has been confirmed client-side, you can capture it.
is create.php client-side or a server-side ?
because as I can see, client_Secret is being submitted to client-side (index.php) with this piece of codeȘ
:
$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => $Price,
'currency' => 'ron',
'payment_method_types' => ['card'],
'capture_method' => 'manual',
'metadata' => [
....metadatalist
]
]);
$output = [
'clientSecret' => $paymentIntent->client_secret,
'id' => $paymentIntent->id,
];
echo json_encode($output);
The above snippet is from your server
And looks to be sending the client_secret to your client
I'd recommend adding logging on both your server and client files to ensure the client_secret matches
Then you will know that you are using the correct one if you are confused by your set up
Yep, then you can capture
Assuming the PaymentIntent you are confirming was created with capture_method: manual
$stripe->paymentIntents->confirm(
$output['id'],
['payment_method' => 'pm_card_visa']
);
with what should i modify the 'pm_card_visa' ?
There's the part where I do not understand.
lol you don't confirm there. You confirm using Stripe.JS: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#web-submit-payment
Use stripe.confirmPayment to complete the payment using details from the Payment Element.
oh lmao i'm dumb
But I'm confirming it already.
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: "https://campionatlol.ro/Cos/Plata/Finalizat",
},
});
Great! Then all you need to do is set capture_method: manual when you create the PaymentIntent.
But I've set it.
And I'm still getting that error I've mentioned earlier,
this >
Uncaught (Status 400) (Request req_Bck9PMLnuo2gQZ) This PaymentIntent could not be captured because it has a status of requires_payment_method. Only a PaymentIntent with one of the following statuses may be captured: requires_capture.
We are going in circles :). The PaymentIntent for the error you mentioned earlier was never confirmed
But why am I getting that error and how could I fix it?
Sorry for dumb questions.
But I can't see it.
pi_3KvluMLKPu9R0yzS1bGCtPEi => was succesfully paid as I can see.
@late wind I'm hopping in since bismark has to head out - give me a bit to catch up
sure, hi
FYI, i'm a bit thickhead and I can't process the infos right-away / don't understand them from first explication.
When we talk about js specially.
Do you want to give a quick rundown of what the current state of your question is?
I'll explain what I'm trying to do,
And what errors I'm getting, and when I'm getting them.
I desire to allow a payment to be authorized only if I allow it.
if not => cancel it.
So, I've added this line in my intent:create
'capture_method' => 'manual',
and, in my webhook, I've added this:
$intent_id = $event->data->object->id;
if($Succes == 1 AND $Succes2 == 1 AND $Succes3 == 1 AND $Succes4 == 1 AND $Succes5 == 1)
{
$stripe->paymentIntents->capture(
$intent_id,
[]
);
}
if($Succes == 0 OR $Succes2 == 0 OR $Succes3 == 0 OR $Succes4 == 0 OR $Succes5 == 0)
{
$stripe->paymentIntents->cancel($intent_id, []);
}
if ($event->type == 'payment_intent.payment_failed')
{
mysqli query to insert failed payment
}
if ($event->type == 'payment_intent.succeeded')
{
mysqli query to insert success payment
}```
But, when I enter on the index.php, the page where I put the card infos, I'm getting this error:
What events are your webhook listener currently listening for?
let me check
payment_intent.succeeded
payment_intent.amount_capturable_updated
payment_intent.canceled
payment_intent.created
Whenever I enter on the index.php, the page where I put my card infos, I'm getting this error =>
This PaymentIntent could not be captured because it has a status of requires_payment_method. Only a PaymentIntent with one of the following statuses may be captured: requires_capture.
Even if I'm submitting the payment or not, when I access the page, I'm automatically getting this error.
If I submit the payment, and payment is OK, it's being set and is registered and It appears confirmed on stripe dashboard.
And what is this line of code doing?
if($Succes == 1 AND $Succes2 == 1 AND $Succes3 == 1 AND $Succes4 == 1 AND $Succes5 == 1)
There are mysql queries, which checks if the payment should be authorized.
As in
$stmt = $con->prepare("SELECT .......... WHERE ID = ?");
$stmt->bind_param("i", $UserIDMetadata);
$stmt->execute();
$results = array();
$results = $stmt->get_result();
foreach($results as $row) {
if($row['Stoc'] < $row['Cantitate']) { $Succes = 0;}
if($row['Stoc'] >= $row['Cantitate']) { $Succes = 1;}
}
Basically it checks if there are stocks or not for the desired item.
There are 5 checkpoints.
If every checkpoint is equal to 1, the payment should be authorized.
If one of them is 0, payment won't be authorized, and will be cancelled.
Gotcha - so the issue with this code is that you're running the capture code for ALL the event types. You should only be running the capture code for payment_intent.amount_capturable_updated
why _updated ?
Because that event is specifically triggered when the Payment Intent is ready to be captured - the other events, like payment_intent.created are triggered at different points when the Payment Intent hasn't even been confirmed yet
👍 awesome!