# Pembaruan status pembayaran

Pantau dan verifikasikan status pembayaran, sehingga Anda dapat merespons pembayaran yang berhasil dan gagal.

Pembaruan *PaymentIntents* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) sebagai respons atas tindakan yang diambil oleh pelanggan atau metode pembayaran. Integrasi Anda dapat memeriksa PaymentIntent untuk menentukan status proses pembayaran, sehingga Anda dapat mengambil tindakan bisnis atau merespons keadaan yang memerlukan intervensi lebih lanjut.

Anda juga dapat menggunakan Dashboard Stripe untuk mengonfigurasi akun untuk mengirim email tentang status pembayaran, seperti pembayaran yang berhasil. Ubah [notifikasi email](https://docs.stripe.com/get-started/account/teams.md#email-notifications) Anda di [pengaturan pengguna](https://dashboard.stripe.com/settings/user).

## Status pembayaran dan status PaymentIntent

Halaman [Payments](https://dashboard.stripe.com/payments) di Dashboard menampilkan status pembayaran untuk setiap pembayaran, yang dapat Anda gunakan untuk memfilter daftar. Status ini merangkum pembayaran tetapi tidak menyertakan detail tambahan yang disediakan oleh [status](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-status) PaymentIntent.

`status` PaymentIntent melacak status pembayaran dan menunjukkan kapan pembayaran memerlukan pemrosesan lebih lanjut atau tindakan pelanggan. Pembayaran yang menggunakan PaymentIntent mungkin memerlukan metode pembayaran, konfirmasi, atau tindakan lainnya agar berhasil. Di Dashboard, status ini dipetakan sebagai **Tidak Lengkap**.

Untuk memahami status pembayaran yang tidak lengkap, ketuk pembayaran dan gunakan [Workbench Inspector](https://docs.stripe.com/workbench/overview.md#inspector) untuk melihat detail PaymentIntent dalam bentuk JSON. Cari `status` untuk melihat nilai yang tepat.

Tabel berikut memetakan setiap `status` PaymentIntent ke status pembayaran di Dashboard. Kasus ekstrem seperti upaya yang kedaluwarsa dan kode gagal tertentu dapat memengaruhi pemetaan ini. Gunakan API atau Workbench Inspector untuk mendapatkan status otoritatif.

| `Status` PaymentIntent | Status pembayaran | Keterangan |
| --- | --- | --- |
| `requires_payment_method` | **Belum selesai** | Biasanya terjadi jika tidak ada [latest_charge](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-latest_charge) atau intent belum melewati penagihan. Bergantung pada metode pembayaran, jumlah, dan kesalahan, status pembayaran juga dapat berupa **Dibayar sebagian**, **Menunggu dana**, atau **Gagal**. |
| `requires_confirmation` | **Belum selesai** | Terjadi setelah pelanggan Anda memberikan informasi pembayaran dan siap untuk mengonfirmasi. Sebagian besar integrasi melewati status ini karena mereka mengirimkan informasi metode pembayaran saat pembayaran dikonfirmasi. |
| `requires_action` | **Belum selesai** | Terjadi saat pembayaran memerlukan tindakan tambahan, seperti autentikasi dengan [3D Secure](https://docs.stripe.com/payments/3d-secure.md). Status pembayaran di Dashboard juga dapat berupa **Dibayar sebagian**, **Menunggu dana**, atau **Gagal** pada kondisi autentikasi atau kesalahan tertentu. |
| `processing` | **Tertunda** | Terjadi saat tindakan yang diperlukan telah selesai dan pembayaran menggunakan *metode pembayaran asinkron* (Asynchronous payment methods can take up to several days to confirm whether the payment has been successful. During this time, the payment can't be guaranteed), seperti debit bank. Proses metode pembayaran ini dapat memakan waktu hingga beberapa hari. |
| `requires_capture` | **Tidak ditarik** atau **Penarikan sebagian** | Terjadi jika alur Anda menggunakan [penarikan terpisah](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md). Jika ada jumlah yang diterima untuk intent tersebut, statusnya adalah **Penarikan sebagian**. Jika tidak ada jumlah yang diterima, statusnya adalah **Tidak ditarik**. |
| `succeeded` | **Berhasil** | PaymentIntent dengan status `succeeded` berarti alur pembayaran terkait telah selesai. Dana ada di akun Anda dan Anda dapat memenuhi pesanan.

Jika upaya pembayaran gagal (misalnya, karena gagal), status PaymentIntent kembali ke `requires_payment_method` agar pembayaran dapat dicoba lagi.

Pengembalian dana, sengketa, dan hasil berikutnya tecermin pada Charge. Hal ini dapat mengubah apa yang Anda lihat di Dashboard, meskipun PaymentIntent tetap `succeeded`. |
| `canceled` | **Dibatalkan** | Terjadi saat pembayaran dibatalkan. Jika intent dibatalkan sebagai bagian dari alur Invoice yang gagal dan charge terakhir gagal, statusnya mungkin menampilkan **Gagal**. |

## Tangani tindakan selanjutnya

Beberapa metode pembayaran memerlukan langkah tambahan, seperti autentikasi, untuk menyelesaikan proses pembayaran. Stripe.js menanganinya secara otomatis saat mengonfirmasi PaymentIntent, tetapi jika Anda memiliki integrasi tingkat lanjut, Anda dapat menanganinya secara manual.

Properti [next_action](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action) PaymentIntent mengekspos langkah selanjutnya yang harus ditangani oleh integrasi Anda untuk menyelesaikan pembayaran. Tindakan selanjutnya yang tersedia bervariasi berdasarkan metode pembayaran. Untuk daftar lengkap, lihat [referensi API](https://docs.stripe.com/api.md#payment_intent_object-next_action-type).

Pelajari cara [menangani tindakan selanjutnya yang diperlukan untuk metode pembayaran](https://docs.stripe.com/payments/payment-methods/overview.md).

## Periksa status PaymentIntent di client

Saat menyelesaikan pembayaran pada client dengan fungsi [confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment), Anda dapat memeriksa PaymentIntent yang dikembalikan untuk menentukan status saat ini:

```javascript
(async () => {
  const {paymentIntent, error} = await stripe.confirmPayment({
    elements,
    confirmParams: {
      return_url: 'https://example.com/order/complete',
    },
    redirect: 'if_required',
  });
  if (error) {
    // Handle error here
  } else if (paymentIntent && paymentIntent.status === 'succeeded') {
    // Handle successful payment here
  }
})();
```

Berikut adalah kemungkinan hasil dari penggunaan fungsi `confirmPayment`:

| **Kejadian** | **Apa yang Terjadi** | **Perkiraan Integrasi** |
| --- | --- | --- |
| Diselesaikan dengan PaymentIntent | Pelanggan menyelesaikan pembayaran di halaman checkout Anda | Informasikan kepada pelanggan bahwa pembayaran mereka berhasil |
| Diselesaikan dengan kesalahan | Pembayaran pelanggan gagal di halaman checkout Anda | Tampilkan pesan kesalahan dan minta pelanggan Anda untuk mencoba pembayaran lagi |

Janji yang dikembalikan oleh `confirmPayment` diselesaikan saat proses pembayaran telah selesai atau gagal dengan error. Saat berhasil diselesaikan dan mengembalikan PaymentIntent, status selalu `berhasil` (atau `requires_capture` jika [menarik nanti](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)). Saat pembayaran memerlukan langkah tambahan seperti autentikasi, promise tidak terselesaikan hingga langkah tersebut selesai atau kehabisan waktu.

## Periksa status PaymentIntent pada client tanpa menggunakan confirmPayment

Untuk memeriksa status PaymentIntent tanpa menggunakan fungsi `confirmPayment`, ambil secara mandiri dengan menggunakan fungsi [retrievePaymentIntent](https://docs.stripe.com/js/payment_intents/retrieve_payment_intent) dan meneruskan *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)).

```javascript
(async () => {
  const {paymentIntent} = await stripe.retrievePaymentIntent(clientSecret);
  if (paymentIntent && paymentIntent.status === 'succeeded') {
    // Handle successful payment here
  } else {
    // Handle unsuccessful, processing, or canceled payments and API errors here
  }
})();
```

Berikut ini adalah beberapa [kemungkinan status](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-status) dari PaymentIntent setelah konfirmasi:

| **Apa yang Terjadi** | **Perkiraan Status PaymentIntent** |
| --- | --- |
| Pelanggan menyelesaikan pembayaran di halaman checkout Anda | `succeeded` |
| Pelanggan tidak menyelesaikan checkout | `requires_action` |
| Pembayaran pelanggan gagal di halaman checkout Anda | `requires_payment_method` |

[Baca lebih lanjut tentang status PaymentIntent](https://docs.stripe.com/payments/paymentintents/lifecycle.md).

## Pantau PaymentIntent dengan webhook

Stripe dapat mengirim kejadian *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) ke server Anda untuk memberitahukan bila status PaymentIntent berubah, yang dapat Anda gunakan untuk keperluan seperti penentuan kapan akan memenuhi barang dan layanan.

Jangan mencoba menangani *pemenuhan* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) pesanan di sisi client karena pelanggan dapat meninggalkan halaman setelah pembayaran selesai tetapi sebelum proses pemenuhan dimulai. Sebagai gantinya, gunakan webhook untuk memantau kejadian `payment_intent.succeeded` dan menangani penyelesaiannya secara asinkron, bukan mencoba memulai pemenuhan di sisi client.

> Anda dapat menggunakan polling alih-alih webhook untuk memantau perubahan yang disebabkan oleh operasi asinkron—mengambil PaymentIntent berulang kali untuk memeriksa statusnya—tetapi ini jauh kurang andal dan mungkin memicu batas kecepatan. Stripe memberlakukan [batas kecepatan](https://docs.stripe.com/testing.md#rate-limits) pada permintaan API, jadi berhati-hatilah jika Anda menggunakan polling.

Untuk menangani kejadian webhook, buat rute di server Anda dan konfigurasikan endpoint webhook yang sesuai [di Dashboard](https://dashboard.stripe.com/account/webhooks). Stripe mengirimkan kejadian `payment_intent.succeeded` bila pembayaran berhasil, dan kejadian `payment_intent.payment_failed` bila pembayaran gagal.

Payload webhook melampirkan objek PaymentIntent. Contoh berikut menunjukkan cara menangani kedua kejadian tersebut:

#### Ruby

```ruby
require 'sinatra'
require 'stripe'

post '/webhook' do
    payload = request.body.read
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
        event = Stripe::Webhook.construct_event(
            payload, sig_header, endpoint_secret
        )
    rescue JSON::ParserError => e
        # Invalid payload
        status 400
        return
    rescue Stripe::SignatureVerificationError => e
        # Invalid signature
        status 400
        return
    end

    case event['type']
    when 'payment_intent.succeeded'
        intent = event['data']['object']
        puts "Succeeded:", intent['id']
        # Fulfill the customer's purchase
    when 'payment_intent.payment_failed'
        intent = event['data']['object']
        error_message = intent['last_payment_error'] && intent['last_payment_error']['message']
        puts "Failed:", intent['id'], error_message
        # Notify the customer that payment failed
    end

    status 200
end
```

Bila pembayaran tidak berhasil, Anda dapat menemukan detail selengkapnya dengan memeriksa properti `last_payment_error` PaymentIntent. Anda dapat memberi tahu pelanggan bahwa pembayaran mereka belum selesai dan mendorong mereka untuk mencoba lagi dengan metode pembayaran yang berbeda. Gunakan kembali PaymentIntent yang sama untuk terus melacak pembelian pelanggan.

### Menangani kejadian webhook tertentu

Daftar berikut menerangkan cara menangani kejadian webhook:

| Kejadian | Keterangan | Langkah berikutnya |
| --- | --- | --- |
| `processing` | Pembayaran pelanggan berhasil dikirimkan ke Stripe. Hanya berlaku untuk metode pembayaran dengan [Konfirmasi keberhasilan yang tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification). | Tunggu pembayaran yang diprakarsai berhasil atau gagal. |
| `succeeded` | Pembayaran pelanggan berhasil. | Penuhi barang atau layanan yang dibeli. |
| `amount_capturable_updated` | Pembayaran pelanggan diotorisasi dan siap untuk penarikan | Tarik dana yang tersedia untuk pembayaran |
| `payment_failed` | Pembayaran pelanggan ditolak oleh jaringan kartu atau kedaluwarsa | Hubungi pelanggan Anda melalui email atau notifikasi otomatis dan minta mereka untuk memberikan metode pembayaran yang lain |

Untuk menguji webhook secara lokal, Anda dapat menggunakan [Stripe CLI](https://docs.stripe.com/cli.md). Setelah menginstalnya, Anda dapat meneruskan peristiwa ke server:

```bash
stripe listen --forward-to localhost:4242/webhook
Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit)
```

Pelajari selengkapnya tentang [penyiapan webhook](https://docs.stripe.com/webhooks.md).

## Mengidentifikasi charge di PaymentIntent

Bila Anda mencoba untuk menagih pembayaran dari pelanggan, PaymentIntent membuat [Charge](https://docs.stripe.com/api/charges.md). Untuk mendapatkan identifikasi charge terbaru, periksa properti [latest_charge](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-latest_charge) PaymentIntent:

#### 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>>')

intent = client.v1.payment_intents.retrieve('{{PAYMENT_INTENT_ID}}')
latest_charge = intent.latest_charge
```

Untuk melihat semua charge yang dikaitkan dengan PaymentIntent, termasuk charge yang tidak berhasil, [cantumkan semua charge](https://docs.stripe.com/api/charges/list.md#list_charges-payment_intent) dan tentukan parameter `payment_intent​`.

```curl
curl -G https://api.stripe.com/v1/charges \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "payment_intent={{PAYMENTINTENT_ID}}"
```
