# Simpan detail pembayaran selama pembayaran dalam aplikasi

Simpan detail pembayaran saat pembayaran di aplikasi seluler Anda.

# iOS

> This is a iOS for when platform is ios and mobile-ui is payment-element. View the full page at https://docs.stripe.com/payments/mobile/save-during-payment?platform=ios&mobile-ui=payment-element.

Gunakan [Payment Intents API](https://docs.stripe.com/api/payment_intents.md) untuk menyimpan detail pembayaran dari pembelian. Ada beberapa contoh penggunaan:

- Charge pelanggan untuk pesanan e-commerce dan menyimpan detailnya untuk pembelian di masa mendatang.
- Memulai pembayaran pertama dari serangkaian pembayaran rutin.
- Charge deposit dan simpan detailnya untuk menagih jumlah penuh nanti.

> #### Transaksi dengan kartu fisik
> 
> Transaksi dengan kartu fisik, seperti pembayaran melalui Stripe Terminal, menggunakan proses yang berbeda untuk menyimpan metode pembayaran. Untuk detailnya, lihat [dokumentasi Terminal](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md).

## Kepatuhan

Anda bertanggung jawab untuk mematuhi semua hukum, peraturan, dan aturan jaringan yang berlaku saat menyimpan detail pembayaran pelanggan untuk penggunaan di masa mendatang, seperti menampilkan metode pembayaran pelanggan kepada mereka dalam proses alur checkout untuk pembelian di masa mendatang atau menagih mereka saat mereka tidak aktif menggunakan situs web atau aplikasi Anda. Sebelum menyimpan atau menagih metode pembayaran pelanggan, pastikan Anda:

- Tambahkan ketentuan ke situs atau aplikasi Anda yang menyatakan bagaimana Anda berencana menyimpan detail metode pembayaran, seperti:
  - Perjanjian pelanggan yang memungkinkan Anda untuk memulai pembayaran atau serangkaian pembayaran atas nama mereka untuk transaksi tertentu.
  - Waktu dan frekuensi pembayaran yang diantisipasi (misalnya, jika charge untuk angsuran terjadwal, pembayaran langganan, atau penambahan saldo tidak terjadwal).
  - Cara Anda menentukan jumlah pembayaran.
  - Kebijakan pembatalan Anda, jika metode pembayarannya untuk layanan langganan.
- Gunakan metode pembayaran tersimpan hanya untuk tujuan yang tercantum dalam ketentuan Anda.
- Dapatkan persetujuan eksplisit dari pelanggan untuk penggunaan khusus ini. Sebagai contoh, sertakan kotak centang bertuliskan ‘Simpan metode pembayaran saya untuk penggunaan mendatang’.
- Catat perjanjian tertulis pelanggan Anda terhadap ketentuan Anda.

## Siapkan Stripe [Sisi server] [Sisi client]

Pertama, Anda membutuhkan akun Stripe. [Daftarkan sekarang juga](https://dashboard.stripe.com/register).

### Sisi server

Integrasi ini memerlukan endpoint di server Anda yang berinteraksi dengan Stripe API. Gunakan pustaka resmi kami untuk akses ke Stripe API dari server Anda:

#### Ruby

```bash
# Available as a gem
sudo gem install stripe
```

```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```

### Sisi client

[Stripe iOS SDK](https://github.com/stripe/stripe-ios) adalah sumber terbuka, yang [didokumentasikan lengkap](https://stripe.dev/stripe-ios/index.html), dan kompatibel dengan aplikasi yang mendukung iOS 13 ke atas.

#### Swift Package Manager

Untuk menginstal SDK, ikuti langkah-langkah ini:

1. Di Xcode, pilih **File** > **Tambahkan Dependensi Paket…** dan masukkan `https://github.com/stripe/stripe-ios-spm` sebagai URL repositori.
1. Pilih nomor versi terbaru dari [halaman rilis](https://github.com/stripe/stripe-ios/releases) kami.
1. Tambahkan produk **StripePaymentSheet** ke [target aplikasi Anda](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app).

#### CocoaPods

1. Jika Anda belum melakukannya, instal versi terbaru [CocoaPods](https://guides.cocoapods.org/using/getting-started.html).
1. Jika Anda tidak memiliki [Podfile](https://guides.cocoapods.org/syntax/podfile.html), jalankan perintah berikut untuk membuatnya:
   ```bash
   pod init
   ```
1. Tambahkan baris ini ke `Podfile` Anda:
   ```podfile
   pod 'StripePaymentSheet'
   ```
1. Jalankan perintah berikut:
   ```bash
   pod install
   ```
1. Jangan lupa menggunakan file `.xcworkspace` untuk membuka proyek Anda di Xcode, sebagai ganti file `.xcodeproj`, mulai sekarang.
1. Di masa mendatang, untuk memperbarui ke versi terbaru SDK, jalankan:
   ```bash
   pod update StripePaymentSheet
   ```

#### Carthage

1. Jika Anda belum melakukannya, instal versi terbaru [Carthage](https://github.com/Carthage/Carthage#installing-carthage).
1. Tambahkan baris ini ke `Cartfile` Anda:
   ```cartfile
   github "stripe/stripe-ios"
   ```
1. Ikuti [instruksi instalasi Carthage](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos). Pastikan untuk menyematkan semua framework yang diwajibkan yang tercantum [di sini](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking).
1. Di masa mendatang, untuk memperbarui ke versi terbaru SDK, jalankan perintah berikut:
   ```bash
   carthage update stripe-ios --platform ios
   ```

#### Kerangka Kerja Manual

1. Masuklah ke [halaman rilis GitHub](https://github.com/stripe/stripe-ios/releases/latest) kami lalu unduh dan unzip **Stripe.xcframework.zip**.
1. Seret **StripePaymentSheet.xcframework** ke bagian **Embedded Binaries** pengaturan **General** di proyek Xcode Anda. Pastikan memilih **Copy items if needed**.
1. Ulangi langkah 2 untuk semua framework yang diwajibkan yang tercantum [di sini](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking).
1. Di masa mendatang, untuk memperbarui ke versi terbaru SDK kami, ulangi langkah 1–3.

> Untuk detail mengenai rilis SDK terbaru dan versi sebelumnya, lihat halaman [Rilis](https://github.com/stripe/stripe-ios/releases) di GitHub. Untuk menerima notifikasi bila rilis baru diterbitkan, [lihat rilis](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository) untuk repositori.

## Aktifkan metode pembayaran

Pembayaran kartu diaktifkan secara default. Lihat [pengaturan metode pembayaran](https://dashboard.stripe.com/settings/payment_methods) Anda untuk mengaktifkan metode pembayaran lainnya yang ingin Anda dukung.

## Tambahkan endpoint [Sisi server]

> #### Catatan
> 
> Untuk menampilkan PaymentSheet sebelum membuat PaymentIntent, lihat [Kumpulkan detail pembayaran sebelum membuat Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment).

Integrasi ini menggunakan tiga objek API Stripe:

1. [PaymentIntent](https://docs.stripe.com/api/payment_intents.md): Stripe menggunakannya untuk mewakili maksud Anda menagih pembayaran dari pelanggan, yang melacak upaya charge dan perubahan status pembayaran selama proses.

1. Objek [Akun yang dikonfigurasi pelanggan](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-applied_configurations) atau [Pelanggan](https://docs.stripe.com/api/customers.md): Untuk menyiapkan metode pembayaran untuk pembayaran mendatang, Anda harus melampirkannya ke pelanggan. Buat objek yang mewakili pelanggan Anda saat mereka membuat akun di bisnis Anda. Jika pelanggan melakukan pembayaran sebagai tamu, Anda dapat membuat objek `Akun` atau `Pelanggan` sebelum pembayaran dan menghubungkannya dengan representasi internal akun pelanggan Anda nanti.

1. [CustomerSession](https://docs.stripe.com/api/customer_sessions.md): Informasi pada objek yang mewakili pelanggan Anda bersifat sensitif dan tidak dapat diambil langsung dari aplikasi. `CustomerSession` memberikan SDK akses berlingkup sementara ke `Akun` atau `Pelanggan` dan menyediakan opsi konfigurasi tambahan. Lihat daftar lengkap [opsi konfigurasi](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components).

Karena alasan keamanan, aplikasi Anda tidak dapat membuat objek ini. Sebagai gantinya, tambahkan endpoint di server Anda yang:

1. Mengambil `Akun` atau `Pelanggan`, atau membuat yang baru.
1. Membuat [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) untuk `Akun` atau `Pelanggan`.
1. Membuat `PaymentIntent` dengan [jumlah](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount), [mata uang](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency), [setup_future_usage](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-setup_future_usage), serta [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) atau [customer](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer).
1. Mengembalikan *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)) dari `PaymentIntent`, `client_secret` dari `CustomerSession`, ID dari `Akun` atau `Pelanggan`, dan [publishable key](https://dashboard.stripe.com/apikeys) Anda ke aplikasi.

> Payment Element seluler hanya mendukung `setup_future_usage` dengan rekening bank AS dan kartu.

Metode pembayaran yang ditampilkan kepada pelanggan selama proses checkout juga disertakan dalam PaymentIntent. Anda dapat mengizinkan Stripe menarik metode pembayaran dari pengaturan Dashboard atau Anda dapat mencantumkannya secara manual. Terlepas dari opsi yang Anda pilih, ketahui mata uang yang diteruskan di PaymentIntent memfilter metode pembayaran yang ditampilkan kepada pelanggan. Misalnya, jika Anda meneruskan `eur` pada PaymentIntent dan mengaktifkan OXXO di Dashboard, OXXO tidak akan ditampilkan kepada pelanggan karena OXXO tidak mendukung pembayaran `eur`.

Kecuali jika integrasi Anda memerlukan opsi berbasis kode untuk menawarkan metode pembayaran, Stripe merekomendasikan opsi otomatis. Hal ini karena Stripe mengevaluasi mata uang, pembatasan metode pembayaran, dan parameter lainnya untuk menentukan daftar metode pembayaran yang didukung. Metode pembayaran yang meningkatkan konversi serta yang paling relevan dengan mata uang dan lokasi pelanggan akan diprioritaskan.

#### Kelola metode pembayaran dari Dashboard

Anda dapat mengelola metode pembayaran dari [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe menangani pengembalian metode pembayaran yang memenuhi syarat berdasarkan faktor-faktor seperti jumlah transaksi, mata uang, dan alur pembayaran. PaymentIntent dibuat menggunakan metode pembayaran yang Anda konfigurasikan di Dashboard. Jika tidak ingin menggunakan Dashboard atau jika ingin menentukan metode pembayaran secara manual, Anda dapat mencantumkannya menggunakan atribut `payment_method_types`.

#### Akun v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

  -d "automatic_payment_methods[enabled]"=true \
```

#### Pelanggan v1

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create an CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

  -d "automatic_payment_methods[enabled]"=true \
```

#### Cantumkan metode pembayaran secara manual

#### Akun v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

#### Pelanggan v1

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create an CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

> Setiap metode pembayaran perlu mendukung mata uang yang diteruskan di PaymentIntent dan bisnis Anda perlu berlokasi di salah satu negara yang didukung oleh setiap metode pembayaran. Lihat halaman [Opsi integrasi metode pembayaran](https://docs.stripe.com/payments/payment-methods/integration-options.md) untuk detail selengkapnya tentang apa yang didukung.

## Kumpulkan detail pembayaran [Sisi client]

Untuk menampilkan Payment Element seluler pada layar checkout, pastikan Anda:

- Tampilkan produk yang dibeli pelanggan beserta jumlah totalnya
- Gunakan [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios) untuk mengumpulkan informasi pengiriman yang diperlukan dari pelanggan
- Tambahkan tombol checkout untuk menampilkan UI Stripe

#### UIKit

Di layar checkout aplikasi Anda, ambil rahasia klien PaymentIntent, rahasia klien CustomerSession, ID Pelanggan, dan kunci yang dapat dipublikasikan dari titik akhir yang Anda buat di langkah sebelumnya. Pakai `STPAPIClient.shared` untuk mengatur kunci yang dapat dipublikasikan dan menginisialisasi [Lembar Pembayaran](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html).

#### iOS (Swift)

```swift
import UIKit@_spi(CustomerSessionBetaAccess) import StripePaymentSheet

class CheckoutViewController: UIViewController {
  @IBOutlet weak var checkoutButton: UIButton!
  var paymentSheet: PaymentSheet?
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint

  override func viewDidLoad() {
    super.viewDidLoad()

    checkoutButton.addTarget(self, action: #selector(didTapCheckoutButton), for: .touchUpInside)
    checkoutButton.isEnabled = false

    // MARK: Fetch the PaymentIntent client secret, CustomerSession client secret, Customer ID, and publishable key
    var request = URLRequest(url: backendCheckoutUrl)
    request.httpMethod = "POST"
    let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
      guard let data = data,
            let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
            let customerId = json["customer"] as? String,
            let customerSessionClientSecret = json["customerSessionClientSecret"] as? String,
            let paymentIntentClientSecret = json["paymentIntent"] as? String,
            let publishableKey = json["publishableKey"] as? String,
            let self = self else {
        // Handle error
        return
      }
STPAPIClient.shared.publishableKey = publishableKey// MARK: Create a PaymentSheet instance
      var configuration = PaymentSheet.Configuration()
      configuration.merchantDisplayName = "Example, Inc."
      configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret)
      // Set `allowsDelayedPaymentMethods` to true if your business handles
      // delayed notification payment methods like US bank accounts.
      configuration.allowsDelayedPaymentMethods = true
      self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration)

      DispatchQueue.main.async {
        self.checkoutButton.isEnabled = true
      }
    })
    task.resume()
  }

}
```

Bila pelanggan mengetuk tombol **Checkout**, panggil `present` untuk menyajikan PaymentSheet. Setelah pelanggan menyelesaikan pembayaran, Stripe akan menutup PaymentSheet dan memanggil blok penyelesaian dengan [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html).

#### iOS (Swift)

```swift
@objc
func didTapCheckoutButton() {
  // MARK: Start the checkout process
  paymentSheet?.present(from: self) { paymentResult in
    // MARK: Handle the payment result
    switch paymentResult {
    case .completed:
      print("Your order is confirmed")
    case .canceled:
      print("Canceled!")
    case .failed(let error):
      print("Payment failed: \(error)")
    }
  }
}
```

#### SwiftUI

Buat model `ObservableObject` untuk layar checkout Anda. Model ini menerbitkan [PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) dan [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html).

```swift
import StripePaymentSheet
import SwiftUI

class CheckoutViewModel: ObservableObject {
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint
  @Published var paymentSheet: PaymentSheet?
  @Published var paymentResult: PaymentSheetResult?
}
```

Ambil rahasia klien PaymentIntent, rahasia klien CustomerSession, ID Pelanggan, dan kunci yang dapat diterbitkan dari titik akhir yang Anda buat di langkah sebelumnya. Pakai `STPAPIClient.shared` untuk mengatur kunci yang dapat dipublikasikan dan menginisialisasi [Lembar Pembayaran](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html).

```swift
@_spi(CustomerSessionBetaAccess) import StripePaymentSheet
import SwiftUI

class CheckoutViewModel: ObservableObject {
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint
  @Published var paymentSheet: PaymentSheet?
  @Published var paymentResult: PaymentSheetResult?
func preparePaymentSheet() {
    // MARK: Fetch thePaymentIntent and Customer information from the backend
    var request = URLRequest(url: backendCheckoutUrl)
    request.httpMethod = "POST"
    let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
      guard let data = data,
            let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
            let customerId = json["customer"] as? String,
            let customerSessionClientSecret = json["customerSessionClientSecret"] as? String,
            letpaymentIntentClientSecret = json["paymentIntent"] as? String,
            let publishableKey = json["publishableKey"] as? String,
            let self = self else {
        // Handle error
        return
      }

      STPAPIClient.shared.publishableKey = publishableKey// MARK: Create a PaymentSheet instance
      var configuration = PaymentSheet.Configuration()
      configuration.merchantDisplayName = "Example, Inc."
      configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret)
      // Set `allowsDelayedPaymentMethods` to true if your business handles
      // delayed notification payment methods like US bank accounts.
      configuration.allowsDelayedPaymentMethods = true

      DispatchQueue.main.async {
        self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration)
      }
    })
    task.resume()
  }
}
struct CheckoutView: View {
  @ObservedObject var model = CheckoutViewModel()

  var body: some View {
    VStack {
      if model.paymentSheet != nil {
        Text("Ready to pay.")
      } else {
        Text("Loading…")
      }
    }.onAppear { model.preparePaymentSheet() }
  }
}
```

Tambahkan [PaymentSheet.PaymentButton](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/PaymentButton.html) ke `View`. Ini berperilaku mirip dengan `Button` SwiftUI, yang memungkinkan Anda menyesuaikannya dengan menambahkan `View`. Ketika Anda mengetuk tombol, itu akan menampilkan PaymentSheet. Setelah Anda menyelesaikan pembayaran, Stripe akan menutup PaymentSheet dan memanggil handler `onCompletion` dengan objek [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html).

```swift
@_spi(CustomerSessionBetaAccess) import StripePaymentSheet
import SwiftUI

class CheckoutViewModel: ObservableObject {
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint
  @Published var paymentSheet: PaymentSheet?
  @Published var paymentResult: PaymentSheetResult?

  func preparePaymentSheet() {
    // MARK: Fetch the PaymentIntent and Customer information from the backend
    var request = URLRequest(url: backendCheckoutUrl)
    request.httpMethod = "POST"
    let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
      guard let data = data,
            let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
            let customerId = json["customer"] as? String,
            let customerSessionClientSecret = json["customerSessionClientSecret"] as? String,
            let paymentIntentClientSecret = json["paymentIntent"] as? String,
            let publishableKey = json["publishableKey"] as? String,
            let self = self else {
        // Handle error
        return
      }

      STPAPIClient.shared.publishableKey = publishableKey
      // MARK: Create a PaymentSheet instance
      var configuration = PaymentSheet.Configuration()
      configuration.merchantDisplayName = "Example, Inc."
      configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret)
      // Set `allowsDelayedPaymentMethods` to true if your business can handle payment methods
      // that complete payment after a delay, like SEPA Debit and Sofort.
      configuration.allowsDelayedPaymentMethods = true

      DispatchQueue.main.async {
        self.paymentSheet = PaymentSheet(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration)
      }
    })
    task.resume()
  }
func onPaymentCompletion(result: PaymentSheetResult) {
    self.paymentResult = result
  }
}

struct CheckoutView: View {
  @ObservedObject var model = CheckoutViewModel()

  var body: some View {
    VStack {if let paymentSheet = model.paymentSheet {
        PaymentSheet.PaymentButton(
          paymentSheet: paymentSheet,
          onCompletion: model.onPaymentCompletion
        ) {
          Text("Buy")
        }
      } else {
        Text("Loading…")
      }if let result = model.paymentResult {
        switch result {
        case .completed:
          Text("Payment complete")
        case .failed(let error):
          Text("Payment failed: \(error.localizedDescription)")
        case .canceled:
          Text("Payment canceled.")
        }
      }
    }.onAppear { model.preparePaymentSheet() }
  }
}
```

Jika `PaymentSheetResult` adalah `.completed`, informasikan pengguna (misalnya, dengan menampilkan layar konfirmasi pesanan).

Mengatur `allowsDelayedPaymentMethods` ke true memungkinkan metode pembayaran [pemberitahuan tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification) seperti rekening bank AS. Untuk metode pembayaran ini, status pembayaran finalnya tidak diketahui bila `PaymentSheet` selesai, dan berhasil atau gagal sebagai gantinya nanti. Jika Anda mendukung jenis pembayaran ini, informasikan kepada pelanggan bahwa pesanannya telah dikonfirmasi dan hanya memenuhi pesanan (misalnya, mengirim produknya) bila pembayaran berhasil.

## Siapkan URL kembali [Sisi client]

Pelanggan dapat keluar dari aplikasi Anda untuk melakukan autentikasi (misalnya, di Safari atau aplikasi perbankannya). Untuk mengizinkan pelanggan kembali secara otomatis ke aplikasi Anda setelah mengautentikasi, [konfigurasikan skema URL custom](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) dan siapkan delegasi aplikasi Anda untuk meneruskan URL ke SDK. Stripe tidak mendukung [tautan universal](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content).

#### SceneDelegate

#### Swift

```swift
// This method handles opening custom URL schemes (for example, "your-app://stripe-redirect")
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else {
        return
    }
    let stripeHandled = StripeAPI.handleURLCallback(with: url)
    if (!stripeHandled) {
        // This was not a Stripe url – handle the URL normally as you would
    }
}

```

#### AppDelegate

#### Swift

```swift
// This method handles opening custom URL schemes (for example, "your-app://stripe-redirect")
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    let stripeHandled = StripeAPI.handleURLCallback(with: url)
    if (stripeHandled) {
        return true
    } else {
        // This was not a Stripe url – handle the URL normally as you would
    }
    return false
}
```

#### SwiftUI

#### Swift

```swift

@main
struct MyApp: App {
  var body: some Scene {
    WindowGroup {
      Text("Hello, world!").onOpenURL { incomingURL in
          let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL)
          if (!stripeHandled) {
            // This was not a Stripe url – handle the URL normally as you would
          }
        }
    }
  }
}
```

Selain itu, atur [returnURL](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV9returnURLSSSgvp) pada objek [PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) ke URL untuk aplikasi Anda.

```swift
var configuration = PaymentSheet.Configuration()
configuration.returnURL = "your-app://stripe-redirect"
```

## Tangani kejadian pasca-pembayaran [Sisi server]

Stripe mengirim kejadian [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) ketika selesai pembayaran. Gunakan [alat webhook Dashboard](https://dashboard.stripe.com/webhooks) atau ikuti [panduan webhook](https://docs.stripe.com/webhooks/quickstart.md) untuk menerima kejadian ini dan menjalankan tindakan, seperti mengirim email konfirmasi pesanan kepada pelanggan Anda, mencatat penjualan di database, atau memulai alur kerja pengiriman.

Dengarkan kejadian ini daripada menunggu callback dari client. Di client, pelanggan dapat menutup jendela browser atau keluar dari aplikasi sebelum callback mengeksekusi, dan klien jahat dapat memanipulasi respons. Penyiapan integrasi untuk mendengarkan kejadian asinkron memungkinkan Anda menyetujui [berbagai tipe metode pembayaran](https://stripe.com/payments/payment-methods-guide) dengan satu integrasi tunggal.

Selain menangani kejadian `payment_intent.succeeded`, kami merekomendasikan penanganan kejadian ini yang lain ketika menagih pembayaran dengan Payment Element:

| Kejadian                                                                                                                        | Keterangan                                                                                                                                                                                                                                                                                 | Tindakan                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | Dikirim bila pelanggan berhasil menyelesaikan pembayaran.                                                                                                                                                                                                                                  | Kirimi pelanggan konfirmasi pesanan dan *penuhi* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) pesanan mereka.     |
| [payment_intent. pemrosesan](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)        | Dikirim bila pelanggan berhasil memprakarsai pembayaran, tetapi pembayaran itu belum selesai. Kejadian ini paling umum dikirim saat pelanggan memprakarsai debit bank. Kejadian diikuti dengan kejadian `payment_intent.succeeded` atau `payment_intent.payment_failed` di masa mendatang. | Kirimi pelanggan konfirmasi pesanan yang menunjukkan bahwa pembayaran mereka menunggu penyelesaian. Untuk barang digital, Anda mungkin ingin memenuhi pesanan sebelum menunggu pembayaran selesai. |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Dikirim bila pelanggan mencoba melakukan pembayaran, tetapi pembayaran itu gagal.                                                                                                                                                                                                          | Jika transisi pembayaran dilakukan dari `processing` menjadi `payment_failed`, tawarkan upaya lain untuk membayar kepada pelanggan.                                                                |

## Charge Metode Pembayaran tersimpan nanti [Sisi server]

> #### Kepatuhan
> 
> Anda bertanggung jawab atas kepatuhan terhadap semua hukum, peraturan, dan aturan jaringan yang berlaku saat menyimpan detail pembayaran pelanggan. Saat menampilkan metode pembayaran sebelumnya kepada pelanggan akhir untuk pembelian di masa mendatang, pastikan Anda mencantumkan metode pembayaran yang telah mendapatkan persetujuan dari pelanggan untuk menyimpan detail metode pembayaran untuk penggunaan khusus di masa mendatang. Untuk membedakan antara metode pembayaran yang dilampirkan pada pelanggan yang dapat dan tidak dapat ditampilkan kepada pelanggan akhir Anda sebagai metode pembayaran tersimpan untuk pembelian di masa mendatang, gunakan parameter [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

Untuk menemukan metode pembayaran yang akan ditagih, buatlah daftar metode pembayaran yang terkait dengan pelanggan Anda. Contoh ini menampilkan daftar kartu, namun Anda dapat mencantumkan [jenis](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) apa pun yang didukung.

> #### Menggunakan API Akun v2 untuk mewakili pelanggan
> 
> API Akun v2 umumnya tersedia untuk pengguna Connect, dan dalam pratinjau publik untuk pengguna Stripe lainnya. Jika Anda adalah bagian dari pratinjau Akun v2, Anda perlu menentukan [Tentukan versi pratinjau](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) dalam kode Anda.
> 
> Untuk meminta akses ke pratinjau Akun v2, 
> 
> Untuk sebagian besar contoh penggunaan, sebaiknya Anda [memodelkan pelanggan Anda sebagai objek Account yang dikonfigurasi pelanggan](https://docs.stripe.com/connect/use-accounts-as-customers.md) alih-alih menggunakan [Customer](https://docs.stripe.com/api/customers.md) objek.

#### Akun v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d type=card
```

#### Pelanggan v1

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d type=card
```

Saat Anda siap untuk menagih pelanggan secara off-session**, gunakan ID pelanggan dan ID `PaymentMethod` untuk membuat `PaymentIntent` dengan jumlah dan mata uang pembayaran yang sesuai. Atur beberapa parameter lainnya untuk melakukan pembayaran di luar sesi (off-session):

- Atur [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) ke `true` untuk menunjukkan bahwa pelanggan tidak berada dalam alur checkout Anda saat percobaan pembayaran dilakukan dan tidak dapat memenuhi permintaan autentikasi dari mitra, seperti penerbit kartu, bank, atau lembaga pembayaran lainnya. Jika mitra meminta autentikasi selama alur checkout, Stripe akan meminta pengecualian (exemption) menggunakan informasi pelanggan dari transaksi on-session** sebelumnya. Jika kondisi untuk pengecualian tidak terpenuhi, `PaymentIntent` mungkin akan menghasilkan kesalahan (error).
- Atur nilai properti [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) pada `PaymentIntent` ke true, agar konfirmasi terjadi segera setelah `PaymentIntent` dibuat.
- Atur [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) ke ID `PaymentMethod`.
- Bergantung pada cara Anda merepresentasikan pelanggan dalam integrasi Anda, atur [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) ke ID `Account` yang dikonfigurasi untuk pelanggan atau atur [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) ke ID `Customer`.

#### Akun v2

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

#### Pelanggan v1

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

## Uji integrasinya

#### Kartu

| Metode pembayaran | Skenario                                                                                                                                                                                                                                                                                                       | Cara mencoba                                                                                                                                    |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Kartu kredit      | Penyiapan kartu berhasil dan tidak memerlukan *autentikasi* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Isilah formulir kartu kredit menggunakan nomor kartu kredit `4242 4242 4242 4242` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos.      |
| Kartu kredit      | Kartu ini memerlukan autentikasi untuk penyiapan awal, kemudian berhasil untuk pembelian berikutnya.                                                                                                                                                                                                           | Isilah formulir kartu kredit kami menggunakan nomor kartu kredit `4000 0025 0000 3155` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos. |
| Kartu kredit      | Kartu ini memerlukan autentikasi untuk penyiapan awal dan juga memerlukan autentikasi untuk pembelian berikutnya.                                                                                                                                                                                              | Isilah formulir kartu kredit kami menggunakan nomor kartu kredit `4000 0027 6000 3184` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos. |
| Kartu kredit      | Kartu ini ditolak selama penyiapan.                                                                                                                                                                                                                                                                            | Isilah formulir kartu kredit menggunakan nomor kartu kredit `4000 0000 0000 9995` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos.      |

## Optional: Aktifkan Apple Pay

> Jika layar checkout Anda memiliki **tombol Apple Pay** khusus, ikuti [panduan Apple Pay](https://docs.stripe.com/apple-pay.md#present-payment-sheet) dan gunakan `ApplePayContext` untuk menagih pembayaran dari tombol Apple Pay. Anda dapat menggunakan `PaymentSheet` untuk menangani tipe metode pembayaran lainnya.

### Mendaftar Apple Merchant ID

Dapatkan Apple Merchant ID dengan [mendaftar identifier baru](https://developer.apple.com/account/resources/identifiers/add/merchant) di situs web Apple Developer.

Isi formulir dengan keterangan dan identifier. Keterangan adalah untuk catatan Anda sendiri dan nanti dapat diubah. Stripe merekomendasikan penggunaan nama aplikasi Anda sebagai identifier (misalnya, `merchant.com.{{YOUR_APP_NAME}}`).

### Buat sertifikat Apple Pay yang baru

Buat sertifikat untuk aplikasi Anda guna mengenkripsi data pembayaran.

Buka [Pengaturan Sertifikat iOS](https://dashboard.stripe.com/settings/ios_certificates) di Dashboard, klik **Tambahkan aplikasi baru**, dan ikuti panduannya.

Unduh file Permintaan Penandatanganan Sertifikat (CSR) untuk mendapatkan sertifikat aman dari Apple yang memungkinkan Anda menggunakan Apple Pay.

Satu file CSR harus digunakan untuk menerbitkan tepat satu sertifikat. Jika Anda mengganti Apple Merchant ID, Anda harus membuka [Pengaturan Sertifikat iOS](https://dashboard.stripe.com/settings/ios_certificates) di Dashboard untuk mendapatkan CSR dan sertifikat baru.

### Integrasikan dengan Xcode

Tambahkan kemampuan Apple Pay ke aplikasi Anda. Di Xcode, buka pengaturan proyek, klik tab **Signing & Capabilities**, dan tambahkan kemampuan **Apple Pay**. Pada saat ini Anda mungkin diminta untuk masuk ke akun pengembang. Pilih identifikasi merchant yang Anda buat sebelumnya, dan aplikasi Anda siap menyetujui Apple Pay.
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

Aktifkan kemampuan Apple Pay di Xcode

### Tambahkan Apple Pay

#### Pembayaran satu kali

Untuk menambahkan Apple Pay ke PaymentSheet, atur [applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) setelah memprakarsai `PaymentSheet.Configuration` dengan identitas merchant Apple dan [kode negara bisnis Anda](https://dashboard.stripe.com/settings/account).

#### iOS (Swift)

```swift
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(
  merchantId: "merchant.com.your_app_name",
  merchantCountryCode: "US"
)
```

#### Pembayaran rutin

Untuk menambahkan Apple Pay ke PaymentSheet, atur [applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) setelah memprakarsai `PaymentSheet.Configuration` dengan identitas merchant Apple dan [kode negara bisnis Anda](https://dashboard.stripe.com/settings/account).

Sesuai [pedoman Apple](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) untuk pembayaran rutin, Anda juga harus mengatur atribut tambahan pada `PKPaymentRequest`. Tambahkan handler di [ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) untuk mengonfigurasi [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) dengan jumlah yang ingin Anda charge (misalnya, 9,95 USD sebulan).

Anda juga dapat mengadopsi [token merchant](https://developer.apple.com/apple-pay/merchant-tokens/) dengan mengatur properti `recurringPaymentRequest` atau `automaticReloadPaymentRequest` di `PKPaymentRequest`.

Untuk mempelajari lebih lanjut tentang cara menggunakan pembayaran rutin dengan Apple Pay, lihat [dokumentasi PassKit Apple](https://developer.apple.com/documentation/passkit/pkpaymentrequest).

#### iOS (Swift)

```swift
let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers(
    paymentRequestHandler: { request in
        // PKRecurringPaymentSummaryItem is available on iOS 15 or later
        if #available(iOS 15.0, *) {
            let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99"))

            // Payment starts today
            billing.startDate = Date()

            // Payment ends in one year
            billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365)

            // Pay once a month.
            billing.intervalUnit = .month
            billing.intervalCount = 1

            // recurringPaymentRequest is only available on iOS 16 or later
            if #available(iOS 16.0, *) {
                request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring",
                                                                            regularBilling: billing,
                                                                            managementURL: URL(string: "https://my-backend.example.com/customer-portal")!)
                request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'"
            }
            request.paymentSummaryItems = [billing]
            request.currencyCode = "USD"
        } else {
            // On older iOS versions, set alternative summary items.
            request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)]
        }
        return request
    }
)
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(merchantId: "merchant.com.your_app_name",
                                merchantCountryCode: "US",
                                customHandlers: customHandlers)
```

### Pelacakan pesanan

Untuk menambahkan informasi [pelacakan pesanan](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) di iOS 16 atau yang lebih baru, konfigurasikan [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) di `PaymentSheet.ApplePayConfiguration.Handlers` Anda. Stripe memanggil implementasi Anda setelah pembayaran selesai, tetapi sebelum iOS menutup lembar Apple Pay.

Dalam penerapan `authorizationResultHandler` Anda, ambil detail pesanan dari server Anda untuk pesanan yang selesai. Tambahkan detailnya ke [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) yang diberikan dan kembalikan hasil yang diubah.

Untuk mempelajari selengkapnya tentang pelacakan pesanan, lihat [dokumentasi Pesanan Dompet Apple](https://developer.apple.com/documentation/walletorders).

#### iOS (Swift)

```swift
let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers(
    authorizationResultHandler: { result in
      do {
        // Fetch the order details from your service
        let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID)
        result.orderDetails = PKPaymentOrderDetails(
          orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order"
          orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111"
          webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend"
          authenticationToken: myOrderDetails.authenticationToken) // "abc123"
        // Return your modified PKPaymentAuthorizationResult
        return result
      } catch {
        return PKPaymentAuthorizationResult(status: .failure, errors: [error])
      }
    }
)
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(merchantId: "merchant.com.your_app_name",
                               merchantCountryCode: "US",
                               customHandlers: customHandlers)
```

## Aktifkan pemindaian kartu

Untuk mengaktifkan dukungan pemindaian kartu untuk iOS, atur `NSCameraUsageDescription` (**Privacy - Camera Usage Description**) di dalam `Info.plist` aplikasi Anda, dan berikan alasan untuk mengakses kamera (misalnya, “Untuk memindai kartu”).

## Optional: Sesuaikan lembar

Semua penyesuaian dikonfigurasi melalui objek [PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html).

### Penampilan

Sesuaikan warna, font, dan sebagainya agar sesuai dengan tampilan dan nuansa aplikasi Anda dengan menggunakan [appearance API](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios).

### Tata letak metode pembayaran

Konfigurasikan tata letak metode pembayaran di lembaran menggunakan [paymentMethodLayout](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/configuration-swift.struct/paymentmethodlayout). Anda dapat menampilkannya secara horizontal, vertikal, atau membiarkan Stripe mengoptimalkan tata letak secara otomatis.
![](https://b.stripecdn.com/docs-statics-srv/assets/ios-mpe-payment-method-layouts.9d0513e2fcec5660378ba1824d952054.png)

#### Swift

```swift
var configuration = PaymentSheet.Configuration()
configuration.paymentMethodLayout = .automatic
```

### Kumpulkan alamat pengguna

Kumpulkan alamat tagihan atau pengiriman lokal dan internasional dari pelanggan Anda menggunakan [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios).

### Nama tampilan merchant

Tentukan nama bisnis yang dilihat pelanggan dengan mengatur [merchantDisplayName](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:18StripePaymentSheet0bC0C13ConfigurationV19merchantDisplayNameSSvp). Secara default, ini adalah nama aplikasi Anda.

#### Swift

```swift
var configuration = PaymentSheet.Configuration()
configuration.merchantDisplayName = "My app, Inc."
```

### Mode gelap

`PaymentSheet` secara otomatis beradaptasi dengan pengaturan penampilan skala-sistem pengguna (mode terang dan gelap). Jika aplikasi tidak mendukung mode gelap, Anda dapat mengatur [gaya](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:18StripePaymentSheet0bC0C13ConfigurationV5styleAC18UserInterfaceStyleOvp) ke mode `alwaysLight` atau `alwaysDark`.

```swift
var configuration = PaymentSheet.Configuration()
configuration.style = .alwaysLight
```

### Detail tagihan default

Untuk mengatur nilai default bagi detail tagihan yang dikumpulkan di lembar pembayaran, konfigurasikan properti `defaultBillingDetails`. `PaymentSheet` akan melengkapi bidang-bidangnya dengan nilai yang Anda berikan.

```swift
var configuration = PaymentSheet.Configuration()
configuration.defaultBillingDetails.address.country = "US"
configuration.defaultBillingDetails.email = "foo@bar.com"
```

### Pengumpulan detail tagihan

Gunakan `billingDetailsCollectionConfiguration` untuk menentukan cara Anda ingin mengumpulkan detail tagihan di lembar pembayaran.

Anda dapat mengumpulkan nama, email, nomor telepon, dan alamat pelanggan.

Jika Anda hanya ingin detail tagihan yang diperlukan oleh metode pembayaran, atur `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` ke true. Dalam hal ini, `PaymentSheet.Configuration.defaultBillingDetails` diatur sebagai [detail tagihan](https://docs.stripe.com/api/payment_methods/object.md?lang=node#payment_method_object-billing_details) metode pembayaran.

Jika Anda ingin mengumpulkan detail tagihan tambahan yang tidak diperlukan oleh metode pembayaran, atur `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` ke false. Dalam hal ini, detail tagihan yang dikumpulkan melalui `PaymentSheet` ditetapkan sebagai detail tagihan metode pembayaran.

```swift
var configuration = PaymentSheet.Configuration()
configuration.defaultBillingDetails.email = "foo@bar.com"
configuration.billingDetailsCollectionConfiguration.name = .always
configuration.billingDetailsCollectionConfiguration.email = .never
configuration.billingDetailsCollectionConfiguration.address = .full
configuration.billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod = true
```

> Konsultasikan dengan penasihat hukum mengenai undang-undang yang berlaku untuk mengumpulkan informasi. Hanya kumpulkan nomor telepon jika Anda memerlukannya untuk transaksi.

## Optional: Selesaikan pembayaran di UI Anda

Anda dapat menyajikan Lembar Pembayaran untuk hanya mengumpulkan detail metode pembayaran, kemudian memanggil metode `confirm` untuk menyelesaikan pembayaran di UI aplikasi Anda. Hal ini akan berguna jika Anda memiliki tombol beli custom atau memerlukan langkah tambahan setelah mengumpulkan detail pembayaran.
![](https://b.stripecdn.com/docs-statics-srv/assets/ios-multi-step.cd631ea4f1cd8cf3f39b6b9e1e92b6c5.png)

Selesaikan pembayaran di UI aplikasi Anda

#### UIKit

Langkah-langkah berikut memandu Anda menyelesaikan pembayaran di UI aplikasi. Lihat sampel integrasi kami di [GitHub](https://github.com/stripe/stripe-ios/blob/master/Example/PaymentSheet%20Example/PaymentSheet%20Example/ExampleCustomCheckoutViewController.swift).

1. Pertama, lakukan inisialisasi [PaymentSheet.FlowController](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller), bukan `PaymentSheet`, serta perbarui UI Anda dengan properti `paymentOption`. Properti ini berisi gambar dan label yang menunjukkan metode pembayaran default yang dipilih pertama kali oleh pelanggan.

```swift
PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) { [weak self] result in
  switch result {
  case .failure(let error):
    print(error)
  case .success(let paymentSheetFlowController):
    self?.paymentSheetFlowController = paymentSheetFlowController
    // Update your UI using paymentSheetFlowController.paymentOption
  }
}
```

1. Berikutnya, panggil `presentPaymentOptions` untuk mengumpulkan detail pembayaran. Setelah selesai, perbarui UI Anda lagi dengan properti `paymentOption`.

```swift
paymentSheetFlowController.presentPaymentOptions(from: self) {
  // Update your UI using paymentSheetFlowController.paymentOption
}
```

1. Terakhir, panggil `confirm`.

```swift
paymentSheetFlowController.confirm(from: self) { paymentResult in
  // MARK: Handle the payment result
  switch paymentResult {
  case .completed:
    print("Payment complete!")
  case .canceled:
    print("Canceled!")
  case .failed(let error):
    print(error)
  }
}
```

#### SwiftUI

Langkah-langkah berikut memandu Anda menyelesaikan pembayaran di UI aplikasi. Lihat sampel integrasi kami di [GitHub](https://github.com/stripe/stripe-ios/blob/master/Example/PaymentSheet%20Example/PaymentSheet%20Example/ExampleSwiftUICustomPaymentFlow.swift).

1. Pertama, lakukan inisialisasi [PaymentSheet.FlowController](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller), bukan `PaymentSheet`. Propertinya `paymentOption` berisi gambar dan label yang menunjukkan metode pembayaran pilihan pelanggan saat ini, yang dapat Anda gunakan di UI.

```swift
PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) { [weak self] result in
  switch result {
  case .failure(let error):
    print(error)
  case .success(let paymentSheetFlowController):
    self?.paymentSheetFlowController = paymentSheetFlowController
    // Use the paymentSheetFlowController.paymentOption properties in your UI
    myPaymentMethodLabel = paymentSheetFlowController.paymentOption?.label ?? "Select a payment method"
    myPaymentMethodImage = paymentSheetFlowController.paymentOption?.image ?? UIImage(systemName: "square.and.pencil")!
  }
}
```

1. Gunakan [PaymentSheet.FlowController.PaymentOptionsButton](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptionsbutton) untuk membungkus tombol yang menyajikan lembaran guna mengumpulkan detail pembayaran. Saat `PaymentSheet.FlowController` memanggil argumen `onSheetDismissed`, `paymentOption` untuk instance `PaymentSheet.FlowController` mencerminkan metode pembayaran yang saat ini dipilih.

```swift
PaymentSheet.FlowController.PaymentOptionsButton(
  paymentSheetFlowController: paymentSheetFlowController,
  onSheetDismissed: {
    myPaymentMethodLabel = paymentSheetFlowController.paymentOption?.label ?? "Select a payment method"
    myPaymentMethodImage = paymentSheetFlowController.paymentOption?.image ?? UIImage(systemName: "square.and.pencil")!
  },
  content: {
    /* An example button */
    HStack {
      Text(myPaymentMethodLabel)
      Image(uiImage: myPaymentMethodImage)
    }
  }
)
```

1. Gunakan [PaymentSheet.FlowController.PaymentOptionsButton](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptionsbutton) untuk membungkus tombol yang mengonfirmasi pembayaran.

```swift
PaymentSheet.FlowController.ConfirmButton(
  paymentSheetFlowController: paymentSheetFlowController,
  onCompletion: { result in
    // MARK: Handle the payment result
    switch result {
    case .completed:
      print("Payment complete!")
    case .canceled:
      print("Canceled!")
    case .failed(let error):
      print(error)
    }
  },
  content: {
    /* An example button */
    Text("Pay")
  }
)
```

Mengatur `allowsDelayedPaymentMethods` ke true memungkinkan metode pembayaran [pemberitahuan tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification) seperti rekening bank AS. Untuk metode pembayaran ini, status pembayaran finalnya tidak diketahui bila `PaymentSheet` selesai, dan berhasil atau gagal sebagai gantinya nanti. Jika Anda mendukung jenis pembayaran ini, informasikan kepada pelanggan bahwa pesanannya telah dikonfirmasi dan hanya memenuhi pesanan (misalnya, mengirim produknya) bila pembayaran berhasil.


# Android

> This is a Android for when platform is android and mobile-ui is payment-element. View the full page at https://docs.stripe.com/payments/mobile/save-during-payment?platform=android&mobile-ui=payment-element.

Gunakan [Payment Intents API](https://docs.stripe.com/api/payment_intents.md) untuk menyimpan detail pembayaran dari pembelian. Ada beberapa contoh penggunaan:

- Charge pelanggan untuk pesanan e-commerce dan menyimpan detailnya untuk pembelian di masa mendatang.
- Memulai pembayaran pertama dari serangkaian pembayaran rutin.
- Charge deposit dan simpan detailnya untuk menagih jumlah penuh nanti.

> #### Transaksi dengan kartu fisik
> 
> Transaksi dengan kartu fisik, seperti pembayaran melalui Stripe Terminal, menggunakan proses yang berbeda untuk menyimpan metode pembayaran. Untuk detailnya, lihat [dokumentasi Terminal](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md).

## Kepatuhan

Anda bertanggung jawab untuk mematuhi semua hukum, peraturan, dan aturan jaringan yang berlaku saat menyimpan detail pembayaran pelanggan untuk penggunaan di masa mendatang, seperti menampilkan metode pembayaran pelanggan kepada mereka dalam proses alur checkout untuk pembelian di masa mendatang atau menagih mereka saat mereka tidak aktif menggunakan situs web atau aplikasi Anda. Sebelum menyimpan atau menagih metode pembayaran pelanggan, pastikan Anda:

- Tambahkan ketentuan ke situs atau aplikasi Anda yang menyatakan bagaimana Anda berencana menyimpan detail metode pembayaran, seperti:
  - Perjanjian pelanggan yang memungkinkan Anda untuk memulai pembayaran atau serangkaian pembayaran atas nama mereka untuk transaksi tertentu.
  - Waktu dan frekuensi pembayaran yang diantisipasi (misalnya, jika charge untuk angsuran terjadwal, pembayaran langganan, atau penambahan saldo tidak terjadwal).
  - Cara Anda menentukan jumlah pembayaran.
  - Kebijakan pembatalan Anda, jika metode pembayarannya untuk layanan langganan.
- Gunakan metode pembayaran tersimpan hanya untuk tujuan yang tercantum dalam ketentuan Anda.
- Dapatkan persetujuan eksplisit dari pelanggan untuk penggunaan khusus ini. Sebagai contoh, sertakan kotak centang bertuliskan ‘Simpan metode pembayaran saya untuk penggunaan mendatang’.
- Catat perjanjian tertulis pelanggan Anda terhadap ketentuan Anda.

## Siapkan Stripe [Sisi server] [Sisi client]

Pertama, Anda membutuhkan akun Stripe. [Daftarkan sekarang juga](https://dashboard.stripe.com/register).

### Sisi server

Integrasi ini memerlukan endpoint di server Anda yang berinteraksi dengan Stripe API. Gunakan pustaka resmi untuk akses ke Stripe API dari server Anda:

#### Ruby

```bash
# Available as a gem
sudo gem install stripe
```

```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```

### Sisi client

[Stripe Android SDK](https://github.com/stripe/stripe-android) adalah sumber terbuka dan [didokumentasikan lengkap](https://stripe.dev/stripe-android/).

Untuk menginstal SDK, tambahkan `stripe-android``ke blok`dependencies` file [app/build.gradle](https://developer.android.com/studio/build/dependencies) Anda:

#### Kotlin

```kotlin
plugins {
    id("com.android.application")
}

android { ... }

dependencies {
  // ...

  // Stripe Android SDK
  implementation("com.stripe:stripe-android:23.3.0")
  // Include the financial connections SDK to support US bank account as a payment method
  implementation("com.stripe:financial-connections:23.3.0")
}
```

> Untuk detail mengenai rilis SDK terbaru dan versi sebelumnya, lihat halaman [Rilis](https://github.com/stripe/stripe-android/releases) di GitHub. Untuk menerima notifikasi bila rilis baru diterbitkan, [lihat rilis untuk repositori](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository).

## Aktifkan metode pembayaran

Pembayaran kartu diaktifkan secara default. Lihat [pengaturan metode pembayaran](https://dashboard.stripe.com/settings/payment_methods) Anda untuk mengaktifkan metode pembayaran lainnya yang ingin Anda dukung.

## Tambahkan endpoint [Sisi server]

> #### Catatan
> 
> Untuk menampilkan PaymentSheet sebelum membuat PaymentIntent, lihat [Kumpulkan detail pembayaran sebelum membuat Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment).

Integrasi ini menggunakan tiga objek API Stripe:

1. [PaymentIntent](https://docs.stripe.com/api/payment_intents.md): Stripe menggunakannya untuk mewakili maksud Anda menagih pembayaran dari pelanggan, yang melacak upaya charge dan perubahan status pembayaran selama proses.

1. Objek [Akun yang dikonfigurasi pelanggan](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-applied_configurations) atau [Pelanggan](https://docs.stripe.com/api/customers.md): Untuk menyiapkan metode pembayaran untuk pembayaran mendatang, Anda harus melampirkannya ke pelanggan. Buat objek yang mewakili pelanggan Anda saat mereka membuat akun di bisnis Anda. Jika pelanggan melakukan pembayaran sebagai tamu, Anda dapat membuat objek `Akun` atau `Pelanggan` sebelum pembayaran dan menghubungkannya dengan representasi internal akun pelanggan Anda nanti.

1. [CustomerSession](https://docs.stripe.com/api/customer_sessions.md): Informasi pada objek yang mewakili pelanggan Anda bersifat sensitif dan tidak dapat diambil langsung dari aplikasi. `CustomerSession` memberikan SDK akses berlingkup sementara ke `Akun` atau `Pelanggan` dan menyediakan opsi konfigurasi tambahan. Lihat daftar lengkap [opsi konfigurasi](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components).

Karena alasan keamanan, aplikasi Anda tidak dapat membuat objek ini. Sebagai gantinya, tambahkan endpoint di server Anda yang:

1. Mengambil `Akun` atau `Pelanggan`, atau membuat yang baru.
1. Membuat [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) untuk `Akun` atau `Pelanggan`.
1. Membuat `PaymentIntent` dengan [jumlah](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount), [mata uang](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency), [setup_future_usage](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-setup_future_usage), serta [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) atau [customer](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer).
1. Mengembalikan *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)) dari `PaymentIntent`, `client_secret` dari `CustomerSession`, ID dari `Akun` atau `Pelanggan`, dan [publishable key](https://dashboard.stripe.com/apikeys) Anda ke aplikasi.

> Payment Element seluler hanya mendukung `setup_future_usage` dengan rekening bank AS dan kartu.

Metode pembayaran yang ditampilkan kepada pelanggan selama proses checkout juga disertakan dalam PaymentIntent. Anda dapat mengizinkan Stripe menarik metode pembayaran dari pengaturan Dashboard atau Anda dapat mencantumkannya secara manual. Terlepas dari opsi yang Anda pilih, ketahui mata uang yang diteruskan di PaymentIntent memfilter metode pembayaran yang ditampilkan kepada pelanggan. Misalnya, jika Anda meneruskan `eur` pada PaymentIntent dan mengaktifkan OXXO di Dashboard, OXXO tidak akan ditampilkan kepada pelanggan karena OXXO tidak mendukung pembayaran `eur`.

Kecuali jika integrasi Anda memerlukan opsi berbasis kode untuk menawarkan metode pembayaran, Stripe merekomendasikan opsi otomatis. Hal ini karena Stripe mengevaluasi mata uang, pembatasan metode pembayaran, dan parameter lainnya untuk menentukan daftar metode pembayaran yang didukung. Metode pembayaran yang meningkatkan konversi serta yang paling relevan dengan mata uang dan lokasi pelanggan akan diprioritaskan.

#### Kelola metode pembayaran dari Dashboard

Anda dapat mengelola metode pembayaran dari [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe menangani pengembalian metode pembayaran yang memenuhi syarat berdasarkan faktor-faktor seperti jumlah transaksi, mata uang, dan alur pembayaran. PaymentIntent dibuat menggunakan metode pembayaran yang Anda konfigurasikan di Dashboard. Jika tidak ingin menggunakan Dashboard atau jika ingin menentukan metode pembayaran secara manual, Anda dapat mencantumkannya menggunakan atribut `payment_method_types`.

#### Akun v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

  -d "automatic_payment_methods[enabled]"=true \
```

#### Pelanggan v1

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create an CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

  -d "automatic_payment_methods[enabled]"=true \
```

#### Cantumkan metode pembayaran secara manual

#### Akun v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

#### Pelanggan v1

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create an CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

> Setiap metode pembayaran perlu mendukung mata uang yang diteruskan di PaymentIntent dan bisnis Anda perlu berlokasi di salah satu negara yang didukung oleh setiap metode pembayaran. Lihat halaman [Opsi integrasi metode pembayaran](https://docs.stripe.com/payments/payment-methods/integration-options.md) untuk detail selengkapnya tentang apa yang didukung.

## Kumpulkan detail pembayaran [Sisi client]

Sebelum menampilkan Payment Element seluler, halaman checkout Anda harus:

- Tampilkan produk yang sedang dibeli dan jumlah totalnya
- Kumpulkan informasi pengiriman yang diperlukan menggunakan [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android)
- Sertakan tombol checkout untuk menyajikan UI Stripe

#### Jetpack Compose

[Inisialisasi](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-builder/index.html) instance `PaymentSheet` di dalam `onCreate` Aktivitas checkout Anda, yang meneruskan metode untuk menangani hasil.

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult

@Composable
fun App() {
  val paymentSheet = remember { PaymentSheet.Builder(::onPaymentSheetResult) }.build()
}

private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
  // implemented in the next steps
}
```

Selanjutnya, ambil PaymentIntent Client Secret, Client Secret Sesi Pelanggan, ID Pelanggan, dan kunci yang dapat diterbitkan dari titik akhir yang Anda buat di langkah sebelumnya. Atur kunci yang dapat dipublikasikan menggunakan `PaymentConfiguration` dan simpan yang lain untuk digunakan saat Anda menunjukkan PaymentSheet.

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberimport androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import com.stripe.android.PaymentConfiguration
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult

@Composable
fun App() {
  val paymentSheet = remember { PaymentSheet.Builder(::onPaymentSheetResult) }.build()val context = LocalContext.current
  var customerConfig by remember { mutableStateOf<PaymentSheet.CustomerConfiguration?>(null) }
  varpaymentIntentClientSecret by remember { mutableStateOf<String?>(null) }

  LaunchedEffect(context) {
    // Make a request to your own server and retrieve payment configurations
    val networkResult = ...
    if (networkResult.isSuccess) {paymentIntentClientSecret = networkResult.paymentIntent
        customerConfig = PaymentSheet.CustomerConfiguration.createWithCustomerSession(
          id = networkResult.customer,
          clientSecret = networkResult.customerSessionClientSecret
        )PaymentConfiguration.init(context, networkResult.publishableKey)}
  }
}

private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
  // implemented in the next steps
}
```

Bila pelanggan mengetuk tombol checkout Anda, panggil [presentWithPaymentIntent](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#1814490530%2FFunctions%2F2002900378) untuk menyajikan lembar pembayaran. Setelah pelanggan menyelesaikan pembayaran, lembaran akan menutup dan [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) dipanggil dengan [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html).

```kotlin
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import com.stripe.android.PaymentConfiguration
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult

@Composable
fun App() {
  val paymentSheet = remember { PaymentSheet.Builder(::onPaymentSheetResult) }.build()
  val context = LocalContext.current
  var customerConfig by remember { mutableStateOf<PaymentSheet.CustomerConfiguration?>(null) }
  var paymentIntentClientSecret by remember { mutableStateOf<String?>(null) }

  LaunchedEffect(context) {
    // Make a request to your own server and retrieve payment configurations
    val networkResult = ...
    if (networkResult.isSuccess) {
        paymentIntentClientSecret = networkResult.paymentIntent
        customerConfig = PaymentSheet.CustomerConfiguration.createWithCustomerSession(
          id = networkResult.customer,
          clientSecret = networkResult.customerSessionClientSecret
        )
        PaymentConfiguration.init(context, networkResult.publishableKey)
    }
  }Button(
    onClick = {
      val currentConfig = customerConfig
      val currentClientSecret =paymentIntentClientSecret

      if (currentConfig != null && currentClientSecret != null) {
        presentPaymentSheet(paymentSheet, currentConfig, currentClientSecret)
      }
    }
  ) {
    Text("Checkout")
  }
}private fun presentPaymentSheet(
  paymentSheet: PaymentSheet,
  customerConfig: PaymentSheet.CustomerConfiguration,paymentIntentClientSecret: String
) {
  paymentSheet.presentWithPaymentIntent(paymentIntentClientSecret,
    PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name")
      .customer(customerConfig)
      // Set `allowsDelayedPaymentMethods` to true if your business handles
      // delayed notification payment methods like US bank accounts.
      .allowsDelayedPaymentMethods(true)
      .build()
  )
}
private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {when(paymentSheetResult) {
    is PaymentSheetResult.Canceled -> {
      print("Canceled")
    }
    is PaymentSheetResult.Failed -> {
      print("Error: ${paymentSheetResult.error}")
    }
    is PaymentSheetResult.Completed -> {
      // Display for example, an order confirmation screen
      print("Completed")
    }
  }
}
```

#### Tampilan (Klasik)

[Inisialisasikan](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#-394860221%2FConstructors%2F2002900378) instance `PaymentSheet` di dalam `onCreate` Aktivitas checkout Anda, yang meneruskan metode untuk menangani hasil.

#### Kotlin

```kotlin
import com.stripe.android.paymentsheet.PaymentSheet

class CheckoutActivity : AppCompatActivity() {
  lateinit var paymentSheet: PaymentSheet

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult).build(this)
  }

  fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
    // implemented in the next steps
  }
}
```

Selanjutnya, ambil PaymentIntent Client Secret, Client Secret Sesi Pelanggan, ID Pelanggan, dan kunci yang dapat diterbitkan dari titik akhir yang Anda buat di langkah sebelumnya. Atur kunci yang dapat dipublikasikan menggunakan `PaymentConfiguration` dan simpan yang lain untuk digunakan saat Anda menunjukkan PaymentSheet.

#### Kotlin

```kotlin
import com.stripe.android.paymentsheet.PaymentSheet

class CheckoutActivity : AppCompatActivity() {
  lateinit var paymentSheet: PaymentSheetlateinit var customerConfig: PaymentSheet.CustomerConfiguration
  lateinit varpaymentIntentClientSecret: String

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult).build(this)lifecycleScope.launch {
      // Make a request to your own server and retrieve payment configurations
      val networkResult = MyBackend.getPaymentConfig()
      if (networkResult.isSuccess) {paymentIntentClientSecret = networkResult.paymentIntent
        customerConfig = PaymentSheet.CustomerConfiguration.createWithCustomerSession(
          id = networkResult.customer,
          clientSecret = networkResult.customerSessionClientSecret
        )PaymentConfiguration.init(context, networkResult.publishableKey)}
    }
  }

  fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
    // implemented in the next steps
  }
}
```

Bila pelanggan mengetuk tombol checkout Anda, panggil [presentWithPaymentIntent](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#1814490530%2FFunctions%2F2002900378) untuk menyajikan lembar pembayaran. Setelah pelanggan menyelesaikan pembayaran, lembaran akan menutup dan [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) dipanggil dengan [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html).

#### Kotlin

```kotlin
// ...
class CheckoutActivity : AppCompatActivity() {
  lateinit var paymentSheet: PaymentSheet
  lateinit var customerConfig: PaymentSheet.CustomerConfiguration
  lateinit var paymentIntentClientSecret: String
  // ...fun presentPaymentSheet() {
    paymentSheet.presentWithPaymentIntent(paymentIntentClientSecret,
      PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name")
        .customer(customerConfig)
        // Set `allowsDelayedPaymentMethods` to true if your business handles
        // delayed notification payment methods like US bank accounts.
        .allowsDelayedPaymentMethods(true)
        .build()
    )
  }

  fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {when(paymentSheetResult) {
      is PaymentSheetResult.Canceled -> {
        print("Canceled")
      }
      is PaymentSheetResult.Failed -> {
        print("Error: ${paymentSheetResult.error}")
      }
      is PaymentSheetResult.Completed -> {
        // Display for example, an order confirmation screen
        print("Completed")
      }
    }
  }
}
```

Mengatur `allowsDelayedPaymentMethods` ke true memungkinkan metode pembayaran [pemberitahuan tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification) seperti rekening bank AS. Untuk metode pembayaran ini, status pembayaran finalnya tidak diketahui bila `PaymentSheet` selesai, dan berhasil atau gagal sebagai gantinya nanti. Jika Anda mendukung jenis pembayaran ini, informasikan kepada pelanggan bahwa pesanannya telah dikonfirmasi dan hanya memenuhi pesanan (misalnya, mengirim produknya) bila pembayaran berhasil.

## Tangani kejadian pasca-pembayaran [Sisi server]

Stripe mengirim kejadian [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) ketika selesai pembayaran. Gunakan [alat webhook Dashboard](https://dashboard.stripe.com/webhooks) atau ikuti [panduan webhook](https://docs.stripe.com/webhooks/quickstart.md) untuk menerima kejadian ini dan menjalankan tindakan, seperti mengirim email konfirmasi pesanan kepada pelanggan Anda, mencatat penjualan di database, atau memulai alur kerja pengiriman.

Dengarkan kejadian ini daripada menunggu callback dari client. Di client, pelanggan dapat menutup jendela browser atau keluar dari aplikasi sebelum callback mengeksekusi, dan klien jahat dapat memanipulasi respons. Penyiapan integrasi untuk mendengarkan kejadian asinkron memungkinkan Anda menyetujui [berbagai tipe metode pembayaran](https://stripe.com/payments/payment-methods-guide) dengan satu integrasi tunggal.

Selain menangani kejadian `payment_intent.succeeded`, kami merekomendasikan penanganan kejadian ini yang lain ketika menagih pembayaran dengan Payment Element:

| Kejadian                                                                                                                        | Keterangan                                                                                                                                                                                                                                                                                 | Tindakan                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | Dikirim bila pelanggan berhasil menyelesaikan pembayaran.                                                                                                                                                                                                                                  | Kirimi pelanggan konfirmasi pesanan dan *penuhi* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) pesanan mereka.     |
| [payment_intent. pemrosesan](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)        | Dikirim bila pelanggan berhasil memprakarsai pembayaran, tetapi pembayaran itu belum selesai. Kejadian ini paling umum dikirim saat pelanggan memprakarsai debit bank. Kejadian diikuti dengan kejadian `payment_intent.succeeded` atau `payment_intent.payment_failed` di masa mendatang. | Kirimi pelanggan konfirmasi pesanan yang menunjukkan bahwa pembayaran mereka menunggu penyelesaian. Untuk barang digital, Anda mungkin ingin memenuhi pesanan sebelum menunggu pembayaran selesai. |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Dikirim bila pelanggan mencoba melakukan pembayaran, tetapi pembayaran itu gagal.                                                                                                                                                                                                          | Jika transisi pembayaran dilakukan dari `processing` menjadi `payment_failed`, tawarkan upaya lain untuk membayar kepada pelanggan.                                                                |

## Charge Metode Pembayaran tersimpan nanti [Sisi server]

> #### Kepatuhan
> 
> Anda bertanggung jawab atas kepatuhan terhadap semua hukum, peraturan, dan aturan jaringan yang berlaku saat menyimpan detail pembayaran pelanggan. Saat menampilkan metode pembayaran sebelumnya kepada pelanggan akhir untuk pembelian di masa mendatang, pastikan Anda mencantumkan metode pembayaran yang telah mendapatkan persetujuan dari pelanggan untuk menyimpan detail metode pembayaran untuk penggunaan khusus di masa mendatang. Untuk membedakan antara metode pembayaran yang dilampirkan pada pelanggan yang dapat dan tidak dapat ditampilkan kepada pelanggan akhir Anda sebagai metode pembayaran tersimpan untuk pembelian di masa mendatang, gunakan parameter [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

Untuk menemukan metode pembayaran yang akan ditagih, buatlah daftar metode pembayaran yang terkait dengan pelanggan Anda. Contoh ini menampilkan daftar kartu, namun Anda dapat mencantumkan [jenis](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) apa pun yang didukung.

> #### Menggunakan API Akun v2 untuk mewakili pelanggan
> 
> API Akun v2 umumnya tersedia untuk pengguna Connect, dan dalam pratinjau publik untuk pengguna Stripe lainnya. Jika Anda adalah bagian dari pratinjau Akun v2, Anda perlu menentukan [Tentukan versi pratinjau](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) dalam kode Anda.
> 
> Untuk meminta akses ke pratinjau Akun v2, 
> 
> Untuk sebagian besar contoh penggunaan, sebaiknya Anda [memodelkan pelanggan Anda sebagai objek Account yang dikonfigurasi pelanggan](https://docs.stripe.com/connect/use-accounts-as-customers.md) alih-alih menggunakan [Customer](https://docs.stripe.com/api/customers.md) objek.

#### Akun v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d type=card
```

#### Pelanggan v1

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d type=card
```

Saat Anda siap untuk menagih pelanggan secara off-session**, gunakan ID pelanggan dan ID `PaymentMethod` untuk membuat `PaymentIntent` dengan jumlah dan mata uang pembayaran yang sesuai. Atur beberapa parameter lainnya untuk melakukan pembayaran di luar sesi (off-session):

- Atur [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) ke `true` untuk menunjukkan bahwa pelanggan tidak berada dalam alur checkout Anda saat percobaan pembayaran dilakukan dan tidak dapat memenuhi permintaan autentikasi dari mitra, seperti penerbit kartu, bank, atau lembaga pembayaran lainnya. Jika mitra meminta autentikasi selama alur checkout, Stripe akan meminta pengecualian (exemption) menggunakan informasi pelanggan dari transaksi on-session** sebelumnya. Jika kondisi untuk pengecualian tidak terpenuhi, `PaymentIntent` mungkin akan menghasilkan kesalahan (error).
- Atur nilai properti [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) pada `PaymentIntent` ke true, agar konfirmasi terjadi segera setelah `PaymentIntent` dibuat.
- Atur [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) ke ID `PaymentMethod`.
- Bergantung pada cara Anda merepresentasikan pelanggan dalam integrasi Anda, atur [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) ke ID `Account` yang dikonfigurasi untuk pelanggan atau atur [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) ke ID `Customer`.

#### Akun v2

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

#### Pelanggan v1

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

## Uji integrasinya

#### Kartu

| Metode pembayaran | Skenario                                                                                                                                                                                                                                                                                                       | Cara mencoba                                                                                                                                    |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Kartu kredit      | Penyiapan kartu berhasil dan tidak memerlukan *autentikasi* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Isilah formulir kartu kredit menggunakan nomor kartu kredit `4242 4242 4242 4242` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos.      |
| Kartu kredit      | Kartu ini memerlukan autentikasi untuk penyiapan awal, kemudian berhasil untuk pembelian berikutnya.                                                                                                                                                                                                           | Isilah formulir kartu kredit kami menggunakan nomor kartu kredit `4000 0025 0000 3155` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos. |
| Kartu kredit      | Kartu ini memerlukan autentikasi untuk penyiapan awal dan juga memerlukan autentikasi untuk pembelian berikutnya.                                                                                                                                                                                              | Isilah formulir kartu kredit kami menggunakan nomor kartu kredit `4000 0027 6000 3184` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos. |
| Kartu kredit      | Kartu ini ditolak selama penyiapan.                                                                                                                                                                                                                                                                            | Isilah formulir kartu kredit menggunakan nomor kartu kredit `4000 0000 0000 9995` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos.      |

## Optional: Aktifkan Google Pay

### Siapkan integrasi Anda

Untuk menggunakan Google Pay, pertama aktifkan Google Pay API dengan menambahkan yang berikut ini ke tag `<application>` **AndroidManifest.xml** Anda:

```xml
<application>
  ...
  <meta-data
    android:name="com.google.android.gms.wallet.api.enabled"
    android:value="true" />
</application>
```

Untuk detail selengkapnya, lihat [Siapkan Google Pay API](https://developers.google.com/pay/api/android/guides/setup) untuk Android dari Google Pay.

### Tambahkan Google Pay

Untuk menambahkan Google Pay ke integrasi Anda, teruskan [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) bersama lingkungan Google Pay Anda (produksi atau percobaan) dan [kode negara bisnis Anda](https://dashboard.stripe.com/settings/account) saat memprakarsai [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html).

#### Kotlin

```kotlin
val googlePayConfiguration = PaymentSheet.GooglePayConfiguration(
  environment = PaymentSheet.GooglePayConfiguration.Environment.Test,
  countryCode = "US",
  currencyCode = "USD" // Required for Setup Intents, optional for Payment Intents
)
val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name")
  .googlePay(googlePayConfiguration)
  .build()
```

### Google Pay percobaan

Google mengizinkan Anda melakukan pembayaran melalui [Rangkaian kartu percobaan](https://developers.google.com/pay/api/android/guides/resources/test-card-suite). Rangkaian kartu percobaan ini mendukung penggunaan [kartu percobaan](https://docs.stripe.com/testing.md) Stripe.

Anda harus menguji Google Pay menggunakan perangkat Android fisik, bukan perangkat simulasi, di negara yang mendukung Google Pay. Masuk ke Akun Google pada perangkat percobaan Anda dengan kartu asli yang disimpan di Google Wallet.

## Optional: Sesuaikan lembar

Semua penyesuaian dikonfigurasi menggunakan objek [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html).

### Penampilan

Sesuaikan warna, font, dan lainnya agar sesuai dengan tampilan dan nuansa aplikasi Anda dengan menggunakan [API penampilan](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=android).

### Tata letak metode pembayaran

Konfigurasikan tata letak metode pembayaran di lembaran menggunakan [paymentMethodLayout](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/-builder/index.html#2123253356%2FFunctions%2F2002900378). Anda dapat menampilkannya secara horizontal, vertikal, atau membiarkan Stripe mengoptimalkan tata letak secara otomatis.
![](https://b.stripecdn.com/docs-statics-srv/assets/android-mpe-payment-method-layouts.3bcfe828ceaad1a94e0572a22d91733f.png)

#### Kotlin

```kotlin
PaymentSheet.Configuration.Builder("Example, Inc.")
  .paymentMethodLayout(PaymentSheet.PaymentMethodLayout.Automatic)
  .build()
```

### Kumpulkan alamat pengguna

Kumpulkan alamat tagihan atau pengiriman lokal dan internasional dari pelanggan Anda menggunakan [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android).

### Nama tampilan bisnis

Tentukan nama bisnis yang dilihat pelanggan dengan mengatur [merchantDisplayName](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html#-191101533%2FProperties%2F2002900378). Secara default, ini adalah nama aplikasi Anda.

#### Kotlin

```kotlin
PaymentSheet.Configuration.Builder(
  merchantDisplayName = "My app, Inc."
).build()
```

### Mode gelap

Secara default `PaymentSheet` beradaptasi otomatis dengan pengaturan penampilan skala-sistem pengguna (mode terang dan gelap). Anda dapat mengubahnya dengan mengatur mode terang atau gelap di aplikasi Anda:

#### Kotlin

```kotlin
// force dark
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
// force light
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
```

### Detail tagihan default

Untuk mengatur nilai default bagi detail tagihan yang dikumpulkan di lembar pembayaran, konfigurasikan properti `defaultBillingDetails`. `PaymentSheet` akan melengkapi bidang-bidangnya dengan nilai yang Anda berikan.

#### Kotlin

```kotlin
val address = PaymentSheet.Address(country = "US")
val billingDetails = PaymentSheet.BillingDetails(
  address = address,
  email = "foo@bar.com"
)
val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.")
  .defaultBillingDetails(billingDetails)
  .build()
```

### Konfigurasikan pengumpulan detail tagihan

Menggunakan `BillingDetailsCollectionConfiguration` untuk menentukan cara Anda ingin mengumpulkan detail tagihan di PaymentSheet.

Anda dapat mengumpulkan nama, email, nomor telepon, dan alamat pelanggan.

Jika Anda ingin melampirkan detail tagihan default ke objek PaymentMethod sekalipun bidang tersebut tidak dikumpulkan di UI, atur `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` ke `true`.

#### Kotlin

```kotlin
val billingDetails = PaymentSheet.BillingDetails(
  email = "foo@bar.com"
)
val billingDetailsCollectionConfiguration = BillingDetailsCollectionConfiguration(
  attachDefaultsToPaymentMethod = true,
  name = BillingDetailsCollectionConfiguration.CollectionMode.Always,
  email = BillingDetailsCollectionConfiguration.CollectionMode.Never,
  address = BillingDetailsCollectionConfiguration.AddressCollectionMode.Full,
)
val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.")
  .defaultBillingDetails(billingDetails)
  .billingDetailsCollectionConfiguration(billingDetailsCollectionConfiguration)
  .build()
```

> Konsultasikan dengan penasihat hukum mengenai undang-undang yang berlaku untuk mengumpulkan informasi. Hanya kumpulkan nomor telepon jika Anda memerlukannya untuk transaksi.

## Optional: Selesaikan pembayaran di UI Anda

Anda dapat menyajikan Lembar Pembayaran untuk hanya mengumpulkan detail metode pembayaran dan menyelesaikan pembayaran kembali di UI aplikasi Anda. Hal ini akan berguna jika Anda memiliki tombol beli custom atau memerlukan langkah tambahan setelah detail pembayaran dikumpulkan.
![](https://b.stripecdn.com/docs-statics-srv/assets/android-multi-step.84d8a0a44b1baa596bda491322b6d9fd.png)

> Contoh integrasi [tersedia di GitHub kami](https://github.com/stripe/stripe-android/blob/master/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/samples/ui/paymentsheet/custom_flow/CustomFlowActivity.kt).

1. Pertama, inisialisasikan [PaymentSheet.FlowController](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html) alih-alih `PaymentSheet` menggunakan salah satu metode [Builder](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/-builder/index.html).

#### Android (Kotlin)

```kotlin
class CheckoutActivity : AppCompatActivity() {
  private lateinit var flowController: PaymentSheet.FlowController

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val flowController = PaymentSheet.FlowController.Builder(
      resultCallback = ::onPaymentSheetResult,
      paymentOptionResultCallback = ::onPaymentOption,
    ).build(this)
  }
}
```

1. Berikutnya, panggil `configureWithPaymentIntent` dengan kunci objek Stripe yang diambil dari backend Anda dan perbarui UI di callback menggunakan [getPaymentOption()](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#-2091462043%2FFunctions%2F2002900378). Ini berisi gambar dan label yang mewakili metode pembayaran yang saat ini dipilih pelanggan.

#### Android (Kotlin)

```kotlin
flowController.configureWithPaymentIntent(
  paymentIntentClientSecret = paymentIntentClientSecret,
  configuration = PaymentSheet.Configuration.Builder("Example, Inc.")
    .customer(PaymentSheet.CustomerConfiguration(
      id = customerId,
      ephemeralKeySecret = ephemeralKeySecret
    ))
    .build()
) { isReady, error ->
  if (isReady) {
    // Update your UI using `flowController.getPaymentOption()`
  } else {
    // handle FlowController configuration failure
  }
}
```

1. Berikutnya, panggil [presentPaymentOptions](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#449924733%2FFunctions%2F2002900378) untuk mengumpulkan detail pembayaran. Saat pelanggan selesai, lembaran akan menutup dan memanggil [paymentOptionCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-option-callback/index.html) yang diteruskan sebelumnya di `create`. Implementasikan metode ini untuk memperbarui UI Anda dengan `paymentOption` yang dikembalikan.

#### Android (Kotlin)

```kotlin
// ...
  flowController.presentPaymentOptions()
// ...
  private fun onPaymentOption(paymentOptionResult: PaymentOptionResult) {
    val paymentOption = paymentOptionResult.paymentOption
    if (paymentOption != null) {
      paymentMethodButton.text = paymentOption.label
      paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
        paymentOption.drawableResourceId,
        0,
        0,
        0
      )
    } else {
      paymentMethodButton.text = "Select"
      paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
        null,
        null,
        null,
        null
      )
    }
  }
```

1. Terakhir, panggil [confirm](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#-479056656%2FFunctions%2F2002900378) untuk menyelesaikan pembayaran. Saat pelanggan selesai, lembaran akan menutup dan memanggil [paymentResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html#237248767%2FFunctions%2F2002900378) yang diteruskan sebelumnya di `create`.

#### Android (Kotlin)

```kotlin
  // ...
    flowController.confirmPayment()
  // ...

  private fun onPaymentSheetResult(
    paymentSheetResult: PaymentSheetResult
  ) {
    when (paymentSheetResult) {
      is PaymentSheetResult.Canceled -> {
        // Payment canceled
      }
      is PaymentSheetResult.Failed -> {
        // Payment Failed. See logcat for details or inspect paymentSheetResult.error
      }
      is PaymentSheetResult.Completed -> {
        // Payment Complete
      }
    }
  }
```

Mengatur `allowsDelayedPaymentMethods` ke true memungkinkan metode pembayaran [pemberitahuan tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification) seperti rekening bank AS. Untuk metode pembayaran ini, status pembayaran finalnya tidak diketahui bila `PaymentSheet` selesai, dan berhasil atau gagal sebagai gantinya nanti. Jika Anda mendukung jenis pembayaran ini, informasikan kepada pelanggan bahwa pesanannya telah dikonfirmasi dan hanya memenuhi pesanan (misalnya, mengirim produknya) bila pembayaran berhasil.


# React Native

> This is a React Native for when platform is react-native and mobile-ui is payment-element. View the full page at https://docs.stripe.com/payments/mobile/save-during-payment?platform=react-native&mobile-ui=payment-element.

Gunakan [Payment Intents API](https://docs.stripe.com/api/payment_intents.md) untuk menyimpan detail pembayaran dari pembelian. Ada beberapa contoh penggunaan:

- Charge pelanggan untuk pesanan e-commerce dan menyimpan detailnya untuk pembelian di masa mendatang.
- Memulai pembayaran pertama dari serangkaian pembayaran rutin.
- Charge deposit dan simpan detailnya untuk menagih jumlah penuh nanti.

> #### Transaksi dengan kartu fisik
> 
> Transaksi dengan kartu fisik, seperti pembayaran melalui Stripe Terminal, menggunakan proses yang berbeda untuk menyimpan metode pembayaran. Untuk detailnya, lihat [dokumentasi Terminal](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md).

## Kepatuhan

Anda bertanggung jawab untuk mematuhi semua hukum, peraturan, dan aturan jaringan yang berlaku saat menyimpan detail pembayaran pelanggan untuk penggunaan di masa mendatang, seperti menampilkan metode pembayaran pelanggan kepada mereka dalam proses alur checkout untuk pembelian di masa mendatang atau menagih mereka saat mereka tidak aktif menggunakan situs web atau aplikasi Anda. Sebelum menyimpan atau menagih metode pembayaran pelanggan, pastikan Anda:

- Tambahkan ketentuan ke situs atau aplikasi Anda yang menyatakan bagaimana Anda berencana menyimpan detail metode pembayaran, seperti:
  - Perjanjian pelanggan yang memungkinkan Anda untuk memulai pembayaran atau serangkaian pembayaran atas nama mereka untuk transaksi tertentu.
  - Waktu dan frekuensi pembayaran yang diantisipasi (misalnya, jika charge untuk angsuran terjadwal, pembayaran langganan, atau penambahan saldo tidak terjadwal).
  - Cara Anda menentukan jumlah pembayaran.
  - Kebijakan pembatalan Anda, jika metode pembayarannya untuk layanan langganan.
- Gunakan metode pembayaran tersimpan hanya untuk tujuan yang tercantum dalam ketentuan Anda.
- Dapatkan persetujuan eksplisit dari pelanggan untuk penggunaan khusus ini. Sebagai contoh, sertakan kotak centang bertuliskan ‘Simpan metode pembayaran saya untuk penggunaan mendatang’.
- Catat perjanjian tertulis pelanggan Anda terhadap ketentuan Anda.

## Siapkan Stripe [Sisi server] [Sisi client]

Pertama, Anda membutuhkan akun Stripe. [Daftarkan sekarang juga](https://dashboard.stripe.com/register).

### Sisi server

Integrasi ini memerlukan endpoint di server Anda yang berinteraksi dengan Stripe API. Gunakan pustaka resmi untuk akses ke Stripe API dari server Anda:

#### Ruby

```bash
# Available as a gem
sudo gem install stripe
```

```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```

### Sisi client

[React Native SDK](https://github.com/stripe/stripe-react-native) adalah sumber terbuka dan didokumentasikan lengkap. Secara internal, SDK [iOS asli](https://github.com/stripe/stripe-ios) dan SDK [Android](https://github.com/stripe/stripe-android) digunakan. Untuk menginstal React Native SDK Stripe, jalankan salah satu perintah berikut di direktori proyek (bergantung pada manajer paket yang Anda gunakan):

#### yarn

```bash
yarn add @stripe/stripe-react-native
```

#### npm

```bash
npm install @stripe/stripe-react-native
```

Selanjutnya, instal beberapa dependensi lain yang diperlukan:

- Untuk iOS, buka direktori **ios** dan jalankan `pod install` untuk memastikan bahwa Anda juga menginstal dependensi asli yang diperlukan.
- Untuk Android, tidak ada lagi ketergantungan yang harus diinstal.

> Sebaiknya ikuti [panduan TypeScript resmi](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project) untuk menambahkan dukungan TypeScript.

### Inisialisasi Stripe

Untuk menginisialisasi Stripe di aplikasi React Native, bungkus layar pembayaran dengan komponen `StripeProvider`, atau gunakan metode inisialisasi `initStripe`. Hanya [kunci yang dapat dipublikasikan](https://docs.stripe.com/keys.md#obtain-api-keys) API di `publishableKey` yang diperlukan. Contoh berikut menunjukkan cara menginisialisasi Stripe menggunakan komponen `StripeProvider`.

```jsx
import { useState, useEffect } from 'react';
import { StripeProvider } from '@stripe/stripe-react-native';

function App() {
  const [publishableKey, setPublishableKey] = useState('');

  const fetchPublishableKey = async () => {
    const key = await fetchKey(); // fetch key from your server here
    setPublishableKey(key);
  };

  useEffect(() => {
    fetchPublishableKey();
  }, []);

  return (
    <StripeProvider
      publishableKey={publishableKey}
      merchantIdentifier="merchant.identifier" // required for Apple Pay
      urlScheme="your-url-scheme" // required for 3D Secure and bank redirects
    >
      {/* Your app code here */}
    </StripeProvider>
  );
}
```

> Gunakan [kunci percobaan](https://docs.stripe.com/keys.md#obtain-api-keys) API Anda saat mencoba serta mengembangkan, dan kunci [mode live](https://docs.stripe.com/keys.md#test-live-modes) bila Anda memublikasikan aplikasi.

## Aktifkan metode pembayaran

Pembayaran kartu diaktifkan secara default. Lihat [pengaturan metode pembayaran](https://dashboard.stripe.com/settings/payment_methods) Anda untuk mengaktifkan metode pembayaran lainnya yang ingin Anda dukung.

## Tambahkan endpoint [Sisi server]

> #### Catatan
> 
> Untuk menampilkan PaymentSheet sebelum membuat PaymentIntent, lihat [Kumpulkan detail pembayaran sebelum membuat Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment).

Integrasi ini menggunakan tiga objek API Stripe:

1. [PaymentIntent](https://docs.stripe.com/api/payment_intents.md): Stripe menggunakannya untuk mewakili maksud Anda menagih pembayaran dari pelanggan, yang melacak upaya charge dan perubahan status pembayaran selama proses.

1. Objek [Akun yang dikonfigurasi pelanggan](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-applied_configurations) atau [Pelanggan](https://docs.stripe.com/api/customers.md): Untuk menyiapkan metode pembayaran untuk pembayaran mendatang, Anda harus melampirkannya ke pelanggan. Buat objek yang mewakili pelanggan Anda saat mereka membuat akun di bisnis Anda. Jika pelanggan melakukan pembayaran sebagai tamu, Anda dapat membuat objek `Akun` atau `Pelanggan` sebelum pembayaran dan menghubungkannya dengan representasi internal akun pelanggan Anda nanti.

1. [CustomerSession](https://docs.stripe.com/api/customer_sessions.md): Informasi pada objek yang mewakili pelanggan Anda bersifat sensitif dan tidak dapat diambil langsung dari aplikasi. `CustomerSession` memberikan SDK akses berlingkup sementara ke `Akun` atau `Pelanggan` dan menyediakan opsi konfigurasi tambahan. Lihat daftar lengkap [opsi konfigurasi](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components).

Karena alasan keamanan, aplikasi Anda tidak dapat membuat objek ini. Sebagai gantinya, tambahkan endpoint di server Anda yang:

1. Mengambil `Akun` atau `Pelanggan`, atau membuat yang baru.
1. Membuat [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) untuk `Akun` atau `Pelanggan`.
1. Membuat `PaymentIntent` dengan [jumlah](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount), [mata uang](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency), [setup_future_usage](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-setup_future_usage), serta [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) atau [customer](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer).
1. Mengembalikan *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)) dari `PaymentIntent`, `client_secret` dari `CustomerSession`, ID dari `Akun` atau `Pelanggan`, dan [publishable key](https://dashboard.stripe.com/apikeys) Anda ke aplikasi.

> Payment Element seluler hanya mendukung `setup_future_usage` dengan rekening bank AS dan kartu.

Metode pembayaran yang ditampilkan kepada pelanggan selama proses checkout juga disertakan dalam PaymentIntent. Anda dapat mengizinkan Stripe menarik metode pembayaran dari pengaturan Dashboard atau Anda dapat mencantumkannya secara manual. Terlepas dari opsi yang Anda pilih, ketahui mata uang yang diteruskan di PaymentIntent memfilter metode pembayaran yang ditampilkan kepada pelanggan. Misalnya, jika Anda meneruskan `eur` pada PaymentIntent dan mengaktifkan OXXO di Dashboard, OXXO tidak akan ditampilkan kepada pelanggan karena OXXO tidak mendukung pembayaran `eur`.

Kecuali jika integrasi Anda memerlukan opsi berbasis kode untuk menawarkan metode pembayaran, Stripe merekomendasikan opsi otomatis. Hal ini karena Stripe mengevaluasi mata uang, pembatasan metode pembayaran, dan parameter lainnya untuk menentukan daftar metode pembayaran yang didukung. Metode pembayaran yang meningkatkan konversi serta yang paling relevan dengan mata uang dan lokasi pelanggan akan diprioritaskan.

#### Kelola metode pembayaran dari Dashboard

Anda dapat mengelola metode pembayaran dari [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe menangani pengembalian metode pembayaran yang memenuhi syarat berdasarkan faktor-faktor seperti jumlah transaksi, mata uang, dan alur pembayaran. PaymentIntent dibuat menggunakan metode pembayaran yang Anda konfigurasikan di Dashboard. Jika tidak ingin menggunakan Dashboard atau jika ingin menentukan metode pembayaran secara manual, Anda dapat mencantumkannya menggunakan atribut `payment_method_types`.

#### Akun v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

  -d "automatic_payment_methods[enabled]"=true \
```

#### Pelanggan v1

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create an CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

  -d "automatic_payment_methods[enabled]"=true \
```

#### Cantumkan metode pembayaran secara manual

#### Akun v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

#### Pelanggan v1

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create an CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

> Setiap metode pembayaran perlu mendukung mata uang yang diteruskan di PaymentIntent dan bisnis Anda perlu berlokasi di salah satu negara yang didukung oleh setiap metode pembayaran. Lihat halaman [Opsi integrasi metode pembayaran](https://docs.stripe.com/payments/payment-methods/integration-options.md) untuk detail selengkapnya tentang apa yang didukung.

## Kumpulkan detail pembayaran [Sisi client]

Sebelum menampilkan Payment Element seluler, halaman checkout Anda harus:

- Tampilkan produk yang sedang dibeli dan jumlah totalnya
- Kumpulkan setiap informasi pengiriman yang diperlukan
- Sertakan tombol checkout untuk menyajikan UI Stripe

Dalam checkout aplikasi Anda, buat permintaan jaringan ke endpoint backend yang Anda buat di langkah sebelumnya dan panggil `initPaymentSheet` dari hook `useStripe`.

#### Akun v2

```javascript
export default function CheckoutScreen() {
  const { initPaymentSheet, presentPaymentSheet } = useStripe();
  const [loading, setLoading] = useState(false);

  const fetchPaymentSheetParams = async () => {
    const response = await fetch(`${API_URL}/payment-sheet`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const { paymentIntent, ephemeralKey, customer_account } = await response.json();

    return {
      paymentIntent,
      ephemeralKey,
      customer_account,
    };
  };

  const initializePaymentSheet = async () => {
    const {
      paymentIntent,
      ephemeralKey,
      customer_account,
    } = await fetchPaymentSheetParams();

    const { error } = await initPaymentSheet({
      merchantDisplayName: "Example, Inc.",
      customerAccountId: customer_account,
      customerEphemeralKeySecret: ephemeralKey,
      paymentIntentClientSecret: paymentIntent,
      // Set `allowsDelayedPaymentMethods` to true if your business accepts payment
      // methods that complete payment after a delay, like SEPA Debit and Sofort.
      allowsDelayedPaymentMethods: true,
      defaultBillingDetails: {
        name: 'Jane Doe',
      }
    });
    if (!error) {
      setLoading(true);
    }
  };

  const openPaymentSheet = async () => {
    // see below
  };

  useEffect(() => {
    initializePaymentSheet();
  }, []);

  return (
    <Screen>
      <Button
        variant="primary"
        disabled={!loading}
        title="Checkout"
        onPress={openPaymentSheet}
      />
    </Screen>
  );
}
```

#### Pelanggan v1

```javascript

export default function CheckoutScreen() {
  const { initPaymentSheet, presentPaymentSheet } = useStripe();
  const [loading, setLoading] = useState(false);

  const fetchPaymentSheetParams = async () => {
    const response = await fetch(`${API_URL}/payment-sheet`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const { paymentIntent, ephemeralKey, customer } = await response.json();

    return {
      paymentIntent,
      ephemeralKey,
      customer,
    };
  };

  const initializePaymentSheet = async () => {
    const {
      paymentIntent,
      ephemeralKey,
      customer,
    } = await fetchPaymentSheetParams();

    const { error } = await initPaymentSheet({
      merchantDisplayName: "Example, Inc.",
      customerId: customer,
      customerEphemeralKeySecret: ephemeralKey,
      paymentIntentClientSecret: paymentIntent,
      // Set `allowsDelayedPaymentMethods` to true if your business can handle payment
      //methods that complete payment after a delay, like SEPA Debit and Sofort.
      allowsDelayedPaymentMethods: true,
      defaultBillingDetails: {
        name: 'Jane Doe',
      }
    });
    if (!error) {
      setLoading(true);
    }
  };

  const openPaymentSheet = async () => {
    // see below
  };

  useEffect(() => {
    initializePaymentSheet();
  }, []);

  return (
    <Screen>
      <Button
        variant="primary"
        disabled={!loading}
        title="Checkout"
        onPress={openPaymentSheet}
      />
    </Screen>
  );
}
```

Ketika pelanggan mengetuk tombol **Checkout**, panggil `presentPaymentSheet()` untuk membuka lembaran. Setelah pelanggan menyelesaikan pembayaran ini, lembaran akan ditutup dan janji akan diselesaikan dengan `StripeError<PaymentSheetError>` opsional.

```javascript
export default function CheckoutScreen() {
  // continued from above

  const openPaymentSheet = async () => {
    const { error } = await presentPaymentSheet();

    if (error) {
      Alert.alert(`Error code: ${error.code}`, error.message);
    } else {
      Alert.alert('Success', 'Your order is confirmed!');
    }
  };

  return (
    <Screen>
      <Button
        variant="primary"
        disabled={!loading}
        title="Checkout"
        onPress={openPaymentSheet}
      />
    </Screen>
  );
}
```

Jika tidak ada kesalahan, informasikan pengguna bahwa mereka selesai (misalnya, dengan menampilkan layar konfirmasi pesanan).

Mengatur `allowsDelayedPaymentMethods` ke true memungkinkan metode pembayaran [pemberitahuan tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification) seperti rekening bank AS. Untuk metode pembayaran ini, status pembayaran finalnya tidak diketahui bila `PaymentSheet` selesai, dan berhasil atau gagal sebagai gantinya nanti. Jika Anda mendukung jenis pembayaran ini, informasikan kepada pelanggan bahwa pesanannya telah dikonfirmasi dan hanya memenuhi pesanan (misalnya, mengirim produknya) bila pembayaran berhasil.

## Siapkan URL kembali Anda (hanya iOS) [Sisi client]

Bila pelanggan keluar dari aplikasi Anda (misalnya untuk melakukan autentikasi di Safari atau aplikasi perbankan), sediakan cara agar pelanggan dapat kembali ke aplikasi Anda secara otomatis. Banyak tipe metode pembayaran *memerlukan* URL kembali. Jika Anda tidak memberikannya, kami tidak dapat menyajikan metode pembayaran yang mengharuskan URL kembali kepada pengguna, sekalipun Anda telah mengaktifkannya.

Untuk memberikan URL kembali:

1. [Daftarkan](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app#Register-your-URL-scheme) URL custom. Tautan universal tidak didukung.
1. [Konfigurasikan](https://reactnative.dev/docs/linking) URL custom Anda.
1. Siapkan komponen root Anda untuk meneruskan URL ke SDK Stripe seperti yang ditunjukkan di bawah ini.

> Jika Anda menggunakan Expo, [atur skema](https://docs.expo.io/guides/linking/#in-a-standalone-app) di file `app.json`.

```jsx
import { useEffect, useCallback } from 'react';
import { Linking } from 'react-native';
import { useStripe } from '@stripe/stripe-react-native';

export default function MyApp() {
  const { handleURLCallback } = useStripe();

  const handleDeepLink = useCallback(
    async (url: string | null) => {
      if (url) {
        const stripeHandled = await handleURLCallback(url);
        if (stripeHandled) {
          // This was a Stripe URL - you can return or add extra handling here as you see fit
        } else {
          // This was NOT a Stripe URL – handle as you normally would
        }
      }
    },
    [handleURLCallback]
  );

  useEffect(() => {
    const getUrlAsync = async () => {
      const initialUrl = await Linking.getInitialURL();
      handleDeepLink(initialUrl);
    };

    getUrlAsync();

    const deepLinkListener = Linking.addEventListener(
      'url',
      (event: { url: string }) => {
        handleDeepLink(event.url);
      }
    );

    return () => deepLinkListener.remove();
  }, [handleDeepLink]);

  return (
    <View>
      <AwesomeAppComponent />
    </View>
  );
}
```

Selain itu, atur `returnURL` bila Anda memanggil metode `initPaymentSheet`:

```js
await initPaymentSheet({
  ...
  returnURL: 'your-app://stripe-redirect',
  ...
});
```

Untuk informasi selengkapnya tentang skema URL asli, baca dokumen [Android](https://developer.android.com/training/app-links/deep-linking) dan [iOS](https://developer.apple.com/documentation/xcode/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app).

## Tangani kejadian pasca-pembayaran

Stripe mengirim kejadian [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) ketika selesai pembayaran. Gunakan [alat webhook Dashboard](https://dashboard.stripe.com/webhooks) atau ikuti [panduan webhook](https://docs.stripe.com/webhooks/quickstart.md) untuk menerima kejadian ini dan menjalankan tindakan, seperti mengirim email konfirmasi pesanan kepada pelanggan Anda, mencatat penjualan di database, atau memulai alur kerja pengiriman.

Dengarkan kejadian ini daripada menunggu callback dari client. Di client, pelanggan dapat menutup jendela browser atau keluar dari aplikasi sebelum callback mengeksekusi, dan klien jahat dapat memanipulasi respons. Penyiapan integrasi untuk mendengarkan kejadian asinkron memungkinkan Anda menyetujui [berbagai tipe metode pembayaran](https://stripe.com/payments/payment-methods-guide) dengan satu integrasi tunggal.

Selain menangani kejadian `payment_intent.succeeded`, kami merekomendasikan penanganan kejadian ini yang lain ketika menagih pembayaran dengan Payment Element:

| Kejadian                                                                                                                        | Keterangan                                                                                                                                                                                                                                                                                 | Tindakan                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | Dikirim bila pelanggan berhasil menyelesaikan pembayaran.                                                                                                                                                                                                                                  | Kirimi pelanggan konfirmasi pesanan dan *penuhi* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) pesanan mereka.     |
| [payment_intent. pemrosesan](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)        | Dikirim bila pelanggan berhasil memprakarsai pembayaran, tetapi pembayaran itu belum selesai. Kejadian ini paling umum dikirim saat pelanggan memprakarsai debit bank. Kejadian diikuti dengan kejadian `payment_intent.succeeded` atau `payment_intent.payment_failed` di masa mendatang. | Kirimi pelanggan konfirmasi pesanan yang menunjukkan bahwa pembayaran mereka menunggu penyelesaian. Untuk barang digital, Anda mungkin ingin memenuhi pesanan sebelum menunggu pembayaran selesai. |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Dikirim bila pelanggan mencoba melakukan pembayaran, tetapi pembayaran itu gagal.                                                                                                                                                                                                          | Jika transisi pembayaran dilakukan dari `processing` menjadi `payment_failed`, tawarkan upaya lain untuk membayar kepada pelanggan.                                                                |

## Charge Metode Pembayaran tersimpan nanti [Sisi server]

> #### Kepatuhan
> 
> Anda bertanggung jawab atas kepatuhan terhadap semua hukum, peraturan, dan aturan jaringan yang berlaku saat menyimpan detail pembayaran pelanggan. Saat menampilkan metode pembayaran sebelumnya kepada pelanggan akhir untuk pembelian di masa mendatang, pastikan Anda mencantumkan metode pembayaran yang telah mendapatkan persetujuan dari pelanggan untuk menyimpan detail metode pembayaran untuk penggunaan khusus di masa mendatang. Untuk membedakan antara metode pembayaran yang dilampirkan pada pelanggan yang dapat dan tidak dapat ditampilkan kepada pelanggan akhir Anda sebagai metode pembayaran tersimpan untuk pembelian di masa mendatang, gunakan parameter [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

Untuk menemukan metode pembayaran yang akan ditagih, buatlah daftar metode pembayaran yang terkait dengan pelanggan Anda. Contoh ini menampilkan daftar kartu, namun Anda dapat mencantumkan [jenis](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) apa pun yang didukung.

> #### Menggunakan API Akun v2 untuk mewakili pelanggan
> 
> API Akun v2 umumnya tersedia untuk pengguna Connect, dan dalam pratinjau publik untuk pengguna Stripe lainnya. Jika Anda adalah bagian dari pratinjau Akun v2, Anda perlu menentukan [Tentukan versi pratinjau](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) dalam kode Anda.
> 
> Untuk meminta akses ke pratinjau Akun v2, 
> 
> Untuk sebagian besar contoh penggunaan, sebaiknya Anda [memodelkan pelanggan Anda sebagai objek Account yang dikonfigurasi pelanggan](https://docs.stripe.com/connect/use-accounts-as-customers.md) alih-alih menggunakan [Customer](https://docs.stripe.com/api/customers.md) objek.

#### Akun v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d type=card
```

#### Pelanggan v1

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d type=card
```

Saat Anda siap untuk menagih pelanggan secara off-session**, gunakan ID pelanggan dan ID `PaymentMethod` untuk membuat `PaymentIntent` dengan jumlah dan mata uang pembayaran yang sesuai. Atur beberapa parameter lainnya untuk melakukan pembayaran di luar sesi (off-session):

- Atur [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) ke `true` untuk menunjukkan bahwa pelanggan tidak berada dalam alur checkout Anda saat percobaan pembayaran dilakukan dan tidak dapat memenuhi permintaan autentikasi dari mitra, seperti penerbit kartu, bank, atau lembaga pembayaran lainnya. Jika mitra meminta autentikasi selama alur checkout, Stripe akan meminta pengecualian (exemption) menggunakan informasi pelanggan dari transaksi on-session** sebelumnya. Jika kondisi untuk pengecualian tidak terpenuhi, `PaymentIntent` mungkin akan menghasilkan kesalahan (error).
- Atur nilai properti [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) pada `PaymentIntent` ke true, agar konfirmasi terjadi segera setelah `PaymentIntent` dibuat.
- Atur [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) ke ID `PaymentMethod`.
- Bergantung pada cara Anda merepresentasikan pelanggan dalam integrasi Anda, atur [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) ke ID `Account` yang dikonfigurasi untuk pelanggan atau atur [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) ke ID `Customer`.

#### Akun v2

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

#### Pelanggan v1

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

## Uji integrasinya

#### Kartu

| Metode pembayaran | Skenario                                                                                                                                                                                                                                                                                                       | Cara mencoba                                                                                                                                    |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Kartu kredit      | Penyiapan kartu berhasil dan tidak memerlukan *autentikasi* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Isilah formulir kartu kredit menggunakan nomor kartu kredit `4242 4242 4242 4242` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos.      |
| Kartu kredit      | Kartu ini memerlukan autentikasi untuk penyiapan awal, kemudian berhasil untuk pembelian berikutnya.                                                                                                                                                                                                           | Isilah formulir kartu kredit kami menggunakan nomor kartu kredit `4000 0025 0000 3155` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos. |
| Kartu kredit      | Kartu ini memerlukan autentikasi untuk penyiapan awal dan juga memerlukan autentikasi untuk pembelian berikutnya.                                                                                                                                                                                              | Isilah formulir kartu kredit kami menggunakan nomor kartu kredit `4000 0027 6000 3184` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos. |
| Kartu kredit      | Kartu ini ditolak selama penyiapan.                                                                                                                                                                                                                                                                            | Isilah formulir kartu kredit menggunakan nomor kartu kredit `4000 0000 0000 9995` dengan sembarang tanggal kedaluwarsa, CVC, dan kode pos.      |

## Optional: Aktifkan Apple Pay

### Mendaftar Apple Merchant ID

Dapatkan Apple Merchant ID dengan [mendaftar identifier baru](https://developer.apple.com/account/resources/identifiers/add/merchant) di situs web Apple Developer.

Isi formulir dengan keterangan dan identifier. Keterangan adalah untuk catatan Anda sendiri dan nanti dapat diubah. Stripe merekomendasikan penggunaan nama aplikasi Anda sebagai identifier (misalnya, `merchant.com.{{YOUR_APP_NAME}}`).

### Buat sertifikat Apple Pay yang baru

Buat sertifikat untuk aplikasi Anda guna mengenkripsi data pembayaran.

Buka [Pengaturan Sertifikat iOS](https://dashboard.stripe.com/settings/ios_certificates) di Dashboard, klik **Tambahkan aplikasi baru**, dan ikuti panduannya.

Unduh file Permintaan Penandatanganan Sertifikat (CSR) untuk mendapatkan sertifikat aman dari Apple yang memungkinkan Anda menggunakan Apple Pay.

Satu file CSR harus digunakan untuk menerbitkan tepat satu sertifikat. Jika Anda mengganti Apple Merchant ID, Anda harus membuka [Pengaturan Sertifikat iOS](https://dashboard.stripe.com/settings/ios_certificates) di Dashboard untuk mendapatkan CSR dan sertifikat baru.

### Integrasikan dengan Xcode

Tambahkan kemampuan Apple Pay ke aplikasi Anda. Di Xcode, buka pengaturan proyek, klik tab **Signing & Capabilities**, dan tambahkan kemampuan **Apple Pay**. Pada saat ini Anda mungkin diminta untuk masuk ke akun pengembang. Pilih identifikasi merchant yang Anda buat sebelumnya, dan aplikasi Anda siap menyetujui Apple Pay.
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

Aktifkan kemampuan Apple Pay di Xcode

### Tambahkan Apple Pay

#### Pembayaran satu kali

Teruskan identifikasi merchant bila Anda membuat `StripeProvider`:

```javascript
import { StripeProvider } from '@stripe/stripe-react-native';

function App() {
  return (
    <StripeProvider
      publishableKey="<<YOUR_PUBLISHABLE_KEY>>"
      merchantIdentifier="MERCHANT_ID"
    >
      {/* Your app code here */}
    </StripeProvider>
  );
}
```

Saat Anda memanggil `initPaymentSheet`, teruskan [ApplePayParams](https://stripe.dev/stripe-react-native/api-reference/modules/PaymentSheet.html#ApplePayParams):

```javascript
await initPaymentSheet({
  // ...
  applePay: {
    merchantCountryCode: 'US',
  },
});
```

#### Pembayaran rutin

Bila Anda memanggil `initPaymentSheet`, teruskan [ApplePayParams](https://stripe.dev/stripe-react-native/api-reference/modules/PaymentSheet.html#ApplePayParams) dengan `merchantCountryCode`yang diatur ke kode negara bisnis Anda.

Sesuai dengan [pedoman Apple](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) untuk pembayaran rutin, Anda juga harus menetapkan `kartuItem` yang mencakup [RutinCartSummaryItem](https://stripe.dev/stripe-react-native/api-reference/modules/ApplePay.html#RecurringCartSummaryItem) dengan jumlah yang ingin Anda kenakan (misalnya, “59,95 USD per bulan”).

Anda juga dapat mengadopsi [token merchant](https://developer.apple.com/apple-pay/merchant-tokens/) dengan mengatur `type` di `request` ke `PaymentRequestType.Recurring`

Untuk mempelajari lebih lanjut cara menggunakan pembayaran rutin dengan Apple Pay, lihat [dokumentasi Apple PassKit](https://developer.apple.com/documentation/passkit/pkpaymentrequest).

#### iOS (React Native)

```javascript
const initializePaymentSheet = async () => {
  const recurringSummaryItem = {
    label: 'My Subscription',
    amount: '59.99',
    paymentType: 'Recurring',
    intervalCount: 1,
    intervalUnit: 'month',
    // Payment starts today
    startDate: new Date().getTime() / 1000,

    // Payment ends in one year
    endDate: new Date().getTime() / 1000 + 60 * 60 * 24 * 365,
  };

  const {error} = await initPaymentSheet({
    // ...
    applePay: {
      merchantCountryCode: 'US',
      cartItems: [recurringSummaryItem],
      request: {
        type: PaymentRequestType.Recurring,
        description: 'Recurring',
        managementUrl: 'https://my-backend.example.com/customer-portal',
        billing: recurringSummaryItem,
        billingAgreement:
          "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'",
      },
    },
  });
};
```

### Pelacakan pesanan

Untuk menambah informasi [pelacakan pesanan](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) di iOS 16 atau lebih baru, konfigurasikan fungsi callback `setOrderTracking`. Stripe memanggil implementasi Anda setelah pembayaran selesai, tetapi sebelum iOS menutup lembar Apple Pay.

Dalam implementasi fungsi callback `setOrderTracking`, ambil detail pesanan dari server Anda untuk pesanan yang sudah selesai, dan lewatkan detail ke fungsi `completion` yang disediakan.

Untuk mempelajari pelacakan pesanan selengkapnya, lihat [dokumentasi Apple’s Wallet Orders](https://developer.apple.com/documentation/walletorders).

#### iOS (React Native)

```javascript
await initPaymentSheet({
  // ...
  applePay: {
    // ...
    setOrderTracking: async complete => {
      const apiEndpoint =
        Platform.OS === 'ios'
          ? 'http://localhost:4242'
          : 'http://10.0.2.2:4567';
      const response = await fetch(
        `${apiEndpoint}/retrieve-order?orderId=${orderId}`,
        {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
          },
        },
      );
      if (response.status === 200) {
        const orderDetails = await response.json();
        // orderDetails should include orderIdentifier, orderTypeIdentifier,
        // authenticationToken and webServiceUrl
        complete(orderDetails);
      }
    },
  },
});
```

## Optional: Aktifkan Google Pay

### Siapkan integrasi Anda

Untuk menggunakan Google Pay, pertama aktifkan Google Pay API dengan menambahkan yang berikut ini ke tag `<application>` **AndroidManifest.xml** Anda:

```xml
<application>
  ...
  <meta-data
    android:name="com.google.android.gms.wallet.api.enabled"
    android:value="true" />
</application>
```

Untuk detail selengkapnya, lihat [Siapkan Google Pay API](https://developers.google.com/pay/api/android/guides/setup) untuk Android dari Google Pay.

### Tambahkan Google Pay

Bila Anda memprakarsai `PaymentSheet`, atur `merchantCountryCode` ke kode negara bisnis Anda dan atur `googlePay` ke true.

Anda juga dapat menggunakan lingkungan percobaan dengan meneruskan parameter `testEnv`. Anda hanya dapat mencoba Google Pay pada perangkat fisik Android. Ikuti [dokumen React Native](https://reactnative.dev/docs/running-on-device) untuk mencoba aplikasi Anda pada perangkat fisik.

```javascript
const { error, paymentOption } = await initPaymentSheet({
  // ...
  googlePay: {
    merchantCountryCode: 'US',
    testEnv: true, // use test environment
  },
});
```

## Aktifkan pemindaian kartu [Sisi client]

> Pengaktifan pemindaian kartu diperlukan untuk proses peninjauan aplikasi iOS Apple. Pemindaian kartu tidak diperlukan untuk proses peninjauan aplikasi Android, tetapi sebaiknya aktifkan.

### iOS

Untuk mengaktifkan dukungan pemindaian kartu untuk iOS, atur `NSCameraUsageDescription` (**Privacy - Camera Usage Description**) di dalam `Info.plist` aplikasi Anda, dan berikan alasan untuk mengakses kamera (misalnya, “Untuk memindai kartu”).

### (Opsional) Android

Untuk mengaktifkan dukungan pemindaian kartu, [minta akses produksi](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access) ke Google Pay API dari [Google Pay dan Wallet Console](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite).

- Jika Anda sudah mengaktifkan Google Pay, fitur pemindaian kartu tersedia secara otomatis di UI kami pada perangkat yang memenuhi syarat. Untuk mempelajari lebih lanjut mengenai perangkat yang memenuhi syarat, baca [Google Pay API](https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition)
- **Penting:** Fitur pemindaian kartu hanya muncul di versi yang ditandatangani dengan kunci penandatanganan yang sama yang terdaftar di [Google Pay & Wallet Console](https://pay.google.com/business/console). Pembuatan percobaan atau debug menggunakan kunci penandatanganan yang berbeda (misalnya, pembuatan yang didistribusikan melalui Firebase App Tester) tidak akan menampilkan opsi **Pindai kartu**. Untuk mencoba pemindaian kartu di versi pra-rilis, Anda harus:
  - Menandatangani build pengujian Anda dengan kunci penandatanganan produksi Anda
  - Menambahkan sidik jari kunci penandatanganan pengujian Anda ke Google Pay dan Wallet Console

## Optional: Sesuaikan lembar [Sisi client]

Semua penyesuaian dikonfigurasi menggunakan `initPaymentSheet`.

### Penampilan

Sesuaikan warna, font, dan sebagainya agar sesuai dengan tampilan dan nuansa aplikasi Anda dengan menggunakan [appearance API](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=react-native).

### Nama tampilan merchant

Tentukan nama bisnis yang dilihat pelanggan dengan mengatur `merchantDisplayName`. Secara default, ini adalah nama aplikasi Anda.

```javascript
await initPaymentSheet({
  // ...
  merchantDisplayName: 'Example Inc.',
});
```

### Mode gelap

Secara default `PaymentSheet` akan beradaptasi otomatis dengan pengaturan penampilan skala-sistem pengguna (mode terang dan gelap). Anda dapat mengubahnya dengan mengatur properti `style` ke mode `alwaysLight` atau `alwaysDark` di iOS.

```javascript
await initPaymentSheet({
  // ...
  style: 'alwaysDark',
});
```

Di Android, atur mode terang atau gelap pada aplikasi Anda:

```
// force dark
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
// force light
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
```

### Detail tagihan default

Untuk mengatur nilai default bagi detail tagihan yang dikumpulkan di PaymentSheet, konfigurasikan properti `defaultBillingDetails`. `PaymentSheet` akan melengkapi bidang-bidangnya dengan nilai yang Anda berikan.

```javascript
await initPaymentSheet({
  // ...
  defaultBillingDetails: {
      email: 'foo@bar.com',
      address: {
        country: 'US',
      },
  },
});
```

### Kumpulkan detail tagihan

Gunakan `billingDetailsCollectionConfiguration` untuk menentukan cara Anda ingin mengumpulkan detail tagihan di PaymentSheet.

Anda dapat mengumpulkan nama, email, nomor telepon, dan alamat pelanggan.

Jika tidak bermaksud untuk mengumpulkan nilai yang diperlukan oleh metode pembayaran, Anda harus melakukan hal berikut:

1. Lampirkan nilai yang tidak dikumpulkan oleh `PaymentSheet` ke properti `defaultBillingDetails`.
1. Atur `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` ke `true`.

```javascript
await initPaymentSheet({
  // ...
  defaultBillingDetails: {
    email: 'foo@bar.com',
  },
  billingDetailsCollectionConfiguration: {
    name: PaymentSheet.CollectionMode.ALWAYS,
    email: PaymentSheet.CollectionMode.NEVER,
    address: PaymentSheet.AddressCollectionMode.FULL,
    attachDefaultsToPaymentMethod: true
  },
});
```

> Konsultasikan dengan penasihat hukum mengenai undang-undang yang berlaku untuk mengumpulkan informasi. Hanya kumpulkan nomor telepon jika Anda memerlukannya untuk transaksi.

## Optional: Selesaikan pembayaran di UI Anda

Anda dapat menyajikan Lembar Pembayaran untuk hanya mengumpulkan detail metode pembayaran, kemudian memanggil metode `confirm` untuk menyelesaikan pembayaran di UI aplikasi Anda. Hal ini akan berguna jika Anda memiliki tombol beli custom atau memerlukan langkah tambahan setelah detail pembayaran dikumpulkan.
![](https://b.stripecdn.com/docs-statics-srv/assets/react-native-multi-step.84d8a0a44b1baa596bda491322b6d9fd.png)

> Sampel integrasi [tersedia di GitHub kami](https://github.com/stripe/stripe-react-native/blob/master/example/src/screens/PaymentsUICustomScreen.tsx).

1. Pertama, panggil `initPaymentSheet` dan teruskan `customFlow: true`. `initPaymentSheet` diselesaikan dengan opsi pembayaran awal yang berisi gambar dan label yang mewakili metode pembayaran pelanggan. Perbarui UI Anda dengan detail ini.

```javascript
const {
  initPaymentSheet,
  presentPaymentSheet,
  confirmPaymentSheetPayment,
} = useStripe()

const { error, paymentOption } = await initPaymentSheet({
  customerId: customer,
  customerEphemeralKeySecret: ephemeralKey,
  paymentIntentClientSecret: paymentIntent,
  customFlow: true,
  merchantDisplayName: 'Example Inc.',
});
// Update your UI with paymentOption
```

1. Gunakan `presentPaymentSheet` untuk mengumpulkan detail pembayaran. Saat pelanggan selesai, lembaran akan menutup sendiri dan menyelesaikan janjinya. Perbarui UI Anda dengan detail metode pembayaran yang dipilih.

```javascript
const { error, paymentOption } = await presentPaymentSheet();
```

1. Gunakan `confirmPaymentSheetPayment` untuk mengonfirmasi pembayaran. Ini diselesaikan dengan hasil pembayaran.

```javascript
const { error } = await confirmPaymentSheetPayment();

if (error) {
  Alert.alert(`Error code: ${error.code}`, error.message);
} else {
  Alert.alert(
    'Success',
    'Your order is confirmed!'
  );
}
```

Mengatur `allowsDelayedPaymentMethods` ke true memungkinkan metode pembayaran [pemberitahuan tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification) seperti rekening bank AS. Untuk metode pembayaran ini, status pembayaran finalnya tidak diketahui bila `PaymentSheet` selesai, dan berhasil atau gagal sebagai gantinya nanti. Jika Anda mendukung jenis pembayaran ini, informasikan kepada pelanggan bahwa pesanannya telah dikonfirmasi dan hanya memenuhi pesanan (misalnya, mengirim produknya) bila pembayaran berhasil.

