#kwac_code

1 messages ยท Page 1 of 1 (latest)

hard galeBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always 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/1328278298744193034

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.

vital cedar
#

I'm trying to get processed fees in stripe webhook.

console.log(charge); prints:

{ id: 'pi_3QgiplKPj3JfoYa7059wBusj',
  object: 'payment_intent',
  amount: 5700,
  amount_capturable: 0,
  amount_details: { tip: {} },
  amount_received: 5700,
  application: null,
  application_fee_amount: null,
  automatic_payment_methods: { allow_redirects: 'always', enabled: true },
  canceled_at: null,
  cancellation_reason: null,
  capture_method: 'automatic_async',
  client_secret: 'pi_3QgiplKPj3JfoYa7059wBusj_secret_xCwrDfrDi9ov6StRKvZSRnLr1',
  confirmation_method: 'automatic',
  created: 1736756237,
  currency: 'usd',
  customer: null,
  description: null,
  invoice: null,
  last_payment_error: null,
  latest_charge: 'ch_3QgiplKPj3JfoYa702CTYiX2',
  livemode: false,
  metadata: {},
  next_action: null,
  on_behalf_of: null,
  payment_method: 'pm_1QgipmKPj3JfoYa79XkEc7CG',
  payment_method_configuration_details: { id: 'pmc_1QNzjCKPj3JfoYa74Tk4JWzv', parent: null },
  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: 'succeeded',
  transfer_data: null,
  transfer_group: null }
#

Here is webhook code

import Stripe from 'stripe';

export default defineEventHandler(async (event) => {

    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
      apiVersion: '2023-08-16'
    })
    
    const headers = event.node.req.headers;
    const body = await readRawBody(event);
    const sig = headers["stripe-signature"];
    let hookEvent;
    
    const isDevMode = process.env.NODE_ENV === 'development';
    const endpoint_secret = isDevMode ? 'secret' : process.env.ENDPOINT_SECRET;

    try{
        hookEvent = stripe.webhooks.constructEvent(
            body,
            sig,
            endpoint_secret
        )
    }catch(error){
        throw createError({ status: 400, message: error })
    }

    switch(hookEvent.type){
        case "payment_intent.created":
            console.log("payment intent created");
            break;
        case "payment_intent.succeeded":
            const paymentIntent  = hookEvent.data.object;
            
            const paymentIntentId = paymentIntent.id; 
            const charge = await stripe.paymentIntents.retrieve(paymentIntentId, {
                expand: ['charges.data.balance_transaction'],
            });
            console.log(charge);

            break;
        case "charge.succeeded":
            break;     
        default: 
            console.log(`unhandled event type ${hookEvent.type}`)       
    }

})

gloomy pine
#

Hi there, so you want to programmatically obtain the stripe fee associated with a payment?

vital cedar
#

yes

gloomy pine
vital cedar
#

this will work in testing mode?

#

when using test cards

#

I mean

gloomy pine
#

yes you can test the same in test mode.

vital cedar
#

and fees will be displayed?

gloomy pine
#

Yes you are right

vital cedar
#

okay thank you

#

well okay that's weird, I followed this guide and the fee is displayed as null

gloomy pine
#

What's the paymentIntent ID?

vital cedar
#

pi_3QgjAgKPj3JfoYa715ccT5GQ

gloomy pine
#

I can see that this paymentInent has a processing fee for USD 0.46

vital cedar
#

i see that as well in dashboard

#

but my code displays null

#

for the fee

gloomy pine
#

Can you show me your code?

vital cedar
#
import Stripe from 'stripe';

export default defineEventHandler(async (event) => {

    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
      apiVersion: '2023-08-16'
    })
    
    const headers = event.node.req.headers;
    const body = await readRawBody(event);
    const sig = headers["stripe-signature"];
    let hookEvent;
    
    const isDevMode = process.env.NODE_ENV === 'development';
    const endpoint_secret = isDevMode ? 'whsec_693438147a85388c0b754f8391794f3e9908c5484e2827729cb91903c49ede13' : process.env.ENDPOINT_SECRET;

    try{
        hookEvent = stripe.webhooks.constructEvent(
            body,
            sig,
            endpoint_secret
        )
    }catch(error){
        throw createError({ status: 400, message: error })
    }

    switch(hookEvent.type){
        case "payment_intent.created":
            console.log("payment intent created");
            break;
        case "payment_intent.succeeded":
            const paymentIntent  = hookEvent.data.object;
            const paymentIntentId = paymentIntent.id; 

            const info = await stripe.paymentIntents.retrieve(
                paymentIntentId,
                {
                  expand: ['charges.data.balance_transaction'],
                }
            );

            const feeDetails = info.charges.data[0].balance_transaction.fee_details;

            console.log(feeDetails);
           

            break;
        case "charge.succeeded":
            break;     
        default: 
            console.log(`unhandled event type ${hookEvent.type}`)       
    }

})

