#Felix Cao
1 messages ยท Page 1 of 1 (latest)
Happy Dragon Boat Festival!
Hello ๐
Happy Dragon Boat Festival to you too! ๐
What code is throwing this error? Can you share more details?
const _ = require('lodash');
const stripeWithSK = require('stripe');
const { Gym, Member } = require('../../../../config');
const { stripeService } = require('../../../../services');
module.exports = async (req, res) => {
const { member_id } = req.params;
try {
if (!member_id) {
throw new Error('Missing required Fields')
}
const member = await Member.findByPk(member_id, {
attributes: ['id', 'stripe_customer_id'],
include: [
{
model: Gym,
attributes: ['stripe_secret_key']
}
]
});
if (!member.gym.stripe_secret_key) {
throw new Error('The gym cannot set up the API secret key from stripe')
}
const stripe = stripeWithSK(_.trim(member.gym.stripe_secret_key));
let stripe_customer_id = member.stripe_customer_id
if (!stripe_customer_id) {
const customer = await stripe.customers.create(
{
name: member.id
},
{
stripeAccount: 'acct_1NL0eJKg0o5Mtnux',
}
);
stripe_customer_id = customer.id;
}
await member.update({ stripe_customer_id });
const intent = await stripe.setupIntents.create(
{
customer: member.stripe_customer_id,
automatic_payment_methods: {enabled: true},
},
{
stripeAccount: 'acct_1NL0eJKg0o5Mtnux',
}
);
return res.status(200).json({ client_secret: intent.client_secret });
} catch (e) {
console.log(`\nAdd stripe payment method error: ${e.message}`);
return res.status(422).json({ message: e.message });
}
};
Can you share the client-secret too? Just want to double check something!
{
"customer_id": "cus_O7gcE7delmBvw3",
"client_secret": "seti_1NLRErKg0o5Mtnuxa6mFNSZq_secret_O7gc9Hn2vrr8OUuQT7NDNcZHucslQG9"
}
Ah okay, so if you look at the SetupIntent
It belongs to acct_1NL0eJKg0o5Mtnux
https://dashboard.stripe.com/test/logs/req_E6tdmUVe0bJ4DQ
But the request that failed, was made by acct_1H6HcFAgLJMWl621
https://dashboard.stripe.com/test/logs/req_MkShC46bTN7k8F
So you're likely missing Stripe-Account header somewhere (likely on the client-side)
https://stripe.com/docs/connect/authentication#adding-the-connected-account-id-to-a-client-side-application
What's the issue?
Wait for me
{
"id": "pi_3NLRihKg0o5Mtnux0HA1eoWR",
"object": "payment_intent",
"amount": 70,
"amount_capturable": 0,
"amount_details": {
"tip": {}
},
"amount_received": 0,
"application": "ca_HfcsRSuA5fBUWGLed5PN9fumPBNxjajJ",
"application_fee_amount": null,
"automatic_payment_methods": {
"allow_redirects": "always",
"enabled": true
},
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"charges": {
"object": "list",
"data": [],
"has_more": false,
"total_count": 0,
"url": "/v1/charges?payment_intent=pi_3NLRihKg0o5Mtnux0HA1eoWR"
},
"client_secret": "pi_3NLRihKg0o5Mtnux0HA1eoWR_secret_L77H5Tl56R1bBoxN8YLx6ZOkD",
"confirmation_method": "automatic",
"created": 1687356555,
"currency": "aud",
"customer": "cus_O7gcE7delmBvw3",
"description": null,
"invoice": null,
"last_payment_error": null,
"latest_charge": null,
"livemode": false,
"metadata": {},
"next_action": null,
"on_behalf_of": null,
"payment_method": "pm_1NLRXDKg0o5MtnuxgxqSXpRp",
"payment_method_options": {
"card": {
"installments": null,
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"processing": null,
"receipt_email": null,
"review": null,
"setup_future_usage": null,
"shipping": null,
"source": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "requires_confirmation",
"transfer_data": null,
"transfer_group": null
}
Why the status is requires_confirmation
https://dashboard.stripe.com/test/logs/req_qkQuZ4KETQ7lct
You're setting confirm: false when you create the PaymentIntent
I had collect the payment method, and confirmSetup on frontend
But I had set confirm: false in the above code
let paymentIntent = await stripe.paymentIntents.create(
{
amount,
currency: member.gym.currency_code,
automatic_payment_methods: { enabled: true },
customer: member.stripe_customer_id,
payment_method: member.stripe_payment_method_id,
confirm: false,
metadata: {
reference_number
}
},
{
stripeAccount: 'acct_1NL0eJKg0o5Mtnux',
}
);
Not sure I understand. You're setting confirm: false which is causing PaymentIntent to not auto-confirm. This is why it is in requires_confirmation status
So , change confirm: true?
yes
I think that setting confirm: true requires that you set a return URL. It is required in case you need to redirect for 3DS or a payment method that requires a full redirect
To be clear, 3DS can be performed without a redirect but I think we still require the URL unfortunately
๐ฅ
๐ฐ
I don't like this
Another question
I send amount: 70
But on the dashboard, it's 0.70
Yep, that is expected. Our APIs take amounts in cents for most currencies
So a 70$ AUD payment will require you to send 7000 as the amount
Right, the amount isn't in full AUD, it is AUD cents
We talk more about this in this doc. Basically a currency will always be represented in its smallest unit unless it is one of the currencies listed there https://stripe.com/docs/currencies#zero-decimal
So we need to send amount: 70 * 100
Correct