# Terima kejadian Stripe di endpoint webhook Anda Dengarkan peristiwa dari akun Stripe pada endpoint webhook sehingga integrasi Anda dapat secara otomatis memicu reaksi. ## Start here: Install agent skills Stripe recommends using official skills to integrate with the API using best practices. Follow the instructions below to learn how. **Tip: Use curl instead of Fetch tools.** Skills are detailed 10–20 KB markdown files. Fetch tools summarize them. `curl -sL` guarantees the full content. **Using `npx skills`**: Check if `npx` is installed on the system. If `npx` is available, run `npx skills add https://docs.stripe.com --list` to list available skills, then run `npx skills add https://docs.stripe.com --yes --skill <--skill other-skills>` to install individual skills. **If `npx skills` isn’t available**: You can use curl to fetch the index of available skills, what they do, and their files from `https://docs.stripe.com/.well-known/skills/index.json`. To download a skill and its related files, use curl to download them from `https://docs.stripe.com/.well-known/skills/`. For this article, we recommend using these skills: `stripe-best-practices` > #### Kirim peristiwa ke akun AWS atau langganan Azure Anda > > Anda dapat mengirim acara langsung ke [Amazon EventBridge](https://docs.stripe.com/event-destinations/eventbridge.md) atau [Azure Event Grid](https://docs.stripe.com/event-destinations/eventgrid.md) sebagai tujuan acara. Buat tujuan kejadian untuk menerima kejadian di endpoint webhook HTTPS. Setelah mendaftarkan endpoint webhook, Stripe dapat mendorong data kejadian secara aktual ke endpoint webhook aplikasi Anda bila [kejadian](https://docs.stripe.com/event-destinations.md#events-overview) berlangsung di akun Stripe. Stripe menggunakan HTTPS untuk mengirim kejadian webhook ke aplikasi Anda sebagai payload JSON yang menyertakan [objek Kejadian](https://docs.stripe.com/api/events.md). Menerima peristiwa webhook membantu Anda merespons peristiwa asinkron, seperti ketika bank pelanggan mengonfirmasi pembayaran, pelanggan mengajukan sengketa atas tagihan, atau pembayaran rutin berhasil. ## Memulai Untuk mulai menerima kejadian webhook di aplikasi Anda: 1. Buat handler endpoint webhook untuk menerima permintaan POST data kejadian. 1. Coba handler endpoint webhook Anda secara lokal menggunakan Stripe CLI. 1. Buat [tujuan kejadian](https://docs.stripe.com/event-destinations.md) baru untuk endpoint webhook Anda. 1. Amankan endpoint webhook Anda. Anda dapat mendaftarkan dan membuat satu endpoint untuk menangani beberapa tipe kejadian yang berbeda secara bersamaan, atau menyiapkan masing-masing endpoint bagi kejadian spesifik. ## Perilaku tipe kejadian yang tidak didukung untuk tujuan kejadian organisasi Stripe mengirimkan sebagian besar jenis peristiwa secara asinkron, tetapi menunggu respons untuk beberapa jenis peristiwa. Dalam kasus ini, Stripe berperilaku berbeda bergantung pada apakah tujuan peristiwa memberikan respons atau tidak. Jika tujuan acara Anda menerima peristiwa [Organisasi](https://docs.stripe.com/get-started/account/orgs.md), peristiwa yang memerlukan respons memiliki batasan berikut: - Anda tidak dapat berlangganan `issuing_authorization.request` untuk tujuan organisasi. Sebagai gantinya, siapkan [endpoint webhook](https://docs.stripe.com/webhooks.md#example-endpoint) di akun Stripe dalam organisasi untuk berlangganan tipe kejadian ini. Gunakan `issuing_authorization.request` untuk mengotorisasi permintaan pembelian secara real-time. - Tujuan organisasi menerima `checkout_sessions.completed` tidak dapat [menangani perilaku pengalihan](https://docs.stripe.com/checkout/fulfillment.md#redirect-hosted-checkout) saat Anda menyematkan [Checkout](https://docs.stripe.com/payments/checkout.md) langsung di situs web Anda atau mengarahkan pelanggan ke halaman pembayaran yang di-hosting Stripe. Untuk memengaruhi perilaku pengalihan Checkout, proses jenis peristiwa ini dengan [webhook endpoint](https://docs.stripe.com/webhooks.md#example-endpoint) yang dikonfigurasi di akun Stripe dalam organisasi. - Tujuan organisasi yang merespons dengan gagal terhadap peristiwa `invoice.created` tidak dapat memengaruhi[ finalisasi invoice otomatis saat menggunakan penagihan otomatis](https://docs.stripe.com/billing/subscriptions/webhooks.md#understand). Anda harus memproses jenis peristiwa ini dengan [endpoint webhook](https://docs.stripe.com/webhooks.md#example-endpoint) yang dikonfigurasi di akun Stripe dalam organisasi untuk memicu finalisasi invoice otomatis. ## Buat handler Siapkan fungsi endpoint HTTP atau HTTPS yang dapat menerima permintaan webhook dengan metode POST. Jika Anda masih mengembangkannya pada mesin lokal, fungsi endpoint dapat menggunakan HTTP. Setelah dapat diakses secara publik, fungsi endpoint webhook Anda harus menggunakan HTTPS. Siapkan fungsi endpoint Anda sehingga fungsi tersebut: - Menangani permintaan POST dengan payload JSON yang terdiri dari [objek kejadian](https://docs.stripe.com/api/events/object.md). - Untuk pengendali peristiwa [organisasi](https://docs.stripe.com/get-started/account/orgs.md), sistem akan memeriksa nilai `context` untuk menentukan akun mana dalam organisasi yang menghasilkan peristiwa, kemudian menetapkan header `Stripe-Context` yang sesuai dengan nilai `context` tersebut. - Segera mengembalikan kode status (`2xx`) yang berhasil sebelum logika kompleks yang mungkin menyebabkan waktu habis. Misalnya, Anda harus mengembalikan tanggapan `200` sebelum memperbarui invoice pelanggan, seperti yang dibayarkan dalam sistem akuntansi Anda. > - Gunakan [perancang webhook endpoint interaktif](https://docs.stripe.com/webhooks/quickstart.md) kami untuk membangun fungsi endpoint webhook dalam bahasa pemrograman Anda. - Gunakan referensi Stripe API untuk mengidentifikasi [objek kejadian ringkas](https://docs.stripe.com/api/v2/core/events/event-types.md) atau [objek kejadian cuplikan](https://docs.stripe.com/api/events/object.md) yang perlu diproses oleh handler webhook Anda. #### Contoh endpoint Potongan kode ini adalah fungsi webhook yang dikonfigurasi untuk memeriksa kejadian yang diterima dari akun Stripe, menangani kejadian, dan mengembalikan tanggapan `200`. Referensikan handler kejadian [snapshot](https://docs.stripe.com/event-destinations.md#events-overview) saat Anda menggunakan sumber daya API v1, dan referensikan handler kejadian [tipis](https://docs.stripe.com/event-destinations.md#events-overview) saat Anda menggunakan sumber daya API v2. #### Handler kejadian snapshot Saat Anda membuat handler kejadian snapshot, gunakan definisi objek API pada saat kejadian untuk logika Anda dengan mengakses bidang `data.object` kejadian. Anda juga dapat mengambil sumber daya API dari API Stripe untuk mengakses definisi objek terbaru dan mutakhir. #### Ruby ```ruby require 'json' # Replace this endpoint secret with your unique endpoint secret key # If you're testing with the CLI, run 'stripe listen' to find the secret key # If you defined your endpoint using the API or the Dashboard, check your webhook settings for your endpoint secret: https://dashboard.stripe.com/webhooks endpoint_secret = 'whsec_...'; # Using Sinatra post '/webhook' do payload = request.body.read event = nil begin event = Stripe::Event.construct_from( JSON.parse(payload, symbolize_names: true) ) rescue JSON::ParserError => e # Invalid payload status 400 return end # Check that you have configured webhook signing if endpoint_secret # Retrieve the event by verifying the signature using the raw body and the endpoint secret signature = request.env['HTTP_STRIPE_SIGNATURE']; begin event = Stripe::Webhook.construct_event( payload, signature, endpoint_secret ) rescue Stripe::SignatureVerificationError => e puts "⚠️ Webhook signature verification failed. #{e.message}" status 400 end end # Handle the event case event.type when 'payment_intent.succeeded' payment_intent = event.data.object # contains a Stripe::PaymentIntent # Then define and call a method to handle the successful payment intent. # handle_payment_intent_succeeded(payment_intent) when 'payment_method.attached' payment_method = event.data.object # contains a Stripe::PaymentMethod # Then define and call a method to handle the successful attachment of a PaymentMethod. # handle_payment_method_attached(payment_method) # ... handle other event types else puts "Unhandled event type: #{event.type}" end status 200 end ``` #### Penangan peristiwa tipis (Clover+) Saat Anda membuat penangan peristiwa tipis, gunakan metode `fetchRelatedObject()` untuk mengambil versi terbaru dari objek yang terkait dengan peristiwa. Peristiwa mungkin berisi [data tambahan](https://docs.stripe.com/event-destinations.md#fetch-data) yang hanya bisa Anda ambil melalui metode instance `.fetchEvent()` pada `EventNotification`. Bentuk pasti dari data tersebut bergantung pada `type` Peristiwa. Tipe event harus tersedia pada saat rilis untuk menghasilkan kelas dalam versi SDK tersebut. Untuk menangani Event yang tidak memiliki kelas di SDK, gunakan kelas `UnknownEventNotification`. #### Python ```python import os from stripe import StripeClient from stripe.events import UnknownEventNotification from flask import Flask, request, jsonify app = Flask(__name__) api_key = os.environ.get("STRIPE_API_KEY", "") webhook_secret = os.environ.get("WEBHOOK_SECRET", "") client = StripeClient(api_key) @app.route("/webhook", methods=["POST"]) def webhook(): webhook_body = request.data sig_header = request.headers.get("Stripe-Signature") try: event_notif = client.parse_event_notification( webhook_body, sig_header, webhook_secret ) # type checkers will narrow the type based on the `type` property if event_notif.type == "v1.billing.meter.error_report_triggered": # in this block, event_notification is typed as # a V1BillingMeterErrorReportTriggeredEventNotification # there's basic info about the related object in the notification print(f"Meter w/ id {event_notif.related_object.id} had a problem") # or you can fetch the full object form the API for more details meter = event_notif.fetch_related_object() print( f"Meter {meter.display_name} ({meter.id}) had a problem" ) # And you can always fetch the full event: event = event_notif.fetch_event() print(f"More info: {event.data.developer_message_summary}") elif event_notif.type == "v1.billing.meter.no_meter_found": # in this block, event_notification is typed as # a V1BillingMeterNoMeterFoundEventNotification # that class doesn't define `fetch_related_object` because the event # has no related object. # so this line would correctly give a type error: # meter = event_notif.fetch_related_object() # but fetching the event always works: event = event_notif.fetch_event() print( f"Err! No meter found: {event.data.developer_message_summary}" ) # Events that were introduced after this SDK version release are # represented as `UnknownEventNotification`s. # They're valid, the SDK just doesn't have corresponding classes for them. # You must match on the "type" property instead. elif isinstance(event_notif, UnknownEventNotification): # these lines are optional, but will give you more accurate typing in this block from typing import cast event_notif = cast(UnknownEventNotification, event_notif) # continue matching on the type property # from this point on, the `related_object` property _may_ be None # (depending on the event type) if event_notif.type == "some.new.event": # if this event type has a related object, you can fetch it obj = event_notif.fetch_related_object() # otherwise, `obj` will just be `None` print(f"Related object: {obj}") # you can still fetch the full event, but it will be untyped event = event_notif.fetch_event() print(f"New event: {event.data}") # type: ignore return jsonify(success=True), 200 except Exception as e: return jsonify(error=str(e)), 400 ``` #### Penangan acara tipis (Akasia atau Kemangi) Saat Anda membuat handler kejadian tipis, gunakan metode `fetchRelatedObject()` untuk mengambil versi terbaru objek yang terkait dengan kejadian tersebut. Kejadian tipis dapat berisi [data kontekstual tambahan](https://docs.stripe.com/event-destinations.md#fetch-data) yang hanya dapat Anda ambil dengan API. Gunakan panggilan `retrieve()` dengan identifikasi kejadian tipis untuk mengakses bidang payload tambahan ini. #### Python ```python import os from stripe import StripeClient from stripe.events import V1BillingMeterErrorReportTriggeredEvent from flask import Flask, request, jsonify app = Flask(__name__) api_key = os.environ.get('STRIPE_API_KEY') webhook_secret = os.environ.get('WEBHOOK_SECRET') client = StripeClient(api_key) @app.route('/webhook', methods=['POST']) def webhook(): webhook_body = request.data sig_header = request.headers.get('Stripe-Signature') try: thin_event = client.parse_thin_event(webhook_body, sig_header, webhook_secret) # Fetch the event data to understand the failure event = client.v2.core.events.retrieve(thin_event.id) if isinstance(event, V1BillingMeterErrorReportTriggeredEvent): meter = event.fetch_related_object() meter_id = meter.id # Record the failures and alert your team # Add your logic here return jsonify(success=True), 200 except Exception as e: return jsonify(error=str(e)), 400 if __name__ == '__main__': app.run(port=4242) ``` #### Menggunakan `context` #### Peristiwa snapshot Potongan kode ini adalah fungsi webhook yang dikonfigurasi untuk memeriksa kejadian yang diterima, mendeteksi akun asal jika berlaku, menangani kejadian, dan mengembalikan respons `200`. #### Ruby ```ruby require 'json' # Using Sinatra post '/webhook' do payload = request.body.read event = nil begin event = Stripe::Event.construct_from( JSON.parse(payload, symbolize_names: true) ) rescue JSON::ParserError => e # Invalid payload status 400 return end # Extract the context context = event.context # Define your API key variables (ideally loaded securely) ACCOUNT_123_API_KEY = "sk_test_123" ACCOUNT_456_API_KEY = "sk_test_456" account_api_keys = { "account_123" => ACCOUNT_123_API_KEY, "account_456" => ACCOUNT_456_API_KEY } api_key = account_api_keys[context] if api_key.nil? puts "No API key found for context: #{context}" status 400 return end # Handle the event case event.type when 'customer.created' customer = event.data.object begin latest_customer = Stripe::Customer.retrieve( customer.id, { api_key: api_key } ) handle_customer_created(latest_customer, context) rescue => e puts "Error retrieving customer: #{e.message}" status 500 return end when 'payment_method.attached' payment_method = event.data.object begin latest_payment_method = Stripe::PaymentMethod.retrieve( payment_method.id, { api_key: api_key } ) handle_payment_method_attached(latest_payment_method, context) rescue => e puts "Error retrieving payment method: #{e.message}" status 500 return end else puts "Unhandled event type: #{event.type}" end status 200 end ``` #### Penangan peristiwa tipis (Clover+) Gunakan properti `context` `EventNotification` untuk mengidentifikasi akun untuk peristiwa dalam [organisasi](https://docs.stripe.com/get-started/account/orgs.md) Anda. Anda harus mengatur [tajuk Stripe-Context](https://docs.stripe.com/context.md) secara manual untuk semua panggilan API kecuali `.fetchRelatedObject()` dan `.fetchEvent()`, yang melakukan ini untuk Anda secara otomatis. #### Python ```python org_api_key = os.environ.get("STRIPE_API_KEY") webhook_secret = os.environ.get("WEBHOOK_SECRET") client = StripeClient(org_api_key) # inside your webhook handler event_notification = client.parse_event_notification(payload, sig_header, webhook_secret) # uses `context` automatically event_notification.fetch_event() # pass context manually for other API requests client.v1.invoices.list(stripe_context=event_notification.context) ``` #### Penangan acara tipis (Akasia atau Kemangi) Potongan kode ini adalah fungsi webhook yang dikonfigurasikan untuk menerima thin event di seluruh organisasi, memverifikasi tanda tangan, menentukan rekening asal dengan bidang `context`, dan menggunakan kunci API rekening tersebut untuk panggilan API berikutnya. #### Python ```python import os from flask import Flask, request, jsonify from stripe import StripeClient from stripe.events import V1BillingMeterErrorReportTriggeredEvent app = Flask(__name__) org_api_key = os.environ.get("STRIPE_API_KEY") webhook_secret = os.environ.get("WEBHOOK_SECRET") client = StripeClient(org_api_key) account_api_keys = { "account_123": os.environ.get("ACCOUNT_123_API_KEY"), "account_456": os.environ.get("ACCOUNT_456_API_KEY"), } @app.route("/webhook", methods=["POST"]) def webhook(): payload = request.data sig_header = request.headers.get("Stripe-Signature") try: thin_event = client.parse_thin_event(payload, sig_header, webhook_secret) # Retrieve the event using the org client to inspect context event = client.v2.core.events.retrieve(thin_event.id) context = getattr(event, "context", None) if not context: return jsonify(error="Missing context"), 400 account_key = account_api_keys.get(context) if not account_key: return jsonify(error="Unknown context"), 400 account_client = StripeClient(account_key) full_event = account_client.v2.core.events.retrieve(thin_event.id) if isinstance(full_event, V1BillingMeterErrorReportTriggeredEvent): meter = full_event.fetch_related_object() meter_id = meter.id # Record the failures and alert your team # Add your logic here return jsonify(success=True), 200 except Exception as e: return jsonify(error=str(e)), 400 if __name__ == "__main__": app.run(port=4242) ``` ## Coba handler Anda Sebelum menjadikan live fungsi endpoint webhook, kami merekomendasikan Anda mencoba integrasi aplikasi. Anda dapat melakukannya dengan melakukan konfigurasi listener lokal untuk mengirim kejadian ke mesin lokal, dan mengirim kejadian percobaan. Anda perlu menggunakan [CLI](https://docs.stripe.com/stripe-cli.md) untuk mencobanya. #### Teruskan kejadian ke endpoint lokal Untuk meneruskan kejadian ke endpoint lokal Anda, jalankan perintah berikut ini dengan [CLI](https://docs.stripe.com/stripe-cli.md) guna menyiapkan listener lokal. Tanda `--forward-to` mengirim semua [kejadian Stripe](https://docs.stripe.com/cli/trigger#trigger-event) dalam [sandbox](https://docs.stripe.com/sandboxes.md) ke endpoint webhook lokal Anda. Gunakan perintah CLI yang sesuai di bawah ini bergantung pada jika Anda menggunakan kejadian snapshot atau [tipis](https://docs.stripe.com/event-destinations.md#events-overview). #### Teruskan kejadian snapshot Gunakan perintah berikut untuk meneruskan [kejadian snapshot](https://docs.stripe.com/event-destinations.md#events-overview) ke listener lokal Anda. ```bash stripe listen --forward-to localhost:4242/webhook ``` #### Teruskan kejadian ringan Gunakan perintah berikut untuk meneruskan [kejadian tipis](https://docs.stripe.com/event-destinations.md#events-overview) ke listener lokal Anda. ```bash $ stripe listen --forward-thin-to localhost:4242/webhook --thin-events "*" ``` > Anda juga dapat menjalankan `Stripe Listen` untuk melihat peristiwa di [Stripe Shell](https://docs.stripe.com/workbench/shell.md), meskipun Anda tidak akan dapat meneruskan kejadian dari shell ke endpoint lokal Anda. Konfigurasi yang berguna untuk membantu percobaan Anda dengan listener lokal menyertakan yang berikut ini: - Untuk menonaktifkan verifikasi sertifikat HTTPS, gunakan tanda opsional `--skip-verify`. - Untuk meneruskan hanya kejadian spesifik, gunakan tanda opsional `--events` dan masukkan daftar kejadian yang dipisahkan dengan koma. #### Teruskan kejadian snapshot target Gunakan perintah berikut untuk meneruskan kejadian snapshot target ke listener lokal Anda. ```bash stripe listen --events payment_intent.created,customer.created,payment_intent.succeeded,checkout.session.completed,payment_intent.payment_failed \ --forward-to localhost:4242/webhook ``` #### Teruskan kejadian ringan target Gunakan perintah berikut untuk meneruskan kejadian tipis target ke listener lokal Anda. ```bash stripe listen --thin-events v1.billing.meter.error_report_triggered,v1.billing.meter.no_meter_found \ --forward-thin-to localhost:4242/webhook ``` - Untuk meneruskan kejadian ke endpoint webhook lokal Anda dari endpoint webhook publik yang sudah didaftarkan di Stripe, gunakan tanda opsional `--load-from-webhooks-api`. Hal ini akan memuat endpoint terdaftar, mengurai jalur dan kejadian terdaftarnya, kemudian menambahkan jalur ke endpoint webhook lokal Anda di `--forward-to path`. #### Teruskan kejadian snapshot dari endpoint webhook publik Gunakan perintah berikut untuk meneruskan kejadian snapshot dari endpoint webhook publik ke listener lokal Anda. ```bash stripe listen --load-from-webhooks-api --forward-to localhost:4242/webhook ``` #### Teruskan kejadian tipis dari endpoint webhook publik Gunakan perintah berikut untuk meneruskan kejadian tipis dari endpoint webhook publik ke listener lokal Anda. ```bash stripe listen --load-from-webhooks-api --forward-thin-to localhost:4242/webhook ``` - Untuk memeriksa tanda tangan webhook, gunakan `{{WEBHOOK_SIGNING_SECRET}}` dari output awal perintah listen. ```output Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit) ``` #### Memicu kejadian percobaan Untuk mengirim kejadian percobaan, picu tipe kejadian yang menjadi langganan tujuan kejadian Anda dengan membuat objek secara manual di Dashboard Stripe. Pelajari cara memicu kejadian dengan [Stripe for VS Code](https://docs.stripe.com/stripe-vscode.md). #### Picu kejadian potret Anda dapat menggunakan perintah berikut di salah satu [Stripe Shell](https://docs.stripe.com/workbench/shell.md) atau [Stripe CLI](https://docs.stripe.com/stripe-cli.md). Contoh ini memicu peristiwa `payment_intent.succeeded`: ```bash stripe trigger payment_intent.succeeded Running fixture for: payment_intent Trigger succeeded! Check dashboard for event details. ``` #### Picu kejadian tipis Anda dapat menggunakan perintah berikut di [Stripe CLI](https://docs.stripe.com/stripe-cli.md). Contoh ini memicu kejadian `v1.billing.meter.error_report_triggered`: ```bash stripe trigger v1.billing.meter.error_report_triggered Setting up fixture for: list_billing_meters Running fixture for: list_billing_meters Setting up fixture for: billing_meter Running fixture for: billing_meter Setting up fixture for: list_billing_meters_after_creation Running fixture for: list_billing_meters_after_creation Setting up fixture for: billing_meter_event_session Running fixture for: billing_meter_event_session Setting up fixture for: create_billing_meter_event_stream Running fixture for: create_billing_meter_event_stream Trigger succeeded! Check dashboard for event details. ``` ## Daftarkan endpoint Anda Setelah mencoba fungsi endpoint webhook Anda, gunakan [API](https://docs.stripe.com/api/v2/event-destinations.md) atau tab **Webhook** di Workbench untuk mendaftarkan URL yang dapat diakses dari endpoint webhook Anda sehingga Stripe mengetahui tujuan pengiriman kejadian. Anda dapat mendaftarkan hingga 16 endpoint webhook dengan Stripe. Endpoint webhook yang didaftarkan harus berupa URL **HTTPS** yang dapat diakses secara publik. #### Format URL webhook Format URL untuk mendaftarkan endpoint webhook adalah: ``` https:/// ``` Misalnya, jika domain Anda adalah `https://mycompanysite.com` dan rute ke endpoint webhook Anda adalah `@app.route('/stripe_webhooks', methods=['POST'])`, masukkan `https://mycompanysite.com/stripe_webhooks` sebagai **Endpoint URL**. #### Buat tujuan kejadian untuk endpoint webhook Anda Buat tujuan kejadian menggunakan Workbench di Dashboard atau secara terprogram dengan [API](https://docs.stripe.com/api/v2/event-destinations.md). Anda dapat mendaftarkan hingga 16 tujuan kejadian di setiap akun Stripe. #### Dashboard Untuk membuat endpoint webhook baru di Dashboard: 1. Buka tab [Webhook](https://dashboard.stripe.com/webhooks) di Workbench. 1. Klik **Buat tujuan kejadian**. 1. Pilih tempat Anda ingin menerima kejadian. Stripe mendukung dua tipe konfigurasi: **Akun Anda** dan [Akun terhubung](https://docs.stripe.com/connect.md). Pilih **Akun** untuk mendengarkan kejadian dari akun Anda sendiri. Jika Anda membuat [aplikasi Connect](https://docs.stripe.com/connect.md) dan ingin mendengarkan kejadian dari akun terhubung, pilih **Akun terhubung**. > #### Dengarkan kejadian dari endpoint webhook organisasi > > Jika membuat endpoint webhook di [akun organisasi](https://docs.stripe.com/get-started/account/orgs.md), pilih **Akun** untuk mendengarkan kejadian dari akun di organisasi Anda. Jika Anda memiliki [platform Connect](https://docs.stripe.com/connect.md) sebagai anggota organisasi dan ingin mendengarkan kejadian dari semua akun terhubung platform, pilih **Akun terhubung**. 1. Pilih versi API untuk [objek kejadian](https://docs.stripe.com/api/events.md) yang ingin Anda gunakan. 1. Pilih [tipe kejadian](https://docs.stripe.com/api/events/types.md) yang ingin Anda kirimkan ke endpoint webhook. 1. Pilih **Lanjutkan**, lalu pilih **Endpoint webhook** sebagai tipe tujuan. 1. Klik **Lanjutkan**, lalu berikan **URL endpoint** dan deskripsi opsional untuk webhook. #### API Anda dapat membuat tujuan kejadian baru yang memberi tahu bila kesalahan validasi [tagihan berbasis penggunaan](https://docs.stripe.com/billing/subscriptions/usage-based.md) dipicu menggunakan [API](https://docs.stripe.com/api/v2/event-destinations.md). Jika Anda telah membuat [Hubungkan aplikasi](https://docs.stripe.com/connect.md) dan ingin mendengarkan akun terhubung Anda, gunakan [events_from](https://docs.stripe.com/api/v2/core/event-destinations/create.md#v2_create_event_destinations-events_from) dan atur nilainya ke `@accounts`. Untuk [Organisasi](https://docs.stripe.com/get-started/account/orgs.md) tujuan acara, gunakan `@organization_members` untuk peristiwa dari akun di organisasi Anda, atau `@organization_members/@accounts` untuk acara dari akun terhubung di seluruh organisasi Anda. ```curl curl -X POST https://api.stripe.com/v2/core/event_destinations \ -H "Authorization: Bearer <>" \ -H "Stripe-Version: 2026-03-25.preview" \ --json '{ "name": "My event destination", "description": "This is my event destination, I like it a lot", "type": "webhook_endpoint", "event_payload": "thin", "enabled_events": [ "v1.billing.meter.error_report_triggered" ], "webhook_endpoint": { "url": "https://example.com/my/webhook/endpoint" } }' ``` > [Workbench](https://docs.stripe.com/workbench.md) menggantikan [Dashboard Pengembang](https://docs.stripe.com/development/dashboard.md) yang ada. Jika Anda masih menggunakan Dashboard Pengembang, lihat cara untuk [membuat endpoint webhook baru](https://docs.stripe.com/development/dashboard/webhooks.md). ## Amankan endpoint Anda Setelah mengonfirmasi bahwa endpoint Anda berfungsi sesuai harapan, amankan dengan mengimplementasikan [praktik terbaik webhook](https://docs.stripe.com/webhooks.md#best-practices). Amankan integrasi Anda dengan memastikan handler Anda memverifikasi bahwa semua permintaan webhook dihasilkan oleh Stripe. Anda dapat memverifikasi tanda tangan webhook menggunakan perpustakaan resmi kami atau memverifikasinya secara manual. #### Verifikasikan dengan pustaka resmi (direkomendasikan) ### Verifikasikan tanda tangan webhook dengan pustaka resmi Kami merekomendasikan penggunaan pustaka resmi kami untuk memverifikasi tanda tangan. Anda melakukan verifikasi dengan memberikan payload kejadian, header `Stripe-Signature` dan rahasia endpoint. Jika verifikasi gagal, Anda akan menerima kesalahan. Jika Anda mendapatkan kesalahan verifikasi tanda tangan, baca panduan kami tentang [pemecahan masalahnya](https://docs.stripe.com/webhooks/signature.md). > Stripe mewajibkan isi permintaan yang belum diproses untuk melakukan verifikasi tanda tangan. Jika Anda menggunakan framework, pastikan itu tidak memanipulasi isi permintaan yang belum diproses. Manipulasi apa pun pada isi permintaan yang belum diproses akan menyebabkan verifikasi gagal. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' require 'stripe' require 'sinatra' # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboardendpoint_secret = 'whsec_...' # Using the Sinatra framework set :port, 4242 post '/my/webhook/url' do payload = request.body.readsig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil beginevent = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload puts "Error parsing payload: #{e.message}" status 400 return rescue Stripe::SignatureVerificationError => e# Invalid signature puts "Error verifying webhook signature: #{e.message}" status 400 return end # Handle the event case event.type when 'payment_intent.succeeded' payment_intent = event.data.object # contains a Stripe::PaymentIntent puts 'PaymentIntent was successful!' when 'payment_method.attached' payment_method = event.data.object # contains a Stripe::PaymentMethod puts 'PaymentMethod was attached to a Customer!' # ... handle other event types else puts "Unhandled event type: #{event.type}" end status 200 end ``` #### Verifikasikan secara manual ### Verifikasikan tanda tangan webhook secara manual Meski kami merekomendasikan Anda menggunakan pustaka resmi kami untuk memverifikasi tanda tangan kejadian webhook, Anda dapat membuat solusi custom dengan mengikuti bagian ini. Header `Stripe-Signature` yang disertakan di setiap kejadian yang ditandatangani berisi stempel waktu dan satu atau beberapa tanda tangan yang harus Anda verifikasi. Stempel waktu memiliki awalan `t=`, dan setiap tanda tangan memiliki awalan *scheme*. Skema dimulai dengan `v`, diikuti oleh bilangan bulat. Saat ini, satu-satunya skema tanda tangan live yang valid adalah `v1`. Untuk membantu percobaan, Stripe mengirim tanda tangan tambahan dengan skema `v0` palsu, untuk kejadian percobaan. ``` Stripe-Signature: t=1492774577, v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd, v0=6ffbb59b2300aae63f272406069a9788598b792a944a07aba816edb039989a39 ``` > Kami menyediakan baris baru untuk kejelasan, tetapi header `Stripe-Signature` yang sebenarnya ada di satu baris. Stripe membuat tanda tangan menggunakan kode autentikasi pesan berbasis hash ([HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code)) dengan [SHA-256](https://en.wikipedia.org/wiki/SHA-2). Untuk mencegah [serangan downgrade](https://en.wikipedia.org/wiki/Downgrade_attack), abaikan semua skema yang bukan `v1`. Anda dapat memiliki beberapa tanda tangan dengan pasangan skema-rahasia yang sama bila Anda [mencabut rahasia endpoint](https://docs.stripe.com/webhooks.md#roll-endpoint-secrets), serta tetap mengaktifkan rahasia sebelumnya hingga 24 jam. Selama waktu ini, endpoint Anda memiliki beberapa rahasia aktif dan Stripe membuatkan satu tanda tangan untuk setiap rahasia. Untuk membuat solusi manual guna memverifikasi tanda tangan, Anda harus menyelesaikan langkah-langkah berikut: #### Langkah 1: Ekstrak stempel waktu dan tanda tangan dari tajuk Pisahkan tajuk menggunakan karakter `,` sebagai pemisah untuk mendapatkan daftar elemen. Kemudian pisahkan setiap elemen menggunakan karakter `=` sebagai pemisah untuk mendapatkan awalan dan pasangan nilai. Nilai untuk awalan `t` sesuai dengan stempel waktu, dan `v1` sesuai dengan tanda tangan. Anda dapat membuang semua elemen lain. #### Langkah 2: Siapkan string `signed_payload` String `signed_payload` dibuat dengan penggabungan: - Stempel waktu (sebagai string) - Karakter `.` - Payload JSON aktual (yaitu, isi permintaan) #### Langkah 3: Tentukan perkiraan tanda tangan Hitung HMAC dengan fungsi hash SHA256. Gunakan rahasia penandatanganan endpoint sebagai kunci, dan gunakan string `signed_payload` sebagai pesan. #### Langkah 4: Bandingkan tanda tangan Bandingkan tanda tangan di tajuk dengan perkiraan tanda tangan. Untuk pencocokan kesetaraan, hitung perbedaan antara stempel waktu saat ini dan stempel waktu yang diterima, kemudian putuskan apakah perbedaannya masih dalam toleransi Anda. Untuk memproteksi dari timing attack, gunakan perbandingan string berwaktu konstan untuk membandingkan perkiraan tanda tangan dengan setiap tanda tangan yang diterima. ## Debug integrasi webhook Beberapa tipe masalah dapat terjadi ketika mengirimkan kejadian ke endpoint webhook Anda: - Stripe mungkin tidak dapat mengirimkan kejadian ke endpoint webhook Anda. - Endpoint webhook Anda mungkin memiliki masalah SSL. - Konektivitas jaringan Anda terputus-putus. - Endpoint webhook Anda tidak menerima kejadian yang Anda perkirakan. ### Lihat pengiriman kejadian Untuk melihat pengiriman peristiwa, pilih endpoint webhook di bawah **Webhooks**, lalu pilih tab **Peristiwa**. Tab **Peristiwa** menyediakan daftar peristiwa dan apakah peristiwa tersebut `Delivered`, `Pending`, atau `Failed`. Klik peristiwa untuk melihat metadata, termasuk kode status HTTP dari upaya pengiriman dan waktu pengiriman yang tertunda di masa mendatang. Anda juga dapat menggunakan [Stripe CLI](https://docs.stripe.com/stripe-cli.md) untuk [mendengarkan kejadian](https://docs.stripe.com/webhooks.md#test-webhook) secara langsung di terminal. ### Perbaiki kode status HTTP Bila kejadian menampilkan kode status `200`, ini menunjukkan pengiriman yang berhasil ke endpoint webhook. Anda mungkin juga menerima kode status selain `200`. Lihat tabel di bawah ini untuk daftar kode status HTTP yang umum dan solusi yang direkomendasikan. | Status webhook menunggu | Keterangan | Perbaiki | | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | (Tidak dapat menghubungkan) ERR | Kami tidak dapat membuat koneksi ke server tujuan. | Pastikan domain host Anda dapat diakses secara publik dengan internet. | | (`302`) ERR (atau status `3xx` lainnya) | Server tujuan berusaha mengarahkan permintaan ke lokasi lain. Kami menganggap respons pengalihan ke permintaan webhook sebagai kegagalan. | Atur tujuan endpoint webhook ke URL yang diselesaikan dengan pengalihan. | | (`400`) ERR (atau status `4xx` lainnya) | Server tujuan tidak dapat atau tidak akan memproses permintaan. Ini mungkin terjadi saat server mendeteksi kesalahan (`400`), saat URL tujuan memiliki pembatasan akses, (`401`, `403`), atau saat URL tujuan tidak ada (`404`). | - Pastikan endpoint Anda dapat diakses secara publik dengan internet. - Pastikan endpoint Anda menerima metode HTTP POST. | | (`500`) ERR (atau status `5xx` lainnya) | Server tujuan mengalami kesalahan saat memproses permintaan. | Tinjau log aplikasi Anda untuk memahami alasannya menampilkan kesalahan `500`. | | (Kesalahan TLS) ERR | Kami tidak dapat membuat koneksi yang aman ke server tujuan. Masalah dengan sertifikat SSL/TLS atau sertifikat perantara dalam rantai sertifikat server tujuan biasanya menyebabkan kesalahan ini. Stripe memerlukan *TLS* (TLS refers to the process of securely transmitting data between the client—the app or browser that your customer is using—and your server. This was originally performed using the SSL (Secure Sockets Layer) protocol) versi `v1.2` atau yang lebih tinggi. | Lakukan [percobaan server SSL](https://www.ssllabs.com/ssltest/) untuk menemukan masalah yang mungkin menyebabkan kesalahan ini. | | (Waktu habis) ERR | Server tujuan memerlukan waktu terlalu lama untuk menanggapi permintaan webhook. | Pastikan Anda segera menunda logika kompleks dan mengembalikan tanggapan yang berhasil dalam kode penanganan webhook Anda. | ## Perilaku pengiriman kejadian Bagian ini membantu Anda memahami berbagai perilaku yang diperkirakan mengenai cara Stripe mengirim kejadian ke endpoint webhook Anda. ### Percobaan ulang otomatis Stripe mencoba untuk mengirim kejadian ke tujuan Anda hingga selama tiga hari dengan backoff eksponensial dalam mode live. Lihat kapan percobaan ulang berikutnya akan terjadi, jika berlaku, di tab **Pengiriman kejadian** dari tujuan kejadian. Kami mencoba ulang pengiriman kejadian yang dibuat di sandbox tiga kali selama beberapa jam. Jika tujuan Anda telah dinonaktifkan atau dihapus saat kami mencoba ulang, kami mencegah percobaan ulang mendatang dari kejadian tersebut. Namun, jika Anda menonaktifkan, kemudian mengaktifkan ulang tujuan kejadian sebelum kami dapat mencoba ulang, Anda masih melihat upaya percobaan ulang mendatang. ### Percobaan ulang manual Ada dua cara untuk mencoba ulang kejadian secara manual: - Di Dashboard Stripe, klik **Kirim ulang** saat melihat acara tertentu. Ini berfungsi hingga 15 hari setelah pembuatan acara. - Dengan [Stripe CLI](https://docs.stripe.com/cli/events/resend), jalankan perintah `stripe events resend --webhook-endpoint=`. Ini berfungsi hingga 30 hari setelah pembuatan acara. Mengirim ulang peristiwa yang mengalami kegagalan pengiriman sebelumnya secara manual ke endpoint webhook tidak mengabaikan [perilaku percobaan ulang otomatis](https://docs.stripe.com/webhooks.md#automatic-retries) Stripe, bahkan jika hal itu menghasilkan kode status `2xx`. Pelajari cara [memproses peristiwa webhook yang tidak terkirim](https://docs.stripe.com/webhooks/process-undelivered-events.md) untuk menghentikan percobaan ulang di masa mendatang. ### Pengurutan kejadian Stripe tidak menjamin pengiriman kejadian sesuai dengan urutan pembuatannya. Misalnya, pembuatan langganan dapat menghasilkan kejadian berikut ini: - `customer.subscription.created` - `invoice.created` - `invoice.paid` - `charge.created` (jika ada charge) Pastikan tujuan kejadian Anda tidak bergantung pada penerimaan kejadian dalam urutan spesifik. Bersiaplah mengelola pengiriman sebagaimana mestinya. Anda juga dapat menggunakan API untuk mengambil objek yang tidak ada. Misalnya, Anda dapat mengambil invoice, charge, dan objek langganan dengan informasi dari `invoice.paid` jika Anda menerima kejadian ini terlebih dahulu. ### Pembuatan versi API Versi API di pengaturan akun Anda saat kejadian berlangsung menentukan versi API, sehingga struktur [Kejadian](https://docs.stripe.com/api/events.md) dikirim ke tujuan Anda. Misalnya, jika akun diatur ke versi API yang lebih lama, seperti 16-02-2015, dan Anda mengubah versi API untuk permintaan spesifik dengan [pembuatan versi](https://docs.stripe.com/api.md#versioning), objek [Event](https://docs.stripe.com/api/events.md) yang dihasilkan serta dikirim ke tujuan Anda tetap didasarkan pada versi API 2015-02-16. Anda tidak dapat mengubah objek [Kejadian](https://docs.stripe.com/api/events.md) setelah pembuatan. Misalnya, jika Anda memperbarui charge, kejadian charge semula tetap tidak berubah. Akibatnya, pembaruan selanjutnya pada versi API akun Anda tidak secara retroaktif mengubah objek [Kejadian](https://docs.stripe.com/api/events.md) yang ada. Mengambil [Kejadian](https://docs.stripe.com/api/events.md) yang lebih lama dengan memanggil `/v1/events` menggunakan versi API yang lebih baru juga tidak memengaruhi struktur kejadian yang diterima. Anda dapat mengatur tujuan kejadian percobaan ke versi API default ataupun versi API terbaru. [Kejadian](https://docs.stripe.com/api/events.md) yang dikirim ke tujuan disusun untuk versi yang ditentukan tujuan kejadian. ## Praktik terbaik menggunakan webhook Tinjau praktik terbaik ini untuk memastikan endpoint webhook tetap aman dan berfungsi dengan baik bersama integrasi Anda. ### Tangani kejadian duplikat Terkadang endpoint webhook dapat menerima kejadian yang sama lebih dari satu kali. Anda dapat berhati-hati terhadap resi kejadian yang diduplikasi dengan memasukkan [identifikasi kejadian](https://docs.stripe.com/api/events/object.md#event_object-id) yang telah Anda proses, kemudian tidak memproses kejadian yang sudah dimasukkan. Dalam beberapa kasus, dua objek Event yang terpisah dihasilkan dan dikirim. Untuk mengidentifikasi duplikat tersebut, gunakan ID objek di `data.object` bersama dengan `event.type`. ### Hanya dengarkan tipe kejadian yang diperlukan oleh integrasi Anda Konfigurasikan endpoint webhook untuk hanya menerima tipe kejadian yang diperlukan oleh integrasi Anda. Mendengarkan kejadian ekstra (atau semua kejadian) akan membebani server Anda dan kami tidak merekomendasikannya. Anda dapat [mengubah kejadian](https://docs.stripe.com/api/webhook_endpoints/update.md#update_webhook_endpoint-enabled_events) yang diterima oleh endpoint webhook di Dashboard atau dengan API. ### Tangani kejadian secara asinkron Konfigurasikan handler Anda untuk memproses kejadian masuk dengan antrean asinkron. Anda mungkin mengalami masalah skalabilitas jika memilih untuk memproses kejadian secara sinkron. Setiap lonjakan besar dalam pengiriman webhook (misalnya, selama awal bulan ketika semua langganan diperbarui) dapat membanjiri host endpoint Anda. Antrean asinkron memungkinkan Anda memproses kejadian bersamaan dengan kecepatan yang dapat didukung sistem Anda. ### Bebaskan rute webhook dari proteksi CSRF Jika menggunakan Rails, Django, atau kerangka web lain, situs Anda dapat memeriksa secara otomatis apakah setiap permintaan POST berisi *CSRF token*. Ini adalah fitur keamanan penting yang membantu memproteksi Anda dan pengguna Anda dari upaya [cross-site request forgery](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_\(CSRF\)). Namun, langkah pengamanan ini juga dapat mencegah situs Anda memproses kejadian yang sah. Jika demikian, Anda mungkin perlu mengecualikan rute webhook dari proteksi CSRF. #### Rails ```ruby class StripeController < ApplicationController # If your controller accepts requests other than Stripe webhooks, # you'll probably want to use `protect_from_forgery` to add CSRF # protection for your application. But don't forget to exempt # your webhook route! protect_from_forgery except: :webhook def webhook # Process webhook data in `params` end end ``` ### Terima kejadian dengan server HTTPS Jika Anda menggunakan URL HTTPS untuk endpoint webhook (diperlukan dalam mode live), Stripe akan memvalidasi keamanan sambungan ke server Anda sebelum mengirim data webhook. Agar hal ini berfungsi, server Anda harus dikonfigurasi dengan benar untuk mendukung HTTPS dengan sertifikat server yang valid. Webhook Stripe hanya mendukung *TLS* (TLS refers to the process of securely transmitting data between the client—the app or browser that your customer is using—and your server. This was originally performed using the SSL (Secure Sockets Layer) protocol) versi v1.2 dan v1.3. ### Cabut rahasia penandatanganan endpoint secara berkala Rahasia yang digunakan untuk memverifikasi bahwa kejadian berasal dari Stripe dapat diubah pada tab **Webhook** di Workbench. Supaya tetap aman, kami merekomendasikan Anda mencabut (mengubah) rahasia secara berkala, atau bila Anda menduga terjadi peretasan kunci rahasia. Untuk mencabut rahasia: 1. Klik setiap endpoint di tab **Webhook** Workbench yang rahasianya ingin Anda cabut. 1. Masuk ke menu perluasan (⋯) dan klik **Cabut rahasia**. Anda dapat memilih untuk segera mengakhiri rahasia saat ini atau menunda kedaluwarsanya hingga 24 jam agar Anda memiliki waktu untuk memperbarui kode verifikasi di server Anda. Selama waktu ini, beberapa rahasia aktif bagi endpoint. Stripe membuat satu tanda tangan per rahasia hingga kedaluwarsa. ### Verifikasikan kejadian dikirim dari Stripe Tanpa verifikasi, penyerang dapat mengirim peristiwa webhook palsu ke endpoint Anda untuk memicu tindakan seperti memenuhi pesanan, memberikan akses akun, atau memodifikasi catatan. Selalu verifikasi bahwa peristiwa webhook berasal dari Stripe sebelum menindaklanjutinya. Gunakan kedua perlindungan ini: - **Daftar IP yang diizinkan**: Stripe mengirimkan peristiwa webhook dari daftar yang ditetapkan [alamat IP](https://docs.stripe.com/ips.md). Konfigurasikan server atau firewall Anda untuk hanya menerima permintaan webhook dari alamat ini. - **Verifikasi tanda tangan**: Stripe menandatangani setiap peristiwa webhook dengan menyertakan tanda tangan di `Tanda Tangan Stripe` header. Verifikasi tanda tangan ini menggunakan [perpustakaan Resmi](https://docs.stripe.com/webhooks.md#verify-official-libraries) atau [secara manual](https://docs.stripe.com/webhooks.md#verify-manually) untuk mengonfirmasi bahwa acara tersebut tidak dikirim atau dimodifikasi oleh pihak ketiga. Bagian berikut menerangkan cara memverifikasi tanda tangan webhook: 1. Ambil rahasia endpoint Anda. 1. Verifikasikan tanda tangan. #### Mengambil rahasia endpoint Anda Gunakan Workbench dan buka tab **Webhooks** untuk melihat semua endpoint Anda. Pilih endpoint yang ingin Anda dapatkan rahasianya, lalu klik **Klik untuk mengungkapkan**. Stripe membuatkan kunci rahasia yang unik bagi setiap endpoint. Jika Anda menggunakan endpoint yang sama untuk [kunci API percobaan maupun live](https://docs.stripe.com/keys.md#test-live-modes), rahasia untuk setiap kunci itu berbeda. Selain itu, jika menggunakan beberapa endpoint, Anda harus memperoleh rahasia untuk setiap kunci yang tanda tangannya ingin Anda verifikasi. Setelah persiapan ini, Stripe mulai menandatangani setiap webhook yang dikirim ke endpoint. ### Mencegah replay attack [Serangan replay](https://en.wikipedia.org/wiki/Replay_attack) adalah saat penyerang mencegat payload yang valid dan tanda tangannya, kemudian mengirimkannya kembali. Untuk melakukan mitigasi serangan semacam itu, Stripe menyertakan stempel waktu di tajuk `Stripe-Signature`. Karena merupakan bagian dari payload yang ditandatangani, stempel waktu ini juga diverifikasi oleh tanda tangan, sehingga penyerang tidak dapat mengubah stempel waktu tanpa membatalkan tanda tangan. Jika tanda tangan valid tetapi stempel waktu terlalu lama, aplikasi Anda dapat menolak payload. Pustaka kami memiliki toleransi default 5 menit antara stempel waktu dan waktu saat ini. Anda dapat mengubah toleransi ini dengan memberikan parameter tambahan ketika memverifikasi tanda tangan. Gunakan Network Time Protocol ([NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol)) untuk memastikan jam server Anda akurat dan sinkron dengan waktu pada server Stripe. > Jangan gunakan nilai toleransi `0`. Menggunakan nilai toleransi `0` menonaktifkan pemeriksaan kebaruan sepenuhnya. Stripe membuat stempel waktu dan tanda tangan setiap kali kami mengirim kejadian ke endpoint Anda. Jika Stripe mencoba ulang kejadian (misalnya endpoint Anda yang sebelumnya dibalas dengan kode status non-`2xx`), maka kami akan membuat tanda tangan dan stempel waktu baru untuk upaya pengiriman baru. ### Segera mengembalikan tanggapan 2xx [Endpoint](https://docs.stripe.com/webhooks.md#example-endpoint) Anda harus segera mengembalikan kode status (`2xx`) yang berhasil sebelum logika kompleks yang dapat menyebabkan waktu habis. Misalnya, Anda harus mengembalikan respons `200` sebelum memperbarui invoice pelanggan sebagai lunas di sistem akuntansi Anda. ## See also - [Kirim kejadian ke Amazon EventBridge](https://docs.stripe.com/event-destinations/eventbridge.md) - [Mengirim peristiwa ke Azure Event Grid](https://docs.stripe.com/event-destinations/eventgrid.md) - [Daftar tipe kejadian ringkas](https://docs.stripe.com/api/v2/core/events/event-types.md) - [Daftar jenis kejadian snapshot](https://docs.stripe.com/api/events/.md) - [Pembangun endpoint webhook interaktif](https://docs.stripe.com/webhooks/quickstart.md)