gloomy pine
#

OK, the webhook event is rendered a newer API version, so you should use latest_charge instead of charges[0]

#
  'pi_1Gpl8kLHughnNhxyIb1RvRTu',
  {
    expand: ['latest_charge.balance_transaction'],
  }
);

const feeDetails = paymentIntent.latest_charge.balance_transaction.fee_details;```
#

Can you try the example code?

#

Can you do a console.log(info) ?

#

Looks like you didn't expand the balance_transaction

#

Do you include latest_charge.balance_transaction in the expand array?

vital cedar
gloomy pine
vital cedar
#

req_Jc7xNnxIgg4e0a

gloomy pine
#

I mean the request that you made to expand the PaymentIntent

vital cedar
#

this one?
req_KxS1f9nyS2yEcf

gloomy pine
#

No, this is still the paymentIntent creation request.

hard galeBOT
vital cedar
#

it's this section, right?

#

im confused

rotund zinc
#

hi! I'm taking over this thread.

#

you are doing a retrieve request, so you need to change your filter on that page to display GET requests (that are hidden by default)

vital cedar
#

req_lz1sEKtDByoIhr

rotund zinc
#

that request was successful. so what's the issue exactly?

#

can you console.log the paymentIntent variable?

vital cedar
#

as you can see from here

   application_fee: null,
   application_fee_amount: null,
rotund zinc
#

this has nothing to do with Stripe fees, this is related to Stripe Connect, which I don't think you are using.

vital cedar
#

so how do I get the fee if i'm not using stripe connect?

rotund zinc
#

it should be in balance_transaction, however here it's null

vital cedar
#

what should i do?

rotund zinc
vital cedar
rotund zinc
vital cedar
#

I did

#

you can even see it from logs

vital cedar
#

maybe in webhook i have to update api verison here to this 2024-04-10?

rotund zinc
#

can you share the PaymentIntent ID? the one from the body you just shared above didn't set it.

vital cedar
#

a new one?

#

pi_3Qgk0pKPj3JfoYa70FpTddP0

rotund zinc
#

there you set it, yes. and what's do you see in your webhook code when you console.log ?

vital cedar
#

i changed api version to the one 2024-04-10, tried placing deposit and here are the logs

{ id: 'pi_3Qgk31KPj3JfoYa70ua2mjdY',
object: 'payment_intent',
amount: 500,
amount_capturable: 0,
amount_details: { tip: {} },
amount_received: 500,
application: null,
application_fee_amount: null,
automatic_payment_methods: { allow_redirects: 'always', enabled: true },
canceled_at: null,
cancellation_reason: null,
capture_method: 'automatic_async',
client_secret: 'pi_3Qgk31KPj3JfoYa70ua2mjdY_secret_JJavl3W3VPbwj0SYd8Of2FWr5',
confirmation_method: 'automatic',
created: 1736760903,
currency: 'usd',
customer: null,
description: null,
invoice: null,
last_payment_error: null,
latest_charge:
{ id: 'ch_3Qgk31KPj3JfoYa70c36sXCN',
object: 'charge',
amount: 500,
amount_captured: 500,
amount_refunded: 0,
application: null,
application_fee: null,
application_fee_amount: null,
balance_transaction: null,
billing_details:
{ address: [Object], email: 'asd@asd.asd', name: 'asdhjsakdhj', phone: '67979797' },
calculated_statement_descriptor: 'TASKERDATA.COM',
captured: true,
created: 1736760904,
currency: 'usd',
customer: null,
description: null,
destination: null,
dispute: null,
disputed: false,
failure_balance_transaction: null,
failure_code: null,
failure_message: null,
fraud_details: {},
invoice: null,
livemode: false,
metadata: {},
on_behalf_of: null,
order: null,
outcome:
{ advice_code: null,
network_advice_code: null,
network_decline_code: null,
network_status: 'approved_by_network',
reason: null,
risk_level: 'normal',
risk_score: 24,
seller_message: 'Payment complete.',
type: 'authorized' },

#

paid: true,
payment_intent: 'pi_3Qgk31KPj3JfoYa70ua2mjdY',
payment_method: 'pm_1Qgk32KPj3JfoYa7W7rofnHl',
payment_method_details: { card: [Object], type: 'card' },
radar_options: {},
receipt_email: null,
receipt_number: null,
receipt_url:
'https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xUUQ1SDlLUGozSmZvWWE3KMm8k7wGMgZwLBTQUgg6LBbIeNg-sELEYQ4KWujvUmLVRk2Cwyj2FFZlXs3p9ev703Pfh-7dWahXExRr',
refunded: false,
review: null,
shipping: null,
source: null,
source_transfer: null,
statement_descriptor: null,
statement_descriptor_suffix: null,
status: 'succeeded',
transfer_data: null,
transfer_group: null },
livemode: false,
metadata: {},
next_action: null,
on_behalf_of: null,
payment_method: 'pm_1Qgk32KPj3JfoYa7W7rofnHl',
payment_method_configuration_details: { id: 'pmc_1QNzjCKPj3JfoYa74Tk4JWzv', parent: null },
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: 'succeeded',
transfer_data: null,
transfer_group: null }

rotund zinc
#

thanks, looking into this

#

oh sorry, I was wrong earlier. can you set capture_method to automatic (and not automatic_async)?

vital cedar
#

id: 'pi_3QgkJvKPj3JfoYa70jI7jqRb',
object: 'payment_intent',
amount: 500,
amount_capturable: 0,
amount_details: { tip: {} },
amount_received: 500,
application: null,
application_fee_amount: null,
automatic_payment_methods: { allow_redirects: 'always', enabled: true },
canceled_at: null,
cancellation_reason: null,
capture_method: 'automatic',
client_secret: 'pi_3QgkJvKPj3JfoYa70jI7jqRb_secret_ZgDCpJCQLVWf1UTbBiznq68gI',
confirmation_method: 'automatic',
created: 1736761951,
currency: 'usd',
customer: null,
description: null,
invoice: null,
last_payment_error: null,
latest_charge:
{ id: 'ch_3QgkJvKPj3JfoYa702WQcsdA',
object: 'charge',
amount: 500,
amount_captured: 500,
amount_refunded: 0,
application: null,
application_fee: null,
application_fee_amount: null,
balance_transaction:
{ id: 'txn_3QgkJvKPj3JfoYa70tErRMsx',
object: 'balance_transaction',
amount: 500,
available_on: 1737331200,
created: 1736761952,
currency: 'usd',
description: null,
exchange_rate: null,
fee: 46,
fee_details: [Array],
net: 454,
reporting_category: 'charge',
source: 'ch_3QgkJvKPj3JfoYa702WQcsdA',
status: 'pending',
type: 'charge' },
billing_details:
{ address: [Object], email: 'asd@asd.asd', name: 'asdhjsakdhj', phone: '67979797' },
calculated_statement_descriptor: 'TASKERDATA.COM',
captured: true,
created: 1736761952,
currency: 'usd',
customer: null,
description: null,
destination: null,
dispute: null,
disputed: false,
failure_balance_transaction: null,
failure_code: null,
failure_message: null,
fraud_details: {},
invoice: null,
livemode: false,
metadata: {},
on_behalf_of: null,
order: null,

#

outcome:
{ advice_code: null,
network_advice_code: null,
network_decline_code: null,
network_status: 'approved_by_network',
reason: null,
risk_level: 'normal',
risk_score: 50,
seller_message: 'Payment complete.',
type: 'authorized' },
paid: true,
payment_intent: 'pi_3QgkJvKPj3JfoYa70jI7jqRb',
payment_method: 'pm_1QgkJwKPj3JfoYa7w3Wus8Ze',
payment_method_details: { card: [Object], type: 'card' },
radar_options: {},
receipt_email: null,
receipt_number: null,
receipt_url:
'https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xUUQ1SDlLUGozSmZvWWE3KOHEk7wGMgZa0UQCYVQ6LBb_RySyIBwcLKYUmaDmVGtglxT4uq5yr5GD71So1GIqSwUP1GCsangVa-5u',
refunded: false,
review: null,
shipping: null,
source: null,
source_transfer: null,
statement_descriptor: null,
statement_descriptor_suffix: null,
status: 'succeeded',
transfer_data: null,
transfer_group: null },
livemode: false,
metadata: {},
next_action: null,
on_behalf_of: null,
payment_method: 'pm_1QgkJwKPj3JfoYa7w3Wus8Ze',
payment_method_configuration_details: { id: 'pmc_1QNzjCKPj3JfoYa74Tk4JWzv', parent: null },
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: 'succeeded',
transfer_data: null,
transfer_group: null

#

i think im seeing a fee there

rotund zinc
#

yep: fee: 46

vital cedar
#

thank you