# Handle payment events with webhooks

How to use webhooks to respond to offline payment events.

*Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) adalah endpoint HTTP yang menerima kejadian dari Stripe.

Webhook memungkinkan Anda diberi tahu tentang kejadian pembayaran di luar alur pembayaran seperti:

- Pembayaran yang berhasil (`payment_intent.succeeded`)
- Pembayaran yang disengketakan (`charge.dispute.created`)
- Saldo yang tersedia di akun Stripe Anda (`balance.available`)

Anda dapat menggunakan Dashboard untuk tindakan satu kali seperti mengembalikan dana pembayaran atau memperbarui informasi pelanggan, sementara webhook membantu Anda menskalakan integrasi pembayaran dan memproses kejadian bisnis penting dalam volume besar.

## Bangun webhook Anda sendiri

Anda dapat membuat webhook handler di server sendiri untuk mengelola semua alur pembayaran offline. Mulailah dengan mengungkapkan endpoint yang dapat menerima permintaan dari Stripe dan menggunakan CLI untuk mencoba integrasi secara lokal. Setiap permintaan dari Stripe berisi objek [Event](https://docs.stripe.com/api/events/object.md) dengan referensi ke objek di Stripe yang telah dimodifikasi.

## Buat endpoint webhook

Tambahkan endpoint baru di aplikasi Anda. Anda dapat bertindak atas kejadian tertentu dengan memeriksa bidang `type` objek kejadian yang dikirim dalam isi permintaan. Kemudian Anda dapat mencetak ke output standar untuk memastikan webhook berfungsi.

Mulai server Anda setelah menambahkan endpoint baru.

#### 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.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

require 'stripe'
require 'sinatra'
require 'json'

# Using the Sinatra framework
set :port, 4242

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

  # 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
```

## Instal dan siapkan Stripe CLI
Untuk opsi instalasi tambahan, lihat [Memulai Stripe CLI](https://docs.stripe.com/stripe-cli.md).
Setelah Anda menginstal Stripe CLI, jalankan `stripe login` di baris perintah untuk menghasilkan kode pemasangan yang akan ditautkan dengan akun Stripe Anda. Tekan **Enter** untuk membuka browser dan masuk ke akun Stripe Anda untuk mengizinkan akses. Kunci API yang dihasilkan berlaku selama 90 hari. Anda dapat mengubah atau menghapus kunci pada [Kunci API](https://dashboard.stripe.com/apikeys) di Dashboard.

> Anda dapat membuat konfigurasi khusus proyek dengan menyertakan bendera [–project-name](https://docs.stripe.com/cli/login#login-project-name) ketika masuk dan ketika menjalankan perintah untuk proyek tersebut.

Percobaan

```bash
stripe login
Your pairing code is: humour-nifty-finer-magic
Press Enter to open up the browser (^C to quit)
```

Jika Anda ingin menggunakan kunci API yang ada, gunakan tanda `--api-key`:

```bash
stripe login --api-key <<YOUR_SECRET_KEY>>
Your pairing code is: humour-nifty-finer-magic
Press Enter to open up the browser (^C to quit)
```

## Coba webhook Anda secara lokal

Gunakan CLI untuk meneruskan kejadian ke endpoint webhook lokal Anda menggunakan perintah `listen`.

Dengan asumsi aplikasi Anda berjalan di port 4242, jalankan:

```bash
stripe listen --forward-to http://localhost:4242/webhook
```

Di tab terminal yang berbeda, gunakan perintah CLI `trigger` untuk memicu kejadian webhook rekaan.

```bash
stripe trigger payment_intent.succeeded
```

Kejadian berikut ini muncul di tab `listen`:

```bash
[200 POST] OK payment_intent.succeeded
```

“PaymentIntent berhasil!” muncul di tab terminal yang menjalankan server Anda.

## Optional: Periksa tanda tangan webhook

Stripe menyertakan tanda tangan di setiap tajuk `Stripe-Signature`. Ini memungkinkan Anda memverifikasi bahwa kejadian dikirim oleh Stripe, dan bukan oleh pihak ketiga. Anda dapat memverifikasi tanda tangan baik menggunakan pustaka resmi kami, atau [verifikasikan tanda tangan secara manual](https://docs.stripe.com/webhooks.md#verify-manually) menggunakan solusi Anda sendiri.

Pertama, temukan webhook endpoint secret Anda dan tambahkan ke webhook handler sebagai `endpoint_secret`. Karena Anda masih menggunakan CLI Stripe untuk mengembangkan endpoint secara lokal, gunakan perintah `trigger` untuk mendapatkan webhook endpoint secret dari CLI.

```bash
stripe listen
```

Webhook endpoint secret dimulai dengan `whsec_` diikuti dengan serangkaian angka dan huruf. Jaga keamanan webhook endpoint secret ini dan jangan mengungkapkannya kepada umum.

#### 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.
client = Stripe::StripeClient.new('<<YOUR_SECRET_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
```

## Gunakan endpoint webhook Anda

Bila Anda siap menggunakan endpoint webhook ke produksi, Anda perlu melakukan:

1. Gunakan [kunci API mode live](https://docs.stripe.com/keys.md#test-live-modes) dan bukan kunci percobaan Anda.
1. Konfigurasikan endpoint webhook Anda di [Workbench](https://docs.stripe.com/workbench.md) atau dengan API.
1. Untuk mengkonfigurasi endpoint di Workbench, buka tab [Webhook](https://dashboard.stripe.com/workbench/webhooks).
1. Klik **Tambahkan tujuan** dan masukkan versi Stripe API dan acara tertentu yang ingin Anda terima dari Stripe. Klik **Lanjutkan** dan pilih **Endpoint webhook** dari daftar tipe tujuan yang tersedia. Klik **Lanjutkan** dan masukkan URL endpoint, nama opsional, dan deskripsi opsional. Klik **Buat tujuan**.
1. Ganti rahasia webhook endpoint dalam aplikasi dengan rahasia baru yang ditampilkan dalam tampilan detail tujuan di Workbench untuk endpoint Anda.

Aplikasi Anda kini siap menerima kejadian live. Untuk informasi selengkapnya tentang mengonfigurasi endpoint webhook Anda, lihat [Webhook Endpoint](https://docs.stripe.com/api/webhook_endpoints.md) API. Untuk percobaan di sandbox, [lihat panduan Pengembangan kami](https://docs.stripe.com/webhooks.md).
