#some1ataplace_webhooks

1 messages ¡ Page 1 of 1 (latest)

wary trenchBOT
#

👋 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/1277808199092932639

📝 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.

short compass
#

Example metadata variable:

"updated_course_ids_and_prices": "[{"course_id": 29, "price": 1.0, "percent_off": null, "amount_off": null, "promo_code": null, "promo_id": null, "product_type": null, "coupon_id": null}, {"course_id": 3, "price": 2.0, "percent_off": null, "amount_off": null, "promo_code": null, "promo_id": null, "product_type": null, "coupon_id": null}]"

lime trout
#

With List Checkout Session API, Stripe returned the list of Checkout Sessions and auto_paging_iter() will turn it into an iterator. You have to loop it through: https://docs.stripe.com/api/pagination/auto

For Checkout Session, I'd recommend listening to checkout.session.* related events and it will include metadata by default, so that you don't have to retrieve the Checkout Session again: https://docs.stripe.com/checkout/fulfillment#create-payment-event-handler

Learn how to fulfill payments received with Checkout and Payment Links.

short compass
#

okay, what I am trying to do is parse through that metadata in the webhook to make a stripe connect transfer api call

lime trout
#

If you wish to have metadata saved on the Payment Intent object for Checkout Session integration, that's possible with setting metadata on payment_intent_data.metadata on Checkout Session creation request: https://docs.stripe.com/api/checkout/sessions/create#create_checkout_session-payment_intent_data-metadata

#

In this case, you can read the metadata directly on payment_intent.* events without additional Checkout Session retrieval

short compass
#

oh wow good to know

lime trout
short compass
#

thanks, give me a few minutes to try some stuff. Do you think this is the right approach to put this array of dictionary items in metadata? Or maybe it would be better to put it in a session variable in django?

lime trout
#

Webhook server has no access to the session on a web browser. They don't share the session.

I'd recommend storing the information in your own database and give it an ID, then set the ID as the metadata, so that your system can retrieve relevant information from your own database later

short compass
#

oh wow good point

#

would it be more efficient to store this stuff in the payment intent metadata rather than the checkout session metadata simply because it is 1 less api call?

lime trout
#

There are two options here:

  1. Store the metadata on the Checkout Session directly, and listen to checkout.session.* event for the payment outcome: https://docs.stripe.com/checkout/fulfillment#create-payment-event-handler
  2. Store the metadata on the payment_intent_data.metadata property, and listen to payment_intent.* events for the payment outcome: https://docs.stripe.com/metadata#set-indirectly

Both will save one retrieval request. Note that Stripe enforce rate limit on the API, so I'd recommend only making a request when necessary: https://docs.stripe.com/rate-limits

Learn about API rate limits and how to work with them.

Learn how to fulfill payments received with Checkout and Payment Links.

Learn how to use metadata to save additional information.

short compass
#

Really?

if event.type == 'payment_intent.succeeded':

payment_intent_id = event.data.object.id

versus

checkout_session = stripe.checkout.Session.list(payment_intent=payment_intent_id,expand=["data.line_items",]).auto_paging_iter()

That seems like an extra api call if I choose to get the metadata from the checkout_session?

lime trout
#

In the object itself of payment_intent.succeeded event, the metadata will be present. No additional retrieval request is required

#

metadata will be available in event.data.object directly

short compass
#

right, that makes me believe that putting the updated_course_ids_and_prices in the payment_intent metadata and then accessing it from the event.data.object in the webhook would be the better approach

lime trout
#

Sounds good!

short compass
#

im about to test what i have now from the checkout session for now hopefully it will work and make the connect transfer

#

hmm a bit shocked by this:

course_id = y['course_id']
~^^^^^^^^^^^^^
TypeError: string indices must be integers, not 'str'

for x in checkout_session:
  print('updated course ids and prices webhook ', x.metadata.updated_course_ids_and_prices)
  updated_course_ids_and_prices = x.metadata.updated_course_ids_and_prices
  #For each course get the new prices and transfer the percentage amounts to the teacher stripe connect account
  for y in updated_course_ids_and_prices:
    course_id = y['course_id']
    course_price = y['price']
    course_owner = Course.objects.get(id=course_id).user
    teacher_connected_account = course_owner.teacher_stripe_connect_id
    transfer_amount = int((course_price * (settings.STRIPE_CONNECT_ORDER_PERCENT / 100)) * 100)
    try:
      stripe.Transfer.create(
        amount=transfer_amount,
        currency="usd",
        destination=teacher_connected_account,
        description=f"Transfer for course {course_id} sale"
      )
#

I will try making course_id an int.

#

That didn't work. Got any ideas?

course_id = int(y['course_id'])
~^^^^^^^^^^^^^
TypeError: string indices must be integers, not 'str'

lime trout
#

updated_course_ids_and_prices is already a hash object

#

why do you loop through it?

#

metadata is a map object

short compass
#

because i need to make multiple connect transfers to each connect account or teacher

lime trout
#

it only allows key-value pair

short compass
#

so when someone buys multiple courses in a cart, each teacher gets a reward

lime trout
#

Can you share an example event ID (evt_xxx), so that I can take a look how you sent the metadata to Stripe?

short compass
#

req_EF0Igd3vhzZKHN

lime trout
#

In https://dashboard.stripe.com/test/logs/req_EF0Igd3vhzZKHN, the metadata is in key-value string pair:

updated_course_ids_and_prices: "[{\"course_id\": 29, \"price\": 1.0, \"percent_off\": null, \"amount_off\": null, \"promo_code\": null, \"promo_id\": null, \"product_type\": null, \"coupon_id\": null}, {\"course_id\": 3, \"price\": 2.0, \"percent_off\": null, \"amount_off\": null, \"promo_code\": null, \"promo_id\": null, \"product_type\": null, \"coupon_id\": null}]"
short compass
#

yes

lime trout
#

Stripe doesn't support array in the metadata value

short compass
#

ah geez

lime trout
#

Your system has to parse or manage manually on your own

short compass
#

would converting to json work?

lime trout
#

You'd need to retrieve the string value from metadata.updated_course_ids_and_prices, then use python library to parse the string to json yourself

short compass
#

okay let me try that

#

It seems like this worked

Webhook:

updated_course_ids_and_prices = json.loads(x.metadata.updated_course_ids_and_prices)

checkout session:

metadata={'updated_course_ids_and_prices':json.dumps(updated_course_ids_and_prices),},

lime trout
#

Looks good to me

short compass
#

awesome, thank you so much for all the help