# Pembayaran Boleto Learn how to accept Boleto, a common payment method in Brazil. # Checkout > This is a Checkout for when payment-ui is checkout. View the full page at https://docs.stripe.com/payments/boleto/accept-a-payment?payment-ui=checkout. > Stripe dapat secara otomatis menyajikan metode pembayaran yang relevan kepada pelanggan Anda dengan mengevaluasi mata uang, pembatasan metode pembayaran, dan parameter lainnya. > > - Ikuti panduan [Menerima pembayaran](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=checkout&ui=stripe-hosted) untuk membangun integrasi Checkout yang menggunakan [metode pembayaran dinamis](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). - Jika Anda tidak ingin menggunakan metode pembayaran dinamis, ikuti langkah-langkah di bawah ini untuk mengonfigurasi metode pembayaran secara manual dalam integrasi Checkout Anda. Boleto is a [single use](https://docs.stripe.com/payments/payment-methods.md#usage) payment method where customers are required to [take additional steps](https://docs.stripe.com/payments/payment-methods.md#customer-actions) to complete their payment. *Customers* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) pay by using a Boleto voucher with a generated number either in ATMs, banks, bank portals or authorized agencies. ## Menentukan kompatibilitas **Lokasi bisnis yang didukung**: BR **Mata uang yang didukung**: `brl` **Mata uang transaksi**: `brl` **Mode pembayaran**: Yes **Mode persiapan**: No **Mode langganan**: Yes A Checkout Session must satisfy the following condition to support Boleto payments: - *Prices* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) untuk semua mata anggaran harus dalam mata uang yang sama. Jika Anda memiliki mata anggaran dalam mata uang berbeda, buat Sesi Checkout terpisah untuk setiap mata uang. ## Menerima pembayaran > Buat integrasi untuk [menerima pembayaran](https://docs.stripe.com/payments/accept-a-payment.md?integration=checkout) dengan Checkout sebelum menggunakan panduan ini. This guides you through enabling Boleto and shows the differences between accepting payments using dynamic payment methods and manually configuring payment methods. ### Mengaktifkan Boleto sebagai metode pembayaran Saat membuat [Sesi Checkout](https://docs.stripe.com/api/checkout/sessions.md) baru, Anda perlu: 1. Add `boleto` to the list of `payment_method_types`. 1. Pastikan semua `line_items` Anda menggunakan mata uang `brl`. #### Halaman yang di-hosting Stripe ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=brl" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=boleto" \ --data-urlencode "success_url=https://example.com/success" ``` #### Full embedded page ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=brl" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=boleto" \ --data-urlencode "return_url=https://example.com/return" \ -d ui_mode=embedded_page ``` ### Opsi metode pembayaran tambahan You can specify an optional `expires_after_days` parameter in the [payment method options](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_method_options-boleto-expires_after_days) for your `Session` that sets the number of calendar days before a Boleto voucher expires. For example, if you create a Boleto voucher on Monday and you set `expires_after_days` to 2, the Boleto voucher expires on Wednesday at 23:59 America/Sao_Paulo (UTC-3) time. If you set it to 0, the Boleto voucher expires at the end of the day. The `expires_after_days` parameter can be set from 0 to 60 days. The default is 3 days. You can customize the default expiration days on your account in the [Payment methods settings](https://dashboard.stripe.com/settings/payment_methods). #### Halaman yang di-hosting Stripe ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=brl" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_options[boleto][expires_after_days]=7" \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=boleto" \ --data-urlencode "success_url=https://example.com/success" ``` #### Full embedded page ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=brl" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_options[boleto][expires_after_days]=7" \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=boleto" \ --data-urlencode "return_url=https://example.com/return" \ -d ui_mode=embedded_page ``` ### Mengarahkan ulang ke halaman voucher yang di-hosting dari Stripe > Unlike card payments, the customer won’t be redirected to the [success_url](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-success_url) with Boleto payment. After submitting the Checkout form successfully, the customer is redirected to the `hosted_voucher_url`. The customer can copy the Boleto number or download the voucher PDF from the hosted voucher page. Stripe sends a [payment_intent.requires_action](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.requires_action) event when a Boleto voucher is created successfully. If you need to email your customers the voucher link, you can locate the `hosted_voucher_url` in [payment_intent.next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-hosted_voucher_url). Learn more about how to [monitor a PaymentIntent with webhooks](https://docs.stripe.com/payments/payment-intents/verifying-status.md#webhooks). Stripe mengizinkan penyesuaian UI yang dilihat pelanggan di halaman [Pengaturan Branding](https://dashboard.stripe.com/account/branding). Pengaturan brand berikut dapat diterapkan ke voucher: - **Ikon**—gambar brand dan nama umum bisnis Anda - **Warna aksen**—digunakan sebagai warna tombol Salin Nomor - **Warna brand**—digunakan sebagai warna latar belakang ### Penuhi pesanan Anda Because Boleto is a delayed notification payment method, you need to use a method such as *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) to monitor the payment status and handle order *fulfillment* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected). Learn more about [setting up webhooks and fulfilling orders](https://docs.stripe.com/checkout/fulfillment.md). Kejadian berikut dikirim ketika status pembayaran berubah: | Nama Kejadian | Keterangan | Langkah berikutnya | | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | The customer has successfully submitted the Checkout form. Stripe has generated the Boleto voucher. You can choose to email the `hosted_voucher_url` to your customer in case they lose the Boleto voucher. | Wait for the customer to pay the Boleto. | | [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) | The customer has successfully paid the Boleto. The `PaymentIntent` transitions to `succeeded`. | Penuhi barang atau layanan yang dibeli oleh pelanggan. | | [checkout.session.async_payment_failed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_failed) | The Boleto voucher has expired, or the payment has failed for some other reason. The `PaymentIntent` returns to a status of `requires_payment_method`. | Contact the customer through email and request that they place a new order. | ## Coba integrasi Anda Saat mencoba integrasi Checkout Anda, pilih Boleto sebagai metode pembayaran dan klik tombol **Bayar**. | Email | Keterangan | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | Simulates a Boleto voucher which a customer pays after 3 minutes and the `payment_intent.succeeded` webhook arrives after about 3 minutes. In production, this webhook arrives 1 business day after a payment. Example: fulaninho@example.com | | `{any_prefix}succeed_immediately@{any_domain}` | Simulates a Boleto voucher which a customer pays immediately and the `payment_intent.succeeded` webhook arrives within several seconds. In production, this webhook arrives 1 business day after a payment. Example: succeed_immediately@example.com | | `{any_prefix}expire_immediately@{any_domain}` | Simulates a Boleto voucher which expires before a customer pays and the `payment_intent.payment_failed` webhook arrives within several seconds. The `expires_at` field in [next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-expires_at) is set to the current time regardless of what the `expires_after_days` parameter in [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-boleto-expires_after_days) is set to. Example: expire_immediately@example.com | | `{any_prefix}expire_with_delay@{any_domain}` | Simulates a Boleto voucher which expires before a customer pays and the `payment_intent.payment_failed` webhook arrives after about 3 minutes. The `expires_at` field in [next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-expires_at) is set to 3 minutes in the future regardless of what the `expires_after_days` parameter in [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-boleto-expires_after_days) is set to. Example: expire_with_delay@example.com | | `{any_prefix}fill_never@{any_domain}` | Simulates a Boleto voucher which never succeeds; it expires according to the `expires_at` field in [next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-expires_at) per the provided parameters in the [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-boleto-expires_after_days) and the `payment_intent.payment_failed` webhook arrives after that. Example: fill_never@example.com | | ID Pajak | Keterangan | | ------------------------------------------------- | --------------------------------------------------------------------------------- | | CPF `000.000.000-00` CNPJ `00.000.000/0000-00` | In a sandbox, set `tax_id` to these values, so they bypass the tax ID validation. | ## Handle refunds Pembayaran Boleto tidak dapat dikembalikan dananya. Beberapa merchant telah membuat proses terpisah untuk menghargai pelanggan mereka yang menghubungi secara langsung. ## Handle disputes Pembayaran Boleto tidak dapat dipersengketakan oleh pelanggan. ## Optional: Kirim email instruksi pembayaran You can enable Boleto payment instruction emails on the [Email Settings](https://dashboard.stripe.com/settings/emails) page in the Dashboard. Once enabled, Stripe sends payment instruction emails upon PaymentIntent confirmation. The emails contain the Boleto number and a link to the Stripe hosted voucher page. > In test environments, instruction emails are only sent to email addresses linked to the Stripe account. ## See also - [Checkout fulfillment](https://docs.stripe.com/checkout/fulfillment.md) - [Customizing Checkout](https://docs.stripe.com/payments/checkout/customization.md) # Checkout Sessions API > This is a Checkout Sessions API for when payment-ui is elements and api-integration is checkout. View the full page at https://docs.stripe.com/payments/boleto/accept-a-payment?payment-ui=elements&api-integration=checkout. To determine which API meets your business needs, see the [comparison guide](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md). Use the [Payment Element](https://docs.stripe.com/payments/payment-element.md) to embed a custom Stripe payment form in your website or application and offer payment methods to customers. For advanced configurations and customizations, refer to the [Accept a Payment](https://docs.stripe.com/payments/accept-a-payment.md) integration guide. ## Determine compatibility **Lokasi bisnis yang didukung**: BR **Mata uang yang didukung**: `brl` **Mata uang transaksi**: `brl` **Mode pembayaran**: Yes **Mode persiapan**: No **Mode langganan**: Yes A Checkout Session must satisfy all of the following conditions to support Boleto payments: - Harga untuk semua mata anggaran harus dalam mata uang yang sama. Jika Anda memiliki mata anggaran dalam mata uang berbeda, buat Sesi Checkout terpisah untuk setiap mata uang. ## Set up the server [Server-side] Gunakan pustaka Stripe resmi untuk mengakses API dari aplikasi 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' ``` ## Create a Checkout Session [Server-side] Tambahkan endpoint pada server yang membuat [Sesi Checkout](https://docs.stripe.com/api/checkout/sessions/create.md) dan mengembalikan [client secret](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) ke frontend Anda. Sesi Checkout mewakili sesi pelanggan Anda saat mereka membayar langganan atau pembelian satu kali. Sesi Checkout akan kedaluwarsa dalam waktu 24 jam setelah pembuatan. We recommend using [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md) to dynamically display the most relevant eligible payment methods to each customer to maximize conversion. You can also [manually list payment methods](https://docs.stripe.com/payments/payment-methods/integration-options.md#listing-payment-methods-manually), which disables dynamic payment methods. #### Kelola metode pembayaran dari Dashboard #### TypeScript ```javascript import express, {Express} from 'express'; const app: Express = express(); app.post('/create-checkout-session', async (req: Express.Request, res: Express.Response) => { const session = await stripe.checkout.sessions.create({ line_items: [ { price_data: { currency: 'brl', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', ui_mode: 'elements', return_url: 'https://example.com/return?session_id={CHECKOUT_SESSION_ID}' }); res.json({checkoutSessionClientSecret: session.client_secret}); }); app.listen(3000, () => { console.log('Running on port 3000'); }); ``` #### Manually list payment methods #### TypeScript ```javascript import express, {Express} from 'express'; const app: Express = express(); app.post('/create-checkout-session', async (req: Express.Request, res: Express.Response) => { const session = await stripe.checkout.sessions.create({ line_items: [ { price_data: { currency: 'brl', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', ui_mode: 'elements', payment_method_types: ['boleto'], return_url: 'https://example.com/return?session_id={CHECKOUT_SESSION_ID}' }); res.json({checkoutSessionClientSecret: session.client_secret}); }); app.listen(3000, () => { console.log('Running on port 3000'); }); ``` ## Siapkan frontend [Client-side] #### HTML + JS Sertakan skrip Stripe.js pada halaman checkout dengan menambahkannya ke `head` file HTML Anda. Selalu muat Stripe.js secara langsung dari js.stripe.com agar tetap mematuhi PCI. Jangan menyertakan skrip dalam paket atau meng-hosting sendiri salinannya. Make sure you’re on the latest Stripe.js version by including the following script tag ``. Learn more about [Stripe.js versioning](https://docs.stripe.com/sdks/stripejs-versioning.md). ```html Checkout ``` > Stripe menyediakan paket npm yang dapat Anda gunakan untuk memuat Stripe.js sebagai modul. Lihat [proyek di GitHub](https://github.com/stripe/stripe-js). Versi [7.0.0](https://www.npmjs.com/package/%40stripe/stripe-js/v/7.0.0) atau yang lebih baru diperlukan. Initialize stripe.js. ```js // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe( '<>', ); ``` #### React Install [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) and the [Stripe.js loader](https://www.npmjs.com/package/@stripe/stripe-js) from the npm public registry. You need at least version 5.0.0 for React Stripe.js and version 8.0.0 for the Stripe.js loader. ```bash npm install --save @stripe/react-stripe-js@^5.0.0 @stripe/stripe-js@^8.0.0 ``` Inisialisasikan instance `stripe` pada frontend Anda dengan kunci yang dapat dipublikasikan. ```javascript import {loadStripe} from '@stripe/stripe-js'; const stripe = loadStripe("<>"); ``` ## Initialize Checkout [Client-side] #### HTML + JS Panggilan [initCheckoutElementsSdk](https://docs.stripe.com/js/custom_checkout/init), masuk `clientRahasia`. `initCheckoutElementsSdk` mengembalikan [Checkout](https://docs.stripe.com/js/custom_checkout) objek yang berisi data dari Sesi Checkout dan metode untuk memperbaruinya. Baca `total` dan `lineItems` dari [actions.getSession()](https://docs.stripe.com/js/custom_checkout/session), dan tampilkan di UI Anda. Dengan begitu, Anda dapat mengaktifkan fitur baru dengan perubahan kode minimum. Misalnya, menambahkan [manual currency prices](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) tidak memerlukan perubahan UI jika Anda menampilkan `total`. ```html
``` ```javascript const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const session = loadActionsResult.actions.getSession(); const checkoutContainer = document.getElementById('checkout-container'); checkoutContainer.append(JSON.stringify(session.lineItems, null, 2)); checkoutContainer.append(document.createElement('br')); checkoutContainer.append(`Total: ${session.total.total.amount}`); } ``` #### React Bungkus aplikasi Anda dengan komponen [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider), yang meneruskan `clientSecret` dan instans `stripe`. ```jsx import React from 'react'; import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const App = () => { return ( ); }; export default App; ``` Akses objek [Checkout](https://docs.stripe.com/js/custom_checkout) di komponen formulir checkout Anda dengan menggunakan hook `useCheckoutElements()`. Objek `Checkout` berisi data dari Sesi Checkout dan metode untuk memperbaruinya. Baca `total` dan `lineItems` dari objek `Checkout` dan tampilkan keduanya di UI Anda. Dengan begitu, Anda dapat mengaktifkan fitur dengan perubahan kode minimum. Misalnya, menambahkan [manual currency prices](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) tidak memerlukan perubahan UI jika Anda menampilkan `total`. ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => {const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount}
); }; ``` ## Collect customer email [Client-side] #### HTML + JS Anda harus memberikan email pelanggan yang valid saat menyelesaikan Sesi Checkout. Petunjuk ini membuat input email dan menggunakan [updateEmail](https://docs.stripe.com/js/custom_checkout/update_email) dari objek `Checkout`. Atau, Anda dapat: - Teruskan [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email), [customer_account](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_account) (untuk pelanggan yang direpresentasikan sebagai objek `Account` yang dikonfigurasi pelanggan), atau [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) (untuk pelanggan yang direpresentasikan sebagai objek `Customer`) saat membuat Sesi Checkout. Stripe memvalidasi email yang diberikan dengan cara ini. - Meneruskan email yang sudah Anda validasi [checkout.confirm](https://docs.stripe.com/js/custom_checkout/confirm). ```html
``` ```javascript const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const emailInput = document.getElementById('email'); const emailErrors = document.getElementById('email-errors'); emailInput.addEventListener('input', () => { // Clear any validation errors emailErrors.textContent = ''; }); emailInput.addEventListener('blur', () => { const newEmail = emailInput.value;actions.updateEmail(newEmail).then((result) => { if (result.error) { emailErrors.textContent = result.error.message; } }); }); } ``` #### React Anda harus memberikan email pelanggan yang valid saat menyelesaikan Sesi Checkout. Petunjuk ini membuat input email dan menggunakan [updateEmail](https://docs.stripe.com/js/react_stripe_js/checkout/update_email) dari objek `Checkout`. Atau, Anda dapat: - Teruskan [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email), [customer_account](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_account) (untuk pelanggan yang direpresentasikan sebagai objek `Account` yang dikonfigurasi pelanggan), atau [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) (untuk pelanggan yang direpresentasikan sebagai objek `Customer`) saat membuat Sesi Checkout. Stripe memvalidasi email yang diberikan dengan cara ini. - Meneruskan email yang sudah Anda validasi di [confirm](https://docs.stripe.com/js/react_stripe_js/checkout/confirm). ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const EmailInput = () => { const checkoutState = useCheckoutElements(); const [email, setEmail] = React.useState(''); const [error, setError] = React.useState(null); if (checkoutState.type === 'loading') { return (
Loading...
); } else if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } const handleBlur = () => {checkoutState.checkout.updateEmail(email).then((result) => { if (result.type === 'error') { setError(result.error); } }) }; const handleChange = (e) => { setError(null); setEmail(e.target.value); }; return (
{error &&
{error.message}
}
); }; export default EmailInput; ``` ## Collect payment details [Client-side] Kumpulkan detail pembayaran pada client dengan [Payment Element](https://docs.stripe.com/payments/payment-element.md). Payment Element adalah komponen UI siap-rakit yang menyederhanakan pengumpulan detail pembayaran untuk berbagai metode pembayaran. Payment Element berisi iframe yang mengirimkan informasi pembayaran dengan aman ke Stripe melalui koneksi HTTPS. Hindari penempatan Payment Element dalam iframe lain karena sejumlah metode pembayaran memerlukan pengalihan ke halaman lain untuk konfirmasi pembayaran. Jika Anda memilih untuk menggunakan iframe dan ingin menerima Apple Pay atau Google Pay, iframe harus memiliki atribut [allow](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allowpaymentrequest) yang ditetapkan ke `"payment *"` setara. Alamat halaman checkout harus dimulai dengan `https://` rather daripada `http://` for integrasi Anda untuk bekerja. Anda dapat menguji integrasi tanpa menggunakan HTTPS, tetapi jangan lupa [mengaktifkannya](https://docs.stripe.com/security/guide.md#tls) saat Anda siap menerima pembayaran langsung. #### HTML + JS Pertama, buat elemen DOM kontainer untuk memasang [Payment Element](https://docs.stripe.com/payments/payment-element.md). Kemudian buat instance `Payment Element` menggunakan [checkout.createPaymentElement](https://docs.stripe.com/js/custom_checkout/create_payment_element) dan pasang dengan memanggil [element.mount](https://docs.stripe.com/js/element/mount), yang menyediakan pemilih CSS atau elemen DOM kontainer. ```html
``` ```javascript const paymentElement = checkout.createPaymentElement(); paymentElement.mount('#payment-element'); ``` Lihat [dokumen Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) untuk melihat opsi yang didukung. Anda dapat [menyesuaikan penampilan](https://docs.stripe.com/payments/checkout/customization/appearance.md) semua Elements dengan meneruskan [elementsOptions.appearance](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-appearance) ketika menginisialisasi Checkout pada frontend. #### React Pasang komponen [Payment Element](https://docs.stripe.com/payments/payment-element.md) dalam [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider). ```jsx import React from 'react';import {PaymentElement, useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount} ); }; export default CheckoutForm; ``` Lihat [dokumen Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) untuk melihat opsi yang didukung. Anda bisa [menyesuaikan tampilan](https://docs.stripe.com/payments/checkout/customization/appearance.md) dari semua Element dengan meneruskan [elementsOptions.appearance](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-appearance) ke [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider). ## Submit the payment [Client-side] #### HTML + JS Menampilkan tombol **Bayar** yang memanggil [konfirmasi](https://docs.stripe.com/js/custom_checkout/confirm) dari instance `Checkout` untuk menyerahkan pembayaran. ```html
``` ```js const checkout = stripe.initCheckoutElementsSdk({clientSecret}); checkout.on('change', (session) => { document.getElementById('pay-button').disabled = !session.canConfirm; }); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; actions.confirm().then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); } ``` #### React Tampilkan tombol **Bayar** yang memanggil [confirm](https://docs.stripe.com/js/custom_checkout/confirm) dari [useCheckoutElements](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout_elements) untuk mengirimkan pembayaran. ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const PayButton = () => { const checkoutState = useCheckoutElements(); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); if (checkoutState.type !== "success") { return null; } const handleClick = () => { setLoading(true);checkoutState.checkout.confirm().then((result) => { if (result.type === 'error') { setError(result.error) } setLoading(false); }) }; return (
{error &&
{error.message}
}
) }; export default PayButton; ``` ## Test your integration To test your integration, choose the payment method and tap **Pay**. In a *sandbox* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes), this redirects you to a test payment page where you can approve or decline the payment. In live mode, tapping **Pay** redirects you to the boleto website—you don’t have the option to approve or decline the payment with boleto. # Payment Intents API > This is a Payment Intents API for when payment-ui is elements and api-integration is paymentintents. View the full page at https://docs.stripe.com/payments/boleto/accept-a-payment?payment-ui=elements&api-integration=paymentintents. To determine which API meets your business needs, see the [comparison guide](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md). Use the [Payment Element](https://docs.stripe.com/payments/payment-element.md) to embed a custom Stripe payment form in your website or application and offer payment methods to customers. For advanced configurations and customizations, refer to the [Accept a Payment](https://docs.stripe.com/payments/accept-a-payment.md) integration guide. ## Set up Stripe [Server-side] To get started, [create a Stripe account](https://dashboard.stripe.com/register). Gunakan pustaka resmi kami untuk mendapatkan akses ke API Stripe dari aplikasi 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' ``` ## Collect payment details [Client-side] Anda siap mengumpulkan detail pembayaran pada klien dengan Payment Element. Payment Element adalah komponen UI bawaan yang menyederhanakan pengumpulan detail pembayaran untuk berbagai metode pembayaran. Payment Element berisi iframe yang mengirimkan informasi pembayaran dengan aman ke Stripe melalui koneksi HTTPS. Hindari penempatan Payment Element dalam iframe lain karena sejumlah metode pembayaran memerlukan pengalihan ke halaman lain untuk konfirmasi pembayaran. The checkout page address must start with `https://` rather than `http://` for your integration to work. You can test your integration without using HTTPS, but remember to [enable it](https://docs.stripe.com/security/guide.md#tls) when you’re ready to accept live payments. #### HTML + JS ### Siapkan Stripe.js Payment Element secara otomatis tersedia sebagai fitur Stripe.js. Sertakan skrip Stripe.js di halaman checkout Anda dengan menambahkannya ke `head` di file HTML. Selalu muat Stripe.js secara langsung dari js.stripe.com agar tetap mematuhi PCI. Jangan sertakan skrip dalam paket atau meng-host sendiri salinannya. ```html Checkout ``` Buat instance Stripe dengan JavaScript berikut di halaman checkout Anda: ```javascript // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe('<>'); ``` ### Tambahkan Payment Element ke halaman pembayaran Anda The Payment Element needs a place on your checkout page. Create an empty DOM node (container) with a unique ID in your payment form: ```html
``` #### Control payment methods from the Dashboard After the form above loads, create an Elements instance with a `mode`, `amount`, and `currency`. These values determine which payment methods your customer sees. To provide a new payment method in your form, make sure you enable it in the [Dashboard](https://dashboard.stripe.com/settings/payment_methods). ```javascript const options = {mode:'payment', amount:2000, currency: 'brl', // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout formconst elements = stripe.elements(options); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` #### Cantumkan metode pembayaran secara manual To manually list the payment methods you want to be available, add each one to `paymentMethodTypes`. Kemudian, buat instance Payment Element dan pasang ke simpul DOM penampung. ```javascript const options = {mode:'payment', amount:2000, currency: 'brl', paymentMethodTypes: ['boleto'], // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout formconst elements = stripe.elements(options); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` #### React ### Siapkan Stripe.js Install [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) and the [Stripe.js loader](https://www.npmjs.com/package/@stripe/stripe-js) from the npm public registry. ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` ### Tambahkan dan konfigurasikan penyedia Elements ke halaman checkout Anda To use the Payment Element component, wrap your checkout page component in an [Elements provider](https://docs.stripe.com/sdks/stripejs-react.md#elements-provider). Call `loadStripe` with your publishable key, and pass the returned `Promise` to the `Elements` provider. #### Control payment methods from the Dashboard The `Elements` provider also accepts a `mode`, `amount`, and `currency`. These values determine which payment methods your customer sees. To provide a new payment method in your form, make sure you enable it in the [Dashboard](https://dashboard.stripe.com/settings/payment_methods). ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('<>'); function App() { const options = {mode:'payment', amount:2000, currency: 'brl', // Fully customizable with appearance API. appearance: {/*...*/}, }; return ( ); }; ReactDOM.render(, document.getElementById('root')); ``` #### Cantumkan metode pembayaran secara manual ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('<>'); function App() { const options = {mode:'payment', amount:2000, currency: 'brl', paymentMethodTypes: ['boleto'], // Fully customizable with appearance API. appearance: {/*...*/}, }; return ( ); }; ReactDOM.render(, document.getElementById('root')); ``` ### Tambahkan komponen Payment Element Gunakan komponen `PaymentElement` untuk membuat formulir Anda. ```jsx import React from 'react'; import {PaymentElement} from '@stripe/react-stripe-js'; const CheckoutForm = () => { return (
); }; export default CheckoutForm; ``` You can customize the Payment Element to match the design of your site by passing the [appearance object](https://docs.stripe.com/elements/appearance-api.md) into `options` when creating the `Elements` provider. ### Kumpulkan alamat Secara default, Payment Element hanya mengumpulkan detail alamat penagihan yang diperlukan. Beberapa perilaku, seperti [menghitung pajak](https://docs.stripe.com/api/tax/calculations/create.md) atau memasukkan detail pengiriman, memerlukan alamat lengkap pelanggan Anda. Anda dapat melakukannya: - Gunakan [Address Element](https://docs.stripe.com/elements/address-element.md) untuk memanfaatkan fitur pelengkapan otomatis dan pelokalan untuk mengumpulkan alamat lengkap pelanggan Anda. Hal ini membantu memastikan penghitungan pajak yang paling akurat. - Kumpulkan detail alamat menggunakan formulir khusus Anda sendiri. ## Create a PaymentIntent [Server-side] > #### Jalankan logika bisnis custom segera sebelum konfirmasi pembayaran > > Navigate to [step 5](https://docs.stripe.com/payments/finalize-payments-on-the-server.md?platform=web&type=payment#submit-payment) in the finalize payments guide to run your custom business logic immediately before payment confirmation. Otherwise, follow the steps below for a simpler integration, which uses `stripe.confirmPayment` on the client to both confirm the payment and handle any next actions. #### Control payment methods from the Dashboard When the customer submits your payment form, use a *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) to facilitate the confirmation and payment process. Create a PaymentIntent on your server with an `amount` and `currency`. To prevent malicious customers from choosing their own prices, always decide how much to charge on the server-side (a trusted environment) and not the client. A `PaymentIntent` includes a *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)). Return this value to your client for Stripe.js to use to securely complete the payment process. #### Accounts v2 #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do intent = client.v1.payment_intents.create({ # To allow saving and retrieving payment methods, provide the customer's Account ID. customer_account: "{{CUSTOMER_ACCOUNT_ID}}", amount: 2000, currency: 'brl', }) {client_secret: intent.client_secret}.to_json end ``` #### Customers v1 #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do intent = client.v1.payment_intents.create({ # To allow saving and retrieving payment methods, provide the Customer ID. customer: customer.id, amount: 2000, currency: 'brl', }) {client_secret: intent.client_secret}.to_json end ``` #### Cantumkan metode pembayaran secara manual When the customer submits your payment form, use a *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) to facilitate the confirmation and payment process. Create a PaymentIntent on your server with an `amount`, `currency`, and one or more payment methods using `payment_method_types`. To prevent malicious customers from choosing their own prices, always decide how much to charge on the server-side (a trusted environment) and not the client. Termasuk dalam PaymentIntent adalah *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)). Kembalikan nilai ini ke klien Anda agar Stripe.js dapat digunakan untuk menyelesaikan proses pembayaran dengan aman. #### Accounts v2 #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do intent = client.v1.payment_intents.create({ # To allow saving and retrieving payment methods, provide the customer's Account ID. customer_account: customer_account.id, amount: 2000, currency: 'brl', payment_method_types: ['boleto'], }) {client_secret: intent.client_secret}.to_json end ``` #### Customers v1 #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do intent = client.v1.payment_intents.create({ # To allow saving and retrieving payment methods, provide the Customer ID. customer: customer.id, amount: 2000, currency: 'brl', payment_method_types: ['boleto'], }) {client_secret: intent.client_secret}.to_json end ``` ## Serahkan pembayaran ke Stripe [Client-side] Use [stripe.confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) to complete the payment using details from the Payment Element. Provide a [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) to this function to indicate where Stripe redirects the user after they complete the payment. Your user might be initially redirected to an intermediate site, such as a bank authorization page, before being redirected to the `return_url`. Card payments immediately redirect to the `return_url` when a payment is successful. If you don’t want to redirect for card payments after payment completion, you can set [redirect](https://docs.stripe.com/js/payment_intents/confirm_payment#confirm_payment_intent-options-redirect) to `if_required`. This only redirects customers that check out with redirect-based payment methods. #### HTML + JS ```javascript const form = document.getElementById('payment-form'); const submitBtn = document.getElementById('submit'); const handleError = (error) => { const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; submitBtn.disabled = false; } form.addEventListener('submit', async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); // Prevent multiple form submissions if (submitBtn.disabled) { return; } // Disable form submission while loading submitBtn.disabled = true; // Trigger form validation and wallet collection const {error: submitError} = await elements.submit(); if (submitError) { handleError(submitError); return; } // Create the PaymentIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", }); const {client_secret: clientSecret} = await res.json(); // Confirm the PaymentIntent using the details collected by the Payment Element const {error} = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point is only reached if there's an immediate error when // confirming the payment. Show the error to your customer (for example, payment details incomplete) handleError(error); } else { // Your customer is redirected to your `return_url`. For some payment // methods like iDEAL, your customer is redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } }); ``` #### React ```jsx import React, {useState} from 'react'; import {useStripe, useElements, PaymentElement} from '@stripe/react-stripe-js'; export default function CheckoutForm() { const stripe = useStripe(); const elements = useElements(); const [errorMessage, setErrorMessage] = useState(); const [loading, setLoading] = useState(false); const handleError = (error) => { setLoading(false); setErrorMessage(error.message); } const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } setLoading(true); // Trigger form validation and wallet collection const {error: submitError} = await elements.submit(); if (submitError) { handleError(submitError); return; } // Create the PaymentIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", }); const {client_secret: clientSecret} = await res.json(); // Confirm the PaymentIntent using the details collected by the Payment Element const {error} = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point is only reached if there's an immediate error when // confirming the payment. Show the error to your customer (for example, payment details incomplete) handleError(error); } else { // Your customer is redirected to your `return_url`. For some payment // methods like iDEAL, your customer is redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } }; return (
{errorMessage &&
{errorMessage}
} ); } ``` ## Optional: Tangani kejadian pascapembayaran Stripe mengirim kejadian [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) ketika selesai pembayaran. Gunakan Dashboard, *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) custom, atau solusi mitra untuk menerima kejadian ini dan menjalankan tindakan, seperti mengirim email konfirmasi pesanan kepada pelanggan Anda, mencatat penjualan di database, atau memulai alur kerja pengiriman. Mendengarkan kejadian ini daripada menunggu callback dari client. Di client, pelanggan dapat menutup jendela browser atau keluar dari aplikasi sebelum callback mengeksekusi, dan client jahat dapat memanipulasi respons. Penyiapan integrasi untuk mendengarkan kejadian asinkron juga membantu Anda menerima lebih banyak metode pembayaran di masa mendatang. Pelajari tentang [perbedaan antara semua metode pembayaran yang didukung](https://stripe.com/payments/payment-methods-guide). - **Tangani event secara manual di Dashboard** Gunakan Dashboard untuk [Melihat pembayaran uji coba Anda di Dashboard](https://dashboard.stripe.com/test/payments), mengirim tanda terima email, menangani pencairan dana, atau mencoba kembali pembayaran yang gagal. - **Buat webhook kustom** [Bangun handler webhook kustom](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) untuk memantau peristiwa dan menyusun alur pembayaran asinkron kustom. Uji dan lakukan debug integrasi webhook Anda secara lokal menggunakan Stripe CLI. - **Integrasikan aplikasi siap pakai** Tangani event bisnis umum, seperti [otomatisasi](https://stripe.partners/?f_category=automation) atau [pemasaran dan penjualan](https://stripe.partners/?f_category=marketing-and-sales), dengan mengintegrasikan aplikasi mitra. ## Test your integration To test your integration, choose the payment method and tap **Pay**. In a *sandbox* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes), this redirects you to a test payment page where you can approve or decline the payment. In live mode, tapping **Pay** redirects you to the boleto website—you don’t have the option to approve or decline the payment with boleto. ## Error codes The following table details common error codes and recommended actions: | Kode kesalahan | Recommended action | | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent_invalid_currency` | Enter a supported currency. | | `missing_required_parameter` | Check the error message for more information about the required parameter. | | `payment_intent_payment_attempt_failed` | This code can appear in the [last_payment_error.code](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-code) field of a PaymentIntent. Check the error message for a detailed failure reason and suggestion on error handling. | | `payment_intent_authentication_failure` | This code can appear in the [last_payment_error.code](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-code) field of a PaymentIntent. Check the error message for a detailed failure reason and suggestion on error handling. This error occurs when you manually trigger a failure when testing your integration. | | `payment_intent_redirect_confirmation_without_return_url` | Provide a `return_url` when confirming a PaymentIntent. | # Direct API > This is a Direct API for when payment-ui is direct-api. View the full page at https://docs.stripe.com/payments/boleto/accept-a-payment?payment-ui=direct-api. Pengguna Stripe di Brasil dapat menerima pembayaran Boleto dari pelanggan di Brasil dengan menggunakan Payment Intents API dan Payment Methods API. *Pelanggan* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) membayar menggunakan voucher Boleto dengan nomor yang bisa dibuat di ATM, bank, portal bank, atau agen resmi. ## Siapkan Stripe [Sisi server] Pertama, Anda membutuhkan akun Stripe. [Daftar sekarang](https://dashboard.stripe.com/register). Gunakan pustaka resmi kami untuk mendapatkan akses ke Stripe API dari aplikasi 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' ``` ## Buat PaymentIntent [Sisi server] Stripe uses a [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) object to represent your intent to collect payment from a customer, tracking state changes from Boleto voucher creation to payment completion. Create a PaymentIntent on your server with an amount and the `brl` currency (Boleto doesn’t support other currencies). If you already have an integration using the [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md), add `boleto` to the list of [payment method types](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types) for your `PaymentIntent`. Included in the returned PaymentIntent is a *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)), which you have to use to securely complete the payment process. Send the client secret back to the client so you can use it in later steps. ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=brl \ -d "payment_method_types[]=boleto" ``` ### Opsi metode pembayaran tambahan You can specify an optional `expires_after_days` parameter in the [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-boleto-expires_after_days) for your `PaymentIntent` that sets the number of calendar days before a Boleto voucher expires. For example, if you create a Boleto voucher on Monday and you set `expires_after_days` to 2, the Boleto voucher will expire on Wednesday at 23:59 America/Sao_Paulo (UTC-3) time. If you set it to 0, the Boleto voucher will expire at the end of the day. The `expires_after_days` parameter can be set from 0 to 60 days. The default is 3 days. You can customize the default expiration days on your account in the [Payment methods settings](https://dashboard.stripe.com/settings/payment_methods) ## Kumpulkan detail metode pembayaran [Sisi client] Buat formulir pembayaran pada client Anda untuk mengumpulkan detail tagihan yang diperlukan dari pelanggan: | Bidang | Nilai | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `name` | Nama lengkap pelanggan. | | `email` | Alamat email pelanggan. | | `tax_id` | CPF (untuk perorangan) atau CNPJ (untuk bisnis) pelanggan. CPF harus berisi 11 angka dalam salah satu format berikut: `000.000.000-00` atau `00000000000`. CNPJ harus berisi 14 angka dalam salah satu format berikut: `00.000.000/0000-00` atau `00000000000000`. | | `address` | Nama jalan dan nomor alamat pelanggan. | | `city` | Kota alamat pelanggan. | | `state` | Kode negara bagian Brasil dua huruf ([ISO_3166-2:BR](https://en.wikipedia.org/wiki/ISO_3166-2:BR)) dari alamat pelanggan. | | `postal_code` | Kode pos alamat pelanggan. Kode pos harus dalam salah satu format berikut: `XXXXX-XXX` atau `XXXXXXXX`. | > Bidang-bidang `name`, `address`, `city` ini minimal harus mengandung satu karakter huruf dan angka dari [Blok Unicode Dasar Huruf Latin (ASCII)](https://en.wikipedia.org/wiki/Basic_Latin_\(Unicode_block\)). ```html
``` ## Serahkan pembayaran ke Stripe [Sisi client] When a customer clicks to pay with Boleto, use Stripe.js to submit the payment to Stripe. [Stripe.js](https://docs.stripe.com/payments/elements.md) is our foundational JavaScript library for building payment flows. Sertakan skrip Stripe.js di halaman checkout dengan menambahkannya ke `head` file HTML Anda. ```html Checkout ``` Buat instance Stripe.js dengan JavaScript berikut di halaman checkout Anda. ```javascript // Set your publishable key. Remember to switch to your live publishable key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe('<>'); ``` Use [stripe.confirmBoletoPayment](https://docs.stripe.com/js/payment_intents/confirm_boleto_payment) and the [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) of the `PaymentIntent` object that you created in Step 2 to submit the customer’s billing details. Setelah konfirmasi, Stripe akan secara otomatis membuka modal untuk menampilkan voucher Boleto kepada pelanggan Anda. ```javascript var form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const result = await stripe.confirmBoletoPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { boleto: { tax_id: document.getElementById('tax_id').value, }, billing_details: { name: document.getElementById('name').value, email: document.getElementById('email').value, address: { line1: document.getElementById('address').value, city: document.getElementById('city').value, state: document.getElementById('state').value, postal_code: document.getElementById('postal_code').value, country: 'BR', }, }, }, } ); // Stripe.js will open a modal to display the Boleto voucher to your customer // This async function finishes when the customer closes the modal if (result.error) { // Display error to your customer const errorMsg = document.getElementById('error-message'); errorMsg.innerText = result.error.message; } }); ``` > `stripe.confirmBoletoPayment` mungkin perlu waktu beberapa detik untuk menyelesaikannya. Sambil menunggu, nonaktifkan formulir Anda agar tidak diserahkan ulang dan tampilkan indikator menunggu seperti spinner. Jika Anda menerima kesalahan, tampilkan kepada pelanggan, aktifkan kembali formulir, dan sembunyikan indikator menunggu. When a Boleto voucher is created successfully, the value of the returned PaymentIntent’s `status` property is `requires_action`. Check the status of a PaymentIntent in the [Dashboard](https://dashboard.stripe.com/test/payments) or by inspecting the status property on the object. If the Boleto voucher wasn’t created successfully, inspect the returned `error` to determine the cause (for example, invalid email format). ### Opsional: Emailkan tautan voucher kepada pelanggan Anda Stripe sends a [payment_intent.requires_action](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.requires_action) event when a Boleto voucher is created successfully. If you need to email your customers the voucher link, you can locate the `hosted_voucher_url` in [payment_intent.next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-hosted_voucher_url). ### Opsional: Sesuaikan voucher Anda Stripe memungkinkan penyesuaian UI yang dilihat pelanggan di halaman [Pengaturan Branding](https://dashboard.stripe.com/account/branding). Pengaturan brand berikut dapat diterapkan ke voucher: - **Ikon**—gambar brand dan nama umum bisnis Anda - **Warna aksen**—digunakan sebagai warna tombol Salin Nomor - **Warna brand**—digunakan sebagai warna latar belakang ## Tangani kejadian pascapembayaran [Sisi server] Boleto payments are asynchronous, so funds aren’t immediately available. Customers might not pay for the Boleto voucher immediately after checking out. Stripe sends a [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) event on the next business day (Monday through Friday excluding Brazilian holidays) for each Boleto voucher that was paid. Use the Dashboard or a custom *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) to receive these events and run actions (for example, sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow). If a Boleto voucher isn’t paid before 23:59 America/Sao_Paulo (UTC-3) on the expiry date, Stripe sends a [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) event after 1 business day. For example, if a Boleto voucher expires on Thursday, the event is sent on Friday. If a Boleto voucher expires on Friday, the event is sent the following Monday. | Kejadian | Keterangan | Langkah berikutnya | | ------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | `payment_intent.succeeded` | Pelanggan membayar voucher Boleto sebelum kedaluwarsa. | Penuhi barang atau layanan yang dibeli oleh pelanggan. | | `payment_intent.payment_failed` | The customer didn’t pay the Boleto voucher before expiration. | Contact the customer through email or push notification and request another payment method. | ## Coba integrasi In a *sandbox* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes), set `payment_method.billing_details.email` to the following values when you call [stripe.confirmBoletoPayment](https://docs.stripe.com/js/payment_intents/confirm_boleto_payment) to test different scenarios. | Email | Keterangan | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | Simulates a Boleto voucher which a customer pays after 3 minutes and the `payment_intent.succeeded` webhook arrives after about 3 minutes. In production, this webhook arrives 1 business day after a payment. Example: fulaninho@example.com | | `{any_prefix}succeed_immediately@{any_domain}` | Simulates a Boleto voucher which a customer pays immediately and the `payment_intent.succeeded` webhook arrives within several seconds. In production, this webhook arrives 1 business day after a payment. Example: succeed_immediately@example.com | | `{any_prefix}expire_immediately@{any_domain}` | Simulates a Boleto voucher which expires before a customer pays and the `payment_intent.payment_failed` webhook arrives within several seconds. The `expires_at` field in [next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-expires_at) is set to the current time regardless of what the `expires_after_days` parameter in [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-boleto-expires_after_days) is set to. Example: expire_immediately@example.com | | `{any_prefix}expire_with_delay@{any_domain}` | Simulates a Boleto voucher which expires before a customer pays and the `payment_intent.payment_failed` webhook arrives after about 3 minutes. The `expires_at` field in [next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-expires_at) is set to 3 minutes in the future regardless of what the `expires_after_days` parameter in [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-boleto-expires_after_days) is set to. Example: expire_with_delay@example.com | | `{any_prefix}fill_never@{any_domain}` | Simulates a Boleto voucher which never succeeds; it expires according to the `expires_at` field in [next_action.boleto_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-expires_at) per the provided parameters in the [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-boleto-expires_after_days) and the `payment_intent.payment_failed` webhook arrives after that. Example: fill_never@example.com | | ID Pajak | Keterangan | | ------------------------------------------------- | --------------------------------------------------------------------------------- | | CPF `000.000.000-00` CNPJ `00.000.000/0000-00` | In a sandbox, set `tax_id` to these values, so they bypass the tax ID validation. | ## Optional: Buat sendiri halaman voucher Anda [Sisi client] Kami merekomendasikan agar mengandalkan Stripe.js untuk menangani penampilan voucher Boleto dengan `confirmBoletoPayment`. Namun, Anda juga dapat menampilkan voucher secara manual kepada pelanggan. You can specify `handleActions: false` when calling stripe.confirmBoletoPayment in step 4 to indicate that you’ll handle the next action to display the Boleto details to your customer. ```javascript var form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const result = await stripe.confirmBoletoPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { boleto: { tax_id: document.getElementById('tax_id').value, }, billing_details: { name: document.getElementById('name').value, email: document.getElementById('email').value, address: { line1: document.getElementById('address').value, city: document.getElementById('city').value, state: document.getElementById('state').value, postal_code: document.getElementById('postal_code').value, country: 'BR', }, }, }, }, {handleActions: false}, ); if (result.error) { // Display error to your customer const errorMsg = document.getElementById('error-message'); errorMsg.innerText = result.error.message; } else { // An Boleto voucher was successfully created const amount = result.paymentIntent.amount; const currency = result.paymentIntent.currency; const details = result.paymentIntent.next_action.boleto_display_details; const number = details.number; const expires_at = details.expires_at; // Handle the next action by displaying the Boleto details to your customer // You can also use the generated hosted voucher const hosted_voucher_url = details.hosted_voucher_url; } }); ``` Sertakan, minimal, yang berikut ini: | Detail | Keterangan | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Nomor | Display the boleto voucher number such that it’s easy for your customers to copy them to their clipboard. Locate the number on the `PaymentIntent` object at [next_action.boleto_display_details.number](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-number). | | Tanggal kedaluwarsa | Display the boleto voucher expiry date is. Locate the UNIX timestamp after which the Boleto voucher expires on the `PaymentIntent` at [next_action.boleto_display_details.expires_at](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-expires_at). | | Unduh pdf | Display a download button that allows your customer to download the boleto pdf. Locate the pdf, where the customer can download the Boleto voucher PDF, on the `PaymentIntent` at [next_action.boleto_display_details.pdf](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-boleto_display_details-pdf). | ## Optional: Konfirmasikan sisi server Payment Intent [Sisi server] We recommend relying on Stripe.js to *confirm* (Confirming an intent indicates that the customer intends to use the current or provided payment method. Upon confirmation, the intent attempts to initiate the portions of the flow that have real-world side effects) a Boleto Payment Intent with `confirmBoletoPayment`. Using Stripe.js makes it much easier to extend your integration to other payment methods. However, you can also confirm a Payment Intent server-side as follows: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=brl \ -d confirm=true \ -d "payment_method_types[]=boleto" \ -d "payment_method_data[type]=boleto" \ -d "payment_method_data[billing_details][name]=João da Silva" \ --data-urlencode "payment_method_data[billing_details][email]=joao@exemplo.com" \ -d "payment_method_data[billing_details][address][line1]=1234 Av. Paulista" \ -d "payment_method_data[billing_details][address][city]=São Paulo" \ -d "payment_method_data[billing_details][address][state]=SP" \ -d "payment_method_data[billing_details][address][postal_code]=01310-000" \ -d "payment_method_data[billing_details][address][country]=BR" \ -d "payment_method_data[boleto][tax_id]=000.000.000-00" ``` ## Optional: Kirim email instruksi pembayaran You can enable Boleto payment instruction emails on the [Email Settings](https://dashboard.stripe.com/settings/emails) page in the Dashboard. Once enabled, Stripe sends payment instruction emails upon PaymentIntent confirmation. The emails contain the Boleto number and a link to the Stripe hosted voucher page. > In test environments, instruction emails are only sent to email addresses linked to the Stripe account. ## Kedaluwarsa dan pembatalan Boleto vouchers expire after the `expires_at` UNIX timestamp and a customer can’t pay a Boleto voucher once it has expired. Boleto vouchers can’t be canceled before expiration. After a Boleto voucher expires, the PaymentIntent’s status changes to `requires_payment_method`. At this point, you can confirm the PaymentIntent with another payment method or cancel.