# Simpan metode pembayaran pelanggan bila mereka menggunakannya untuk pembayaran Pelajari cara menyimpan metode pembayaran pelanggan saat Anda mengonfirmasi PaymentIntent. # Checkout Sessions API > This is a Checkout Sessions API for when payment-ui is embedded-components. View the full page at https://docs.stripe.com/payments/save-during-payment?payment-ui=embedded-components. Use the [Checkout Sessions API](https://docs.stripe.com/api/checkout/sessions.md) to save payment details during a purchase. This is useful for situations such as: - Charging a customer for an e-commerce order and storing the payment details for future purchases. - Initiating the first payment in a series of recurring payments. - Charging a deposit and storing the payment details to charge the full amount later. ## Compliance 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. > When using Elements with the Checkout Sessions API, only cards and ACH Direct Debit are supported for saved payment methods. You can’t save other payment methods, such as bank accounts. ## Prerequisites 1. Follow the Checkout guide to [accept a payment](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=checkout&ui=stripe-hosted). 1. Ikuti panduan ini untuk menyimpan metode pembayaran yang digunakan selama pembayaran sehingga Anda dapat mengambilnya untuk digunakan pada pembayaran berikutnya oleh pelanggan yang sama. ## Enable saved payment methods > Undang-undang privasi global bersifat kompleks dan memiliki banyak nuansa. Sebelum mengimplementasikan kemampuan untuk menyimpan detail metode pembayaran pelanggan, bekerja samalah dengan tim hukum Anda untuk memastikan bahwa hal tersebut mematuhi kerangka kerja privasi dan kepatuhan Anda. Untuk memungkinkan pelanggan menyimpan metode pembayaran mereka untuk penggunaan di masa mendatang, tentukan parameter [saved_payment_method_options.payment_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) saat membuat Sesi Checkout. > #### Use the Accounts v2 API to represent customers > > The Accounts v2 API is GA for Connect users, and in public preview for other Stripe users. All Stripe users can enable Accounts v2 [in their Dashboard](https://dashboard.stripe.com/settings/connect/platform-setup). However, when making calls to the Accounts v2 API, preview users need to [specify a preview version](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning). > > 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. Saving a payment method requires an object that represents your customer. This object can be a customer-configured [Account](https://docs.stripe.com/api/v2/core/accounts/object.md) if you use the Accounts v2 API, or a [Customer](https://docs.stripe.com/api/customers/object.md) if you use the Customers API. Pass an existing customer or create a new one by setting [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_creation) to `always` on the Checkout Session. ```dotnet // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var options = new Stripe.Checkout.SessionCreateOptions { LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 2, }, }, Mode = "payment", UiMode = "elements", CustomerCreation = "always", SavedPaymentMethodOptions = new Stripe.Checkout.SessionSavedPaymentMethodOptionsOptions { PaymentMethodSave = "enabled", }, }; var client = new StripeClient("<>"); var service = client.V1.Checkout.Sessions; Stripe.Checkout.Session session = service.Create(options); ``` Setelah Anda membuat Sesi Checkout, gunakan [client secret](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) yang dikembalikan dalam respons untuk [membangun halaman checkout Anda](https://docs.stripe.com/payments/quickstart-checkout-sessions.md). > In the latest version of Stripe.js, specifying `enableSave` to `auto` is optional because that’s the default value when saved payment methods are enabled on the Checkout Session. #### HTML+JS The Payment Element automatically displays a consent collection checkbox when saved payment methods are enabled on the Checkout Session. You can explicitly configure this behavior using [elementsOptions](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions) on `initCheckoutElementsSdk`. ```javascript const checkout = stripe.initCheckoutElementsSdk({ clientSecret, elementsOptions: {savedPaymentMethod: { // Default is 'auto' in the latest version of Stripe.js - this configuration is optional enableSave: 'auto', } } }); ``` #### React The Payment Element automatically displays a consent collection checkbox when saved payment methods are enabled on the Checkout Session. You can explicitly configure this behavior using [elementsOptions](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions) on the `CheckoutElementsProvider`. ```jsx import React from 'react'; import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const App = () => { const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.checkoutSessionClientSecret); return ( ); }; export default App; ``` ## Gunakan kembali metode pembayaran yang sebelumnya disimpan Each saved payment method is linked to an object that represents your customer. This object can be a customer-configured [Account](https://docs.stripe.com/api/v2/core/accounts/object.md) if you use the Accounts v2 API, or a [Customer](https://docs.stripe.com/api/customers/object.md) if you use the Customers API. Before creating the Checkout Session, authenticate your customer, and pass the corresponding object ID to the Checkout Session. > In the latest version of Stripe.js, `enableRedisplay` defaults to `auto` when saved payment methods are enabled on the Checkout Session. The Payment Element automatically redisplays previously saved payment methods for your customer to use during checkout when saved payment methods are enabled on the Checkout Session. #### Accounts v2 ```dotnet // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var options = new Stripe.Checkout.SessionCreateOptions { LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 2, }, }, Mode = "payment", UiMode = "elements", CustomerAccount = "{{CUSTOMERACCOUNT_ID}}", }; var client = new StripeClient("<>"); var service = client.V1.Checkout.Sessions; Stripe.Checkout.Session session = service.Create(options); ``` #### Customers v1 ```dotnet // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var options = new Stripe.Checkout.SessionCreateOptions { LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 2, }, }, Mode = "payment", UiMode = "elements", Customer = "{{CUSTOMER_ID}}", }; var client = new StripeClient("<>"); var service = client.V1.Checkout.Sessions; Stripe.Checkout.Session session = service.Create(options); ``` #### HTML+JS You can explicitly configure the redisplay behavior using [elementsOptions](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions) on `initCheckoutElementsSdk`. ```javascript const checkout = stripe.initCheckoutElementsSdk({ clientSecret, elementsOptions: { savedPaymentMethod: { // Default is 'auto' in the latest version of Stripe.js - this configuration is optional enableSave: 'auto',// Default is 'auto' in the latest version of Stripe.js - this configuration is optional enableRedisplay: 'auto', } } }); ``` #### React You can explicitly configure the redisplay behavior using [elementsOptions](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions) on the `CheckoutElementsProvider`. ```jsx import React from 'react'; import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const App = () => { const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.checkoutSessionClientSecret) return ( ); }; export default App; ``` ## Optional: Build a saved payment method UI #### HTML+JS You can build your own saved payment method UI instead of using the built-in UI provided by the Payment Element. To prevent the Payment Element from handling consent collection and displaying the previously saved payment methods, pass in additional [elementsOptions](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions) on `initCheckoutElementsSdk`. ```javascript const checkout = stripe.initCheckoutElementsSdk({ clientSecret, elementsOptions: {savedPaymentMethod: { enableSave: 'never', enableRedisplay: 'never', }, } }); ``` #### React You can build your own saved payment method UI instead of using the built-in UI provided by the Payment Element. To prevent the Payment Element from handling consent collection and displaying the previously saved payment methods, pass in additional [elementsOptions](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions) on the `CheckoutElementsProvider`. ```jsx import React from 'react'; import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const App = () => { const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.checkoutSessionClientSecret) return ( ); }; export default App; ``` ### Collect consent > Undang-undang privasi global bersifat kompleks dan memiliki banyak nuansa. Sebelum mengimplementasikan kemampuan untuk menyimpan detail metode pembayaran pelanggan, bekerja samalah dengan tim hukum Anda untuk memastikan bahwa hal tersebut mematuhi kerangka kerja privasi dan kepatuhan Anda. In most cases, you must collect a customer’s consent before you save their payment method details. The following example shows how to obtain consent using a checkbox. #### HTML+JS ```html
``` #### React ```jsx import React from 'react'; type Props = { savePaymentMethod: boolean; onSavePaymentMethodChange: (save: boolean) => void; } const ConsentCollection = (props: Props) => { const handleChange = (e: React.ChangeEvent) => { props.onSavePaymentMethodChange(e.target.checked); }; return ( ); }; export default ConsentCollection; ``` When you call [confirm](https://docs.stripe.com/js/custom_checkout/confirm), you can indicate to Stripe that your customer has provided consent by passing the `savePaymentMethod` parameter. When you save a customer’s payment details, you’re responsible for complying with all applicable laws, regulations, and network rules. #### HTML+JS ```js const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); const checkbox = document.getElementById('save-payment-method-checkbox'); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; const savePaymentMethod = checkbox.checked; actions.confirm({savePaymentMethod}).then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); } ``` #### React ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; type Props = { savePaymentMethod: boolean; } const PayButton = (props: Props) => { const checkoutState = useCheckout(); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); if (checkoutState.type === 'loading') { return (
Loading...
); } else if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } const {confirm} = checkoutState.checkout; const handleClick = () => { setLoading(true);confirm({savePaymentMethod: props.savePaymentMethod}).then((result) => { if (result.type === 'error') { setError(result.error) } setLoading(false); }) }; return (
{error &&
{error.message}
}
) }; export default PayButton; ``` ### Render saved payment methods Use the [savedPaymentMethods](https://docs.stripe.com/js/custom_checkout/session_object#custom_checkout_session_object-savedPaymentMethods) array on the front end to render the customer’s available payment methods. > The `savedPaymentMethods` array includes only the payment methods that have [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay) set to `always`. Follow the steps for [collecting consent](https://docs.stripe.com/payments/save-during-payment.md#collect-consent) from your customer and make sure to properly set the `allow_redisplay` parameter. #### HTML+JS ```html
``` ```js const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const container = document.getElementById('saved-payment-methods'); const {actions} = loadActionsResult; actions.getSession().savedPaymentMethods.forEach((pm) => { const label = document.createElement('label'); const radio = document.createElement('input'); radio.type = 'radio'; radio.value = pm.id; label.appendChild(radio); label.appendChild(document.createTextNode(`Card ending in ${pm.card.last4}`)); container.appendChild(label); }); } ``` #### React ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; type Props = { selectedPaymentMethod: string | null; onSelectPaymentMethod: (paymentMethod: string) => void; }; const PaymentMethods = (props: Props) => {const checkoutState = useCheckout(); if (checkoutState.type === 'loading') { return (
Loading...
); } else if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); }const {savedPaymentMethods} = checkoutState.checkout; const handleOptionChange = (e: React.ChangeEvent) => { props.onSelectPaymentMethod(e.target.value); }; return (
{savedPaymentMethods.map((pm) => ( ))}
); }; export default PaymentMethods; ``` ### Confirm with a saved payment method When your customer selects a saved payment method and is ready to complete checkout, call [confirm](https://docs.stripe.com/js/custom_checkout/confirm) and pass in the [paymentMethod](https://docs.stripe.com/js/custom_checkout/confirm#custom_checkout_session_confirm-options-paymentMethod) ID. #### HTML+JS ```html ``` ```js const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const container = document.getElementById('saved-payment-methods'); const {actions} = loadActionsResult; actions.getSession().savedPaymentMethods.forEach((pm) => { const label = document.createElement('label'); const radio = document.createElement('input'); radio.type = 'radio'; radio.value = pm.id; label.appendChild(radio); label.appendChild(document.createTextNode(`Card ending in ${pm.card.last4}`)); container.appendChild(label); }); } ``` #### React ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; type Props = { selectedPaymentMethod: string | null; } const PayButton = (props: Props) => { const checkoutState = useCheckout(); const [loading, setLoading] = React.useState(false); if (checkoutState.type === 'loading') { return (
Loading...
); } else if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } const {confirm} = checkoutState.checkout; const handleClick = () => { setLoading(true);confirm({paymentMethod: props.selectedPaymentMethod}).then((result) => { if (result.error) { // Confirmation failed. Display the error message. } setLoading(false); }) }; return ( ) }; export default PayButton; ``` # Payment Intents API > This is a Payment Intents API for when payment-ui is elements. View the full page at https://docs.stripe.com/payments/save-during-payment?payment-ui=elements. 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. ## Prerequisites 1. Follow the Payment Intents API guide to [accept a payment](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=elements&api-integration=paymentintents). 1. Ikuti panduan ini untuk menyimpan metode pembayaran yang digunakan selama pembayaran sehingga Anda dapat mengambilnya untuk digunakan pada pembayaran berikutnya oleh pelanggan yang sama. ## Save payment methods during payment [Sisi server] Anda dapat mengonfigurasi Payment Element untuk menyimpan metode pembayaran pelanggan untuk digunakan di masa mendatang. Bagian ini menunjukkan cara mengintegrasikan [fitur metode pembayaran tersimpan](https://docs.stripe.com/payments/save-customer-payment-methods.md), yang memungkinkan Payment Element untuk: - Meminta persetujuan pembeli untuk menyimpan metode pembayaran - Menyimpan metode pembayaran saat pembeli memberikan persetujuan - Menampilkan metode pembayaran yang tersimpan kepada pembeli untuk pembelian di masa mendatang - [Secara otomatis memperbarui kartu yang hilang atau kedaluwarsa](https://docs.stripe.com/payments/cards/overview.md#automatic-card-updates) saat pembeli menggantinya ![Kotak centang Payment Element dan metode pembayaran tersimpan](https://b.stripecdn.com/docs-statics-srv/assets/spm-save.fe0b24afd0f0a06e0cf4eecb0ce2403a.png) Simpan metode pembayaran. ![Payment Element dengan Metode pembayaran tersimpan dipilih](https://b.stripecdn.com/docs-statics-srv/assets/spm-saved.5dba5a8a190a9a0e9f1a99271bed3f4b.png) Gunakan kembali metode pembayaran yang disimpan sebelumnya. ### Mengaktifkan penyimpanan metode pembayaran di Payment Element When creating a [PaymentIntent](https://docs.stripe.com/api/payment_intents/.md) on your server, also create a [CustomerSession](https://docs.stripe.com/api/customer_sessions/.md) providing the customer’s ID (using either `customer` for a `Customer` object or `customer_account` for a customer-configured `Account` object) and enabling the [payment_element](https://docs.stripe.com/api/customer_sessions/object.md#customer_session_object-components-payment_element) component for your session. Configure which saved payment method [features](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components-payment_element-features) you want to enable. For instance, enabling [payment_method_save](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components-payment_element-features-payment_method_save) displays a checkbox offering customers to save their payment details for future use. You can specify `setup_future_usage` on a PaymentIntent or Checkout Session to override the default behavior for saving payment methods. This ensures that you automatically save the payment method for future use, even if the customer doesn’t explicitly choose to save it. If you intend to specify `setup_future_usage`, don’t set `payment_method_save_usage` in the same payment transaction because this causes an integration error. > #### Use the Accounts v2 API to represent customers > > The Accounts v2 API is GA for Connect users, and in public preview for other Stripe users. All Stripe users can enable Accounts v2 [in their Dashboard](https://dashboard.stripe.com/settings/connect/platform-setup). However, when making calls to the Accounts v2 API, preview users need to [specify a preview version](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning). > > 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. #### Accounts v2 #### .NET ```csharp namespace StripeExampleApi.Controllers { [Route("create-intent-and-customer-session")] [ApiController] public class CheckoutApiController : Controller { [HttpPost] public ActionResult Post() { // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var client = new StripeClient("<>"); var intentOptions = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions { Enabled = true, }, CustomerAccount = {{CUSTOMER_ACCOUNT_ID}}, }; var intent = client.V1.PaymentIntents.Create(intentOptions); var customerSessionOptions = new CustomerSessionCreateOptions { CustomerAccount = {{CUSTOMER_ACCOUNT_ID}}, Components = new CustomerSessionComponentsOptions(), }; customerSessionOptions.AddExtraParam("components[payment_element][enabled]", true); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_redisplay]", "enabled"); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_save]", "enabled"); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_save_usage]", "off_session"); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_remove]", "enabled"); var customerSession = client.V1.CustomerSessions.Create(customerSessionOptions); return Json(new { client_secret = intent.ClientSecret, customerSessionClientSecret = customerSession.ClientSecret }); } } } ``` #### Customers v1 #### .NET ```csharp namespace StripeExampleApi.Controllers { [Route("create-intent-and-customer-session")] [ApiController] public class CheckoutApiController : Controller { [HttpPost] public ActionResult Post() { // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var client = new StripeClient("<>"); var intentOptions = new PaymentIntentCreateOptions Amount = 1099, { Enabled = true, }, Customer = {{CUSTOMER_ID}}, }; var intent = client.V1.PaymentIntents.Create(intentOptions); var customerSessionOptions = new CustomerSessionCreateOptions { Customer = {{CUSTOMER_ID}}, Components = new CustomerSessionComponentsOptions(), }; customerSessionOptions.AddExtraParam("components[payment_element][enabled]", true); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_redisplay]", "enabled"); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_save]", "enabled"); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_save_usage]", "off_session"); customerSessionOptions.AddExtraParam( "components[payment_element][features][payment_method_remove]", "enabled"); var customerSession = client.V1.CustomerSessions.Create(customerSessionOptions); return Json(new { client_secret = intent.ClientSecret, customerSessionClientSecret = customerSession.ClientSecret }); } } } ``` Instance Elements Anda menggunakan *client secret* (A client secret is used with your publishable key to authenticate a request for a single object. Each client secret is unique to the object it's associated with) untuk mengakses metode pembayaran yang disimpan pelanggan tersebut. [Tangani kesalahan](https://docs.stripe.com/error-handling.md) dengan benar saat Anda membuat CustomerSession. Jika terjadi kesalahan, Anda tidak perlu memberikan client secret CustomerSession ke instance Elements, karena bersifat opsional. Buat instance Elements menggunakan client secrets untuk PaymentIntent dan CustomerSession. Kemudian, gunakan instance Elements ini untuk membuat Payment Element. ```javascript // Create the CustomerSession and obtain its clientSecret const res = await fetch("/create-intent-and-customer-session", { method: "POST" }); const { customer_session_client_secret: customerSessionClientSecret } = await res.json(); const elementsOptions = { clientSecret: '{{CLIENT_SECRET}}',customerSessionClientSecret, // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout form, passing the client secret // and CustomerSession's client secret obtained in a previous step const elements = stripe.elements(elementsOptions); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` > Allowing customers to remove their saved payment methods by enabling [payment_method_remove](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components-payment_element-features-payment_method_remove) impacts subscriptions that depend on that payment method. Removing the payment method detaches the [PaymentMethod](https://docs.stripe.com/api/payment_methods.md) from the object that represents the customer (either a customer-configured `Account` or a `Customer`). Saat mengonfirmasi PaymentIntent, Stripe.js secara otomatis mengontrol pengaturan [setup_future_usage](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-setup_future_usage) pada PaymentIntent dan [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay) pada PaymentMethod, tergantung pada jika pelanggan mencentang kotak untuk menyimpan detail pembayaran. ### Terapkan pengumpulan kembali CVC Secara opsional, tentukan `require_cvc_recollection` [ketika membuat PaymentIntent](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-card-require_cvc_recollection) untuk memberlakukan pengumpulan kembali CVC saat pelanggan membayar dengan kartu. ### Mendeteksi pemilihan metode pembayaran yang disimpan Untuk mengontrol konten dinamis saat metode pembayaran tersimpan dipilih, dengarkan peristiwa `change` elemen pembayaran, yang diisi dengan metode pembayaran yang dipilih. ```javascript paymentElement.on('change', function(event) { if (event.value.payment_method) { // Control dynamic content if a saved payment method is selected } }) ``` ## Save only payment methods that support reuse [Sisi server] You can’t make all payment methods [reusable](https://docs.stripe.com/payments/accept-a-payment.md#save-payment-method-details) by enabling `setup_future_usage` in the Payment Intent. See [Payment method support](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability) to learn more about which payment methods are compatible with `setup_future_usage`. Instead, you can save payment method details only when a customer selects a payment method that supports it. For example, if you accept both card payments and Giropay (which you can’t reuse), configure `setup_future_usage=off_session` on the `payment_method_options[card]` object. Jika pelanggan menolak menyimpan detail pembayarannya, nonaktifkan `setup_future_usage` di PaymentIntent di sisi server. Kami tidak mendukung penyesuaian ini di sisi client. #### 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. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1099 \ -d "currency"="usd" \ -d "automatic_payment_methods[enabled]"="true" \ -d "payment_method_options[card][setup_future_usage]"="off_session" ``` #### Mencantumkan metode pembayaran secara manual Sebagai alternatif, Anda dapat mencantumkan `card` dan `giropay` menggunakan [tipe metode pembayaran](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types) seperti dalam contoh di bawah. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1099 \ -d "currency"="usd" \ -d "payment_method_types[]"="card" \ -d "payment_method_types[]"="giropay" \ -d "payment_method_options[card][setup_future_usage]"="off_session" ``` ## Charge metode pembayaran yang disimpan nanti [Sisi server] > `bancontact`, `ideal`, dan `sofort` adalah metode pembayaran satu kali secara default. Ketika diatur untuk penggunaan di masa mendatang, metode pembayaran tersebut menghasilkan tipe metode pembayaran `sepa_debit` yang dapat digunakan kembali, sehingga Anda harus menggunakan `sepa_debit` untuk meminta metode pembayaran yang telah disimpan. > #### 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). To find a payment method to charge, list the payment methods associated with your customer. This example lists cards but you can list any supported [type](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type). #### Accounts v2 ```dotnet // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var options = new PaymentMethodListOptions { CustomerAccount = "{{CUSTOMERACCOUNT_ID}}", Type = "card", }; var client = new StripeClient("<>"); var service = client.V1.PaymentMethods; StripeList paymentMethods = service.List(options); ``` #### Customers v1 ```dotnet // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var options = new PaymentMethodListOptions { Customer = "{{CUSTOMER_ID}}", Type = "card", }; var client = new StripeClient("<>"); var service = client.V1.PaymentMethods; StripeList paymentMethods = service.List(options); ``` When you’re ready to charge your customer *off-session* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information), use the customer’s ID and the `PaymentMethod` ID to create a `PaymentIntent` with the amount and currency of the payment. Set a few other parameters to make the off-session payment: - Set [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) to `true` to indicate that the customer isn’t in your checkout flow during a payment attempt and can’t fulfill an authentication request made by a partner, such as a card issuer, bank, or other payment institution. If, during your checkout flow, a partner requests authentication, Stripe requests exemptions using customer information from a previous *on-session* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method) transaction. If the conditions for exemption aren’t met, the `PaymentIntent` might throw an error. - Set the value of the `PaymentIntent`’s [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) property to true, which causes confirmation to occur immediately when the `PaymentIntent` is created. - Set [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) to the `PaymentMethod`’s ID. - Depending on how you represent customers in your integration, set either [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) to the ID of the customer-configured `Account` or [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) to the ID of the `Customer`. > #### Use the Accounts v2 API to represent customers > > The Accounts v2 API is GA for Connect users, and in public preview for other Stripe users. All Stripe users can enable Accounts v2 [in their Dashboard](https://dashboard.stripe.com/settings/connect/platform-setup). However, when making calls to the Accounts v2 API, preview users need to [specify a preview version](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning). > > 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 ```dotnet // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions { Enabled = true, }, CustomerAccount = "{{CUSTOMERACCOUNT_ID}}", PaymentMethod = "{{PAYMENT_METHOD_ID}}", ReturnUrl = "https://example.com/order/123/complete", OffSession = true, Confirm = true, }; var client = new StripeClient("<>"); var service = client.V1.PaymentIntents; PaymentIntent paymentIntent = service.Create(options); ``` #### Pelanggan v1 ```dotnet // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions { Enabled = true, }, Customer = "{{CUSTOMER_ID}}", PaymentMethod = "{{PAYMENT_METHOD_ID}}", ReturnUrl = "https://example.com/order/123/complete", OffSession = true, Confirm = true, }; var client = new StripeClient("<>"); var service = client.V1.PaymentIntents; PaymentIntent paymentIntent = service.Create(options); ``` ## Coba integrasi Gunakan detail pembayaran percobaan dan halaman pengarahan ulang percobaan untuk memverifikasi integrasi Anda. Klik tab di bawah guna melihat detail untuk setiap metode pembayaran. #### 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. | #### Pengarahan ulang bank | Metode pembayaran | Skenario | Cara mencoba | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bancontact | Pelanggan Anda berhasil menyiapkan metode pembayaran Debit Langsung SEPA untuk penggunaan mendatang dengan menggunakan Bancontact. | Gunakan sembarang nama di formulir Bancontact, kemudian klik **Otorisasikan penyiapan percobaan** di halaman pengarahan ulang. | | Bancontact | Pelanggan Anda gagal mengautentikasi di halaman pengarahan ulang Bancontact. | Gunakan sembarang nama di formulir Bancontact, kemudian klik **Gagalkan penyiapan percobaan** di halaman pengarahan ulang. | | Debit Langsung BECS | Pelanggan Anda berhasil membayar dengan Debit Langsung BECS. | Isilah formulir menggunakan nomor akun `900123456`. Transisi PaymentIntent yang telah dikonfirmasi awalnya menjadi `sedang diproses`, kemudian akan berubah menjadi status `berhasil` setelah 3 menit kemudian. | | Debit Langsung BECS | Pembayaran pelanggan Anda gagal dengan kode kesalahan `account_closed`. | Isilah formulir menggunakan nomor akun `111111113`. | | iDEAL | Pelanggan Anda berhasil menyiapkan metode pembayaran [Debit Langsung SEPA](https://docs.stripe.com/payments/sepa-debit.md) untuk penggunaan mendatang dengan menggunakan iDEAL. | Gunakan sembarang nama dan bank di formulir iDEAL, kemudian klik **Otorisasikan penyiapan percobaan** di halaman pengarahan ulang. | | iDEAL | Pelanggan Anda gagal mengautentikasi di halaman pengarahan ulang iDEAL. | Pilih sembarang bank dan gunakan sembarang nama di formulir iDEAL, kemudian klik **Gagalkan penyiapan percobaan** di halaman pengarahan ulang. | #### Debit bank | Metode pembayaran | Skenario | Cara mencoba | | ------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Debit Langsung SEPA | Pelanggan Anda berhasil membayar dengan Debit Langsung SEPA. | Isilah formulir menggunakan nomor akun `AT321904300235473204`. Transisi PaymentIntent yang telah dikonfirmasi awalnya menjadi sedang diproses, kemudian akan berubah menjadi status berhasil setelah tiga menit kemudian. | | Debit Langsung SEPA | Transisi status maksud pembayaran pelanggan dari `processing` menjadi `requires_payment_method`. | Isilah formulir menggunakan nomor akun `AT861904300235473202`. | ### Coba men-charge PaymentMethod Debit SEPA yang disimpan Mengonfirmasi PaymentIntent menggunakan iDEAL, Bancontact, atau Sofort, menghasilkan *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) [Debit Langsung SEPA](https://docs.stripe.com/payments/sepa-debit.md). Debit Langsung SEPA adalah metode pembayaran dengan [notifikasi tertunda](https://docs.stripe.com/payments/payment-methods.md#payment-notification) yang berubah menjadi status `processing` penengah sebelum nanti transisi beberapa hari menjadi status `succeeded` atau `requires_payment_method`. #### Email Atur `payment_method.billing_details.email` ke salah satu nilai berikut untuk menguji transisi status `PaymentIntent`. Anda dapat menyertakan teks kustom Anda sendiri di awal alamat email yang diikuti dengan garis bawah. Misalnya, `test_1_generatedSepaDebitIntentsFail@example.com` menghasilkan PaymentMethod Debit Langsung SEPA yang selalu gagal saat digunakan dengan `PaymentIntent`. | Alamat Email | Keterangan | | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | | `generatedSepaDebitIntentsSucceed@example.com` | Status `PaymentIntent` bertransisi dari `processing` ke `succeeded`. | | `generatedSepaDebitIntentsSucceedDelayed@example.com` | Status `PaymentIntent` bertransisi dari `processing` ke `succeeded` setelah setidaknya tiga menit. | | `generatedSepaDebitIntentsFail@example.com` | Status `PaymentIntent` bertransisi dari `processing` ke `requires_payment_method`. | | `generatedSepaDebitIntentsFailDelayed@example.com` | Status `PaymentIntent` bertransisi dari `processing` ke `requires_payment_method` setelah setidaknya tiga menit. | | `generatedSepaDebitIntentsSucceedDisputed@example.com` | Status `PaymentIntent` bertransisi dari `processing` ke `succeeded`, tetapi sengketa dibuat segera. | | `generatedSepaDebitIntentsFailsDueToInsufficientFunds@example.com` | Status `PaymentIntent` bertransisi dari `processing` ke `requires_payment_method` dengan kode kegagalan `insufficient_funds`. | #### PaymentMethod Gunakan PaymentMethods ini untuk menguji transisi status `PaymentIntent`. Token ini berguna untuk pengujian otomatis guna segera melampirkan PaymentMethod ke SetupIntent di server. | Metode Pembayaran | Keterangan | | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | `pm_bancontact_generatedSepaDebitIntentsSucceed` | Status `PaymentIntent` bertransisi dari `processing` ke `succeeded`. | | `pm_bancontact_generatedSepaDebitIntentsSucceedDelayed` | Status `PaymentIntent` bertransisi dari `processing` ke `succeeded` setelah setidaknya tiga menit. | | `pm_bancontact_generatedSepaDebitIntentsFail` | Status `PaymentIntent` bertransisi dari `processing` ke `requires_payment_method`. | | `pm_bancontact_generatedSepaDebitIntentsFailDelayed` | Status `PaymentIntent` bertransisi dari `processing` ke `requires_payment_method` setelah setidaknya tiga menit. | | `pm_bancontact_generatedSepaDebitIntentsSucceedDisputed` | Status `PaymentIntent` bertransisi dari `processing` ke `succeeded`, tetapi sengketa dibuat segera. | | `pm_bancontact_generatedSepaDebitIntentsFailsDueToInsufficientFunds` | Status `PaymentIntent` bertransisi dari `processing` ke `requires_payment_method` dengan kode kegagalan `insufficient_funds`. | ## See also - [Simpan detail pembayaran selama pembayaran dalam aplikasi](https://docs.stripe.com/payments/mobile/save-during-payment.md) - [Simpan detail pembayaran di sesi Checkout](https://docs.stripe.com/payments/checkout/how-checkout-works.md#save-payment-methods) - [Siapkan pembayaran mendatang](https://docs.stripe.com/payments/save-and-reuse.md) - [Handle post-payment events](https://docs.stripe.com/webhooks/handling-payment-events.md)