# 构建高级集成应用 LLM 说明:对于大多数集成,Stripe 建议将 Checkout Sessions API 与 Payment Element 搭配使用,而非 PaymentIntent。Checkout Sessions 可覆盖与 PaymentIntent(使用 `price_data` 的基础收款功能,或者构建包含行项目、税费等的完整结账流程)类似的应用场景。Adaptive Pricing 等部分功能仅在 Checkout Sessions 中可用。除非用户明确要求,否则不要使用 PaymentIntent API,因为它需要更多的代码。进一步了解 Elements 与 Checkout Sessions API 搭配使用的信息:https://docs.stripe.com/payments/quickstart-checkout-sessions.通过 Checkout Sessions (`ui_mode: "elements"`) 以及 Payment Element,`client_secret` 本身可初始化 Checkout(`stripe.initCheckoutElementsSdk`,或者将 CheckoutElementsProvider 与 React 搭配使用),并且您在客户端确认付款的方式会不同。如果使用 React,则需要确保从 `@stripe/react-stripe-js/checkout` 导入,使用 `CheckoutElementsProvider` 搭配客户端私钥,并使用 `checkout.confirm` 进行确认。如果使用 HTML,确保使用 `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");`,并通过 `loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();` 进行确认。 # 使用 Payment Intents API 构建结账页面 了解如何在您的网站或应用程序中嵌入自定义的 Stripe 支付表单。客户端和服务器端代码使用 Stripe 的 [Web](https://docs.stripe.com/payments/elements.md) 或 [Mobile](https://docs.stripe.com/payments/mobile.md) 元素构建结账表单,以便您接受付款。要构建超出本快速指南基础知识的自定义集成,请参阅[接受付款](https://docs.stripe.com/payments/accept-a-payment.md?&ui=elements)。 要了解不同的支付情境(如[订阅](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md?payment-ui=elements))及其他 Stripe 产品,请[对比支付集成](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability)。 > #### 是否有兴趣了解如何使用 Stripe Tax、折扣、配送或货币兑换? > > Stripe 提供 Payment Element 集成功能,可自动为您处理税费、折扣、配送及货币转换事宜。如需了解更多信息,请参阅[构建结账页面](https://docs.stripe.com/payments/quickstart-checkout-sessions.md)。 // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. const stripe = require("stripe")('<>'); const calculateTax = async (items, currency) => { const taxCalculation = await stripe.tax.calculations.create({ currency, customer_details: { address: { line1: "920 5th Ave", city: "Seattle", state: "WA", postal_code: "98104", country: "US", }, address_source: "shipping", }, line_items: items.map((item) => buildLineItem(item)), }); return taxCalculation; }; const buildLineItem = (item) => { return { amount: item.amount, // Amount in cents reference: item.id, // Unique reference for the item in the scope of the calculation }; }; // Securely calculate the order amount, including tax const calculateOrderAmount = (taxCalculation) => { // Calculate the order total with any exclusive taxes on the server to prevent // people from directly manipulating the amount on the client return taxCalculation.amount_total; }; const calculateOrderAmount = (items) => { // Calculate the order total on the server to prevent // people from directly manipulating the amount on the client let total = 0; items.forEach((item) => { total += item.amount; }); return total; }; const chargeCustomer = async (customerId) => { // Lookup the payment methods available for the customer const paymentMethods = await stripe.paymentMethods.list({ customer: customerId, type: "card", }); try { // Charge the customer and payment method immediately const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: "{{CURRENCY}}", customer: customerId, payment_method: paymentMethods.data[0].id, off_session: true, confirm: true, }); } catch (err) { // Error code will be authentication_required if authentication is needed console.log("Error code is: ", err.code); const paymentIntentRetrieved = await stripe.paymentIntents.retrieve(err.raw.payment_intent.id); console.log("PI retrieved: ", paymentIntentRetrieved.id); } }; const chargeCustomer = async (customerId) => { // Lookup the payment methods available for the customer-configured Account const paymentMethods = await stripe.paymentMethods.list({ customer_account: customerId, type: "card", }); try { // Charge the customer-configured Account and payment method immediately const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: "{{CURRENCY}}", customer_account: customerId, payment_method: paymentMethods.data[0].id, off_session: true, confirm: true, }); } catch (err) { // Error code will be authentication_required if authentication is needed console.log("Error code is: ", err.code); const paymentIntentRetrieved = await stripe.paymentIntents.retrieve(err.raw.payment_intent.id); console.log("PI retrieved: ", paymentIntentRetrieved.id); } }; // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new Customer const customer = await stripe.customers.create(); // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new customer-configured Account const account = await stripe.v2.core.accounts.create({ configuration: { customer: { capabilities: { automatic_indirect_tax: {requested: true}, }, } } }); // Create a Tax Calculation for the items being sold const taxCalculation = await calculateTax(items, '{{CURRENCY}}'); const amount = await calculateOrderAmount(taxCalculation); // Create a PaymentIntent with the order amount and currency const paymentIntent = await stripe.paymentIntents.create({ customer: customer.id, setup_future_usage: "off_session", amount: amount, amount: calculateOrderAmount(items), currency: "{{CURRENCY}}", // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: { enabled: true, }, hooks: { inputs: { tax: { calculation: taxCalculation.id } } }, }); res.send({ clientSecret: paymentIntent.client_secret, }); // Create a PaymentIntent with the order amount and currency const paymentIntent = await stripe.paymentIntents.create({ customer_account: account.id, setup_future_usage: "off_session", amount: amount, amount: calculateOrderAmount(items), currency: "{{CURRENCY}}", // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: { enabled: true, }, hooks: { inputs: { tax: { calculation: taxCalculation.id } } }, }); res.send({ clientSecret: paymentIntent.client_secret, }); require 'stripe' \# This is a public sample test API key. # Don’t submit any personally identifiable information in requests made with this key. # Sign in to see your own test API key embedded in code samples. $CLIENT = Stripe::StripeClient.new('<>') def calculate_tax(items, currency) $CLIENT.v1.tax.calculations.create( currency: currency, customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, line_items: items.map {|item| build_line_item(item) } ) end def build_line_item(item) { amount: item['amount'], \# Amount in cents reference: item['id'], # Unique reference for the item in the scope of the calculation } end # Securely calculate the order amount, including tax def calculate_order_amount(tax_calculation) # Calculate the order total with any exclusive taxes on the server to prevent # people from directly manipulating the amount on the client tax_calculation.amount_total end def calculate_tax(items, currency) $CLIENT.v1.tax.calculations.create( currency: currency, customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, line_items: items.map {|item| build_line_item(item) } ) end def build_line_item(item) { amount: item['amount'], \# Amount in cents reference: item['id'], # Unique reference for the item in the scope of the calculation } end # Securely calculate the order amount, including tax def calculate_order_amount(tax_calculation) # Calculate the order total with any exclusive taxes on the server to prevent # people from directly manipulating the amount on the client tax_calculation.amount_total end \# Securely calculate the order amount def calculate_order_amount(_items) # Calculate the order total on the server to prevent # people from directly manipulating the amount on the client _items.sum {|h| h['amount']} end def charge_customer(customerId) \# Lookup the payment methods available for the customer payment_methods = $CLIENT.v1.payment_methods.list( customer: customerId, type: 'card' ) begin # Charge the customer and payment method immediately payment_intent = $CLIENT.v1.payment_intents.create( amount: 1099, currency: '{{CURRENCY}}', customer_account: customerId, payment_method: payment_methods.data[0]['id'], off_session: true, confirm: true ) rescue Stripe::CardError => e # Error code will be authentication_required if authentication is needed puts "Error is: \#{e.error.code}" payment_intent_id = e.error.payment_intent.id payment_intent = $CLIENT.v1.payment_intents.retrieve(payment_intent_id) puts payment_intent.id end end def charge_customer(customerId) \# Lookup the payment methods available for the customer-configured Account payment_methods = $CLIENT.v1.payment_methods.list( customer_account: customerId, type: 'card' ) begin # Charge the customer-configured Account and payment method immediately payment_intent = $CLIENT.v1.payment_intents.create( amount: 1099, currency: '{{CURRENCY}}', customer_account: customerId, payment_method: payment_methods.data[0]['id'], off_session: true, confirm: true ) rescue Stripe::CardError => e # Error code will be authentication_required if authentication is needed puts "Error is: \#{e.error.code}" payment_intent_id = e.error.payment_intent.id payment_intent = $CLIENT.v1.payment_intents.retrieve(payment_intent_id) puts payment_intent.id end end \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event # and attach the PaymentMethod to a new Customer customer = $CLIENT.v1.customers.create \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event # and attach the PaymentMethod to a new customer-configured Account account = $CLIENT.v2.core.accounts.create({ configuration: { customer: { capabilities: {automatic_indirect_tax: {requested: true}} } } }) \# Create a Tax Calculation for the items being sold tax_calculation = calculate_tax(data['items'], '{{CURRENCY}}') \# Create a PaymentIntent with amount and currency payment_intent = $CLIENT.v1.payment_intents.create( customer: customer['id'], setup_future_usage: 'off_session', amount: calculate_order_amount(tax_calculation), amount: calculate_order_amount(data['items']), currency: '{{CURRENCY}}', \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: { enabled: true, }, hooks: { inputs: { tax: { calculation: tax_calculation.id } } }, ) { clientSecret: payment_intent.client_secret, }.to_json \# Create a PaymentIntent with amount and currency payment_intent = $CLIENT.v1.payment_intents.create( customer_account: account['id'], setup_future_usage: 'off_session', amount: calculate_order_amount(tax_calculation), amount: calculate_order_amount(data['items']), currency: '{{CURRENCY}}', \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: { enabled: true, }, hooks: { inputs: { tax: { calculation: tax_calculation.id } } }, ) { clientSecret: payment_intent.client_secret, }.to_json import stripe \# This is a public sample test API key. # Don’t submit any personally identifiable information in requests made with this key. # Sign in to see your own test API key embedded in code samples. client = stripe.StripeClient('<>') import stripe \# This is a public sample test API key. # Don’t submit any personally identifiable information in requests made with this key. # Sign in to see your own test API key embedded in code samples. client = stripe.StripeClient('<>') def calculate_tax(items, currency): tax_calculation = client.v1.tax.calculations.create(params={ 'currency': currency, 'customer_details': { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, 'line_items': list(map(build_line_item, items)), }) return tax_calculation def build_line_item(item): return { "amount": item["amount"], \# Amount in cents "reference": item["id"], # Unique reference for the item in the scope of the calculation } def calculate_tax(items, currency): tax_calculation = client.v1.tax.calculations.create({ "currency": currency, "customer_details": { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, "line_items": list(map(build_line_item, items)), }) return tax_calculation def build_line_item(item): return { "amount": item["amount"], \# Amount in cents "reference": item["id"], # Unique reference for the item in the scope of the calculation } \# Securely calculate the order amount, including tax def calculate_order_amount(items, tax_calculation): # Replace this constant with a calculation of the order's amount # Calculate the order total with any exclusive taxes on the server to prevent # people from directly manipulating the amount on the client order_amount = 1400 order_amount += tax_calculation['tax_amount_exclusive'] return order_amount def calculate_order_amount(items): \# Replace this constant with a calculation of the order's amount # Calculate the order total on the server to prevent # people from directly manipulating the amount on the client return 1400 def charge_customer(customer_id): \# Lookup the payment methods available for the customer payment_methods = client.v1.payment_methods.list(params={ 'customer': customer_id, 'type': 'card', }) # Charge the customer and payment method immediately try: client.v1.payment_intents.create(params={ 'amount': 1099, 'currency': '{{CURRENCY}}', 'customer': customer_id, 'payment_method': payment_methods.data[0].id, 'off_session': True, 'confirm': True, }) except stripe.error.CardError as e: err = e.error # Error code will be authentication_required if authentication is needed print('Code is: %s' % err.code) payment_intent_id = err.payment_intent['id'] payment_intent = client.v1.payment_intents.retrieve(payment_intent_id) def charge_customer(customer_id): \# Lookup the payment methods available for the customer-configured Account payment_methods = stripe.PaymentMethod.list( customer_account=customer_id, type='card' ) # Charge the customer-configured Account and payment method immediately try: stripe.PaymentIntent.create( amount=1099, currency='{{CURRENCY}}', customer_account=customer_id, payment_method=payment_methods.data[0].id, off_session=True, confirm=True ) except stripe.error.CardError as e: err = e.error # Error code will be authentication_required if authentication is needed print('Code is: %s' % err.code) payment_intent_id = err.payment_intent['id'] payment_intent = client.v1.payment_intents.retrieve(payment_intent_id) \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event # and attach the PaymentMethod to a new Customer customer = client.v1.customers.create() \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event # and attach the PaymentMethod to a new customer-configured Account account = client.v2.core.accounts.create({ "configuration": { "customer": { "capabilities": {"automatic_indirect_tax": {"requested": True}} }, }, }) try: data = json.loads(request.data) \# Create a Tax Calculation for the items being sold tax_calculation = calculate_tax(data['items'], '{{CURRENCY}}') \# Create a PaymentIntent with the order amount and currency intent = client.v1.payment_intents.create(params={ 'customer': customer['id'], 'setup_future_usage': 'off_session', 'amount': calculate_order_amount(data['items'], tax_calculation), 'amount': calculate_order_amount(data['items']), 'currency': '{{CURRENCY}}', \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. 'automatic_payment_methods': { 'enabled': True, }, 'hooks': { 'inputs': { 'tax': { 'calculation': tax_calculation['id'] } } }, }) return jsonify({ 'clientSecret': intent['client_secret'] }) except Exception as e: return jsonify(error=str(e)), 403 try: data = json.loads(request.data) \# Create a Tax Calculation for the items being sold tax_calculation = calculate_tax(data['items'], '{{CURRENCY}}') \# Create a PaymentIntent with the order amount and currency intent = client.v1.payment_intents.create({ "customer_account": account['id'], "setup_future_usage": 'off_session', "amount": calculate_order_amount(data['items'], tax_calculation), "amount": calculate_order_amount(data['items']), "currency": '{{CURRENCY}}', \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. "automatic_payment_methods": { 'enabled': True, }, "hooks": { 'inputs': { 'tax': { 'calculation': tax_calculation['id'] } } }, }) return jsonify({ 'clientSecret': intent['client_secret'] }) except Exception as e: return jsonify(error=str(e)), 403 $stripe = new \Stripe\StripeClient($stripeSecretKey); function calculateTax($stripe, $items, $currency) { $taxCalculation = $stripe->tax->calculations->create([ 'currency' => $currency, 'customer_details' => [ 'address' => [ 'line1' => '920 5th Ave', 'city' => 'Seattle', 'state' => 'WA', 'postal_code' => '98104', 'country' => 'US', ], 'address_source' => 'shipping', ], 'line_items' => array_map('buildLineItem', $items), ]); return $taxCalculation; } function buildLineItem($item) { return [ 'amount' => $item->amount, // Amount in cents 'reference' => $item->id, // Unique reference for the item in the scope of the calculation ]; } // Securely calculate the order amount, including tax function calculateOrderAmount($taxCalculation) { // Calculate the order total with any exclusive taxes on the server to prevent // people from directly manipulating the amount on the client return $taxCalculation->amount_total; } function calculateOrderAmount(array $items): int { // Calculate the order total on the server to prevent // people from directly manipulating the amount on the client $total = 0; foreach($items as $item) { $total += $item->amount; } return $total; } // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new Customer $customer = $stripe->customers->create(); // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new customer-configured Account $account = $stripe->v2->core->accounts->create([ 'configuration' => [ 'customer' => [ 'capabilities' => [ 'automatic_indirect_tax' => [ 'requested' => true, ], ], ], ] ]); // Create a Tax Calculation for the items being sold $taxCalculation = calculateTax($stripe, $jsonObj->items, '{{CURRENCY}}'); // Create a PaymentIntent with amount and currency $paymentIntent = $stripe->paymentIntents->create([ 'customer' => $customer->id, 'setup_future_usage' => 'off_session', 'amount' => calculateOrderAmount($jsonObj->items, $taxCalculation), 'amount' => calculateOrderAmount($jsonObj->items), 'currency' => '{{CURRENCY}}', // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. 'automatic_payment_methods' => [ 'enabled' => true, ], 'hooks' => [ 'inputs' => [ 'tax' => [ 'calculation' => $taxCalculation->id ] ] ], ]); $output = [ 'clientSecret' => $paymentIntent->client_secret, ]; // Create a PaymentIntent with amount and currency $paymentIntent = $stripe->paymentIntents->create([ 'customer_account' => $account->id, 'setup_future_usage' => 'off_session', 'amount' => calculateOrderAmount($jsonObj->items, $taxCalculation), 'amount' => calculateOrderAmount($jsonObj->items), 'currency' => '{{CURRENCY}}', // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. 'automatic_payment_methods' => [ 'enabled' => true, ], 'hooks' => [ 'inputs' => [ 'tax' => [ 'calculation' => $taxCalculation->id ] ] ], ]); $output = [ 'clientSecret' => $paymentIntent->client_secret, ]; $stripe = new \Stripe\StripeClient($'<>'); // Lookup the payment methods available for the customer $paymentMethods = $stripe->paymentMethods->all([ 'customer' => $jsonObj->customer, 'type' => 'card' ]); // Charge the customer and payment method immediately $paymentIntent = $stripe->paymentIntents->create([ 'amount' => 1099, 'currency' => '{{CURRENCY}}', 'customer' => $jsonObj->customer, 'payment_method' => $paymentMethods->data[0]->id, 'off_session' => true, 'confirm' => true, ]); // Lookup the payment methods available for the customer-configured Account $paymentMethods = $stripe->paymentMethods->all([ 'customer_account' => $jsonObj->customer, 'type' => 'card' ]); // Charge the customer-configured Account and payment method immediately $paymentIntent = $stripe->paymentIntents->create([ 'amount' => 1099, 'currency' => '{{CURRENCY}}', 'customer_account' => $jsonObj->customer, 'payment_method' => $paymentMethods->data[0]->id, 'off_session' => true, 'confirm' => true, ]); $stripeSecretKey = '<>'; "github.com/stripe/stripe-go/v85" // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. sc = stripe.NewClient("<>") func calculateTax(items []item, currency stripe.Currency) *stripe.TaxCalculation { var lineItems []*stripe.TaxCalculationCreateLineItemParams for _, item := range items { lineItems = append(lineItems, buildLineItem(item)) } taxCalculationParams := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(string(currency)), CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String("shipping"), }, LineItems: lineItems, } taxCalculation, _ := sc.V1TaxCalculations.Create(context.TODO(), taxCalculationParams) return taxCalculation } func buildLineItem(i item) *stripe.TaxCalculationCreateLineItemParams { return &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(i.Amount), // Amount in cents Reference: stripe.String(i.Id), // Unique reference for the item in the scope of the calculation } } func calculateTax(items []item, currency stripe.Currency) *stripe.TaxCalculation { var lineItems []*stripe.TaxCalculationCreateLineItemParams for _, item := range items { lineItems = append(lineItems, buildLineItem(item)) } taxCalculationParams := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(string(currency)), CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String("shipping"), }, LineItems: lineItems, } taxCalculation, _ := sc.V1TaxCalculations.Create(context.TODO(), taxCalculationParams) return taxCalculation } func buildLineItem(i item) *stripe.TaxCalculationCreateLineItemParams { return &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(i.Amount), // Amount in cents Reference: stripe.String(i.Id), // Unique reference for the item in the scope of the calculation } } // Securely calculate the order amount, including tax func calculateOrderAmount(taxCalculation *stripe.TaxCalculation) int64 { // Calculate the order total with any exclusive taxes on the server to prevent // people from directly manipulating the amount on the client return taxCalculation.AmountTotal } func calculateOrderAmount(items []item) int64 { // Calculate the order total on the server to prevent // people from directly manipulating the amount on the client total := int64(0) for _, item := range items { total += item.Amount } return total; } func chargeCustomer(CustomerID string) { // Look up the payment methods available for the customer params := &stripe.PaymentMethodListParams{ Customer: stripe.String(CustomerID), Type: stripe.String(stripe.PaymentMethodTypeCard), } var pm *stripe.PaymentMethod for p, err := range sc.V1PaymentMethods.List(context.TODO(), params).All(context.TODO()) { if err != nil { log.Printf("sc.V1Prices.List: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } pm = p break } paymentIntentParams := &stripe.PaymentIntentCreateParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.Currency{{CURRENCY}})), Customer: stripe.String(CustomerID), PaymentMethod: stripe.String(pm.ID), Confirm: stripe.Bool(true), OffSession: stripe.Bool(true), } // Charge the customer and payment method immediately _, err := sc.V1PaymentIntents.Create(context.TODO(), paymentIntentParams) if err != nil { if stripeErr, ok := err.(*stripe.Error); ok { // Error code will be authentication_required if authentication is needed fmt.Printf("Error code: %v", stripeErr.Code) paymentIntentID := stripeErr.PaymentIntent.ID paymentIntent, _ := sc.V1PaymentIntents.Retrieve(context.TODO(), paymentIntentID, nil) fmt.Printf("PI: %v", paymentIntent.ID) } } } func chargeCustomer(CustomerID string) { // Look up the payment methods available for the customer-configured Account params := &stripe.PaymentMethodListParams{ CustomerAccount: stripe.String(CustomerID), Type: stripe.String(stripe.PaymentMethodTypeCard), } var pm *stripe.PaymentMethod for p, err := range sc.V1PaymentMethods.List(context.TODO(), params).All(context.TODO()) { if err != nil { log.Printf("sc.V1Prices.List: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } pm = p break } paymentIntentParams := &stripe.PaymentIntentCreateParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.Currency{{CURRENCY}})), CustomerAccount: stripe.String(CustomerID), PaymentMethod: stripe.String(pm.ID), Confirm: stripe.Bool(true), OffSession: stripe.Bool(true), } // Charge the customer-configured Account and payment method immediately _, err := sc.V1PaymentIntents.Create(context.TODO(), paymentIntentParams) if err != nil { if stripeErr, ok := err.(*stripe.Error); ok { // Error code will be authentication_required if authentication is needed fmt.Printf("Error code: %v", stripeErr.Code) paymentIntentID := stripeErr.PaymentIntent.ID paymentIntent, _ := sc.V1PaymentIntents.Retrieve(context.TODO(), paymentIntentID, nil) fmt.Printf("PI: %v", paymentIntent.ID) } } } // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new Customer custParams := &stripe.CustomerCreateParams{} cust, _ := sc.V1Customers.Create(context.TODO(), custParams) // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new customer-configured Account acctParams := &stripe.V2CoreAccountCreateParams{ Configuration: &stripe.V2CoreAccountCreateConfigurationParams{ Customer: &stripe.V2CoreAccountCreateConfigurationCustomerParams{ Capabilities: &stripe.V2CoreAccountCreateConfigurationCustomerCapabilitiesParams{ AutomaticIndirectTax: &stripe.V2CoreAccountCreateConfigurationCustomerCapabilitiesAutomaticIndirectTaxParams{ Requested: stripe.Bool(true), }, }, }, }, } acct, _ := sc.V2CoreAccounts.Create(context.TODO(), acctParams) // Create a Tax Calculation for the items being sold taxCalculation := calculateTax(req.Items, "{{CURRENCY}}") // Create a PaymentIntent with amount and currency params := &stripe.PaymentIntentCreateParams{ Customer: stripe.String(cust.ID), SetupFutureUsage: stripe.String("off_session"), Amount: stripe.Int64(calculateOrderAmount(taxCalculation)), Amount: stripe.Int64(calculateOrderAmount(req.Items)), Currency: stripe.String(string(stripe.Currency{{CURRENCY}})), // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. AutomaticPaymentMethods: &stripe.PaymentIntentCreateAutomaticPaymentMethodsParams{ Enabled: stripe.Bool(true), }, } params.Hooks = &stripe.PaymentIntentCreateHooksParams{ Inputs: &stripe.PaymentIntentCreateHooksInputsParams{ Tax: &stripe.PaymentIntentCreateHooksInputsTaxParams{ Calculation: stripe.String(taxCalculation.ID), }, }, } pi, err := sc.V1PaymentIntents.Create(context.TODO(), params) if err != nil { log.Printf("sc.V1PaymentIntents.Create: %v", pi.ClientSecret) http.Error(w, err.Error(), http.StatusInternalServerError) log.Printf("sc.V1PaymentIntents.Create: %v", err) return } writeJSON(w, struct { ClientSecret string `json:"clientSecret"` }{ ClientSecret: pi.ClientSecret, }) // Create a PaymentIntent with amount and currency params := &stripe.PaymentIntentCreateParams{ CustomerAccount: stripe.String(acct.ID), SetupFutureUsage: stripe.String("off_session"), Amount: stripe.Int64(calculateOrderAmount(taxCalculation)), Amount: stripe.Int64(calculateOrderAmount(req.Items)), Currency: stripe.String(string(stripe.Currency{{CURRENCY}})), // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. AutomaticPaymentMethods: &stripe.PaymentIntentCreateAutomaticPaymentMethodsParams{ Enabled: stripe.Bool(true), }, } params.Hooks = &stripe.PaymentIntentCreateHooksParams{ Inputs: &stripe.PaymentIntentCreateHooksInputsParams{ Tax: &stripe.PaymentIntentCreateHooksInputsTaxParams{ Calculation: stripe.String(taxCalculation.ID), }, }, } pi, err := sc.V1PaymentIntents.Create(context.TODO(), params) log.Printf("pi.Create: %v", pi.ClientSecret) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Printf("pi.Create: %v", err) return } writeJSON(w, struct { ClientSecret string `json:"clientSecret"` }{ ClientSecret: pi.ClientSecret, }) using Stripe.Tax; using System.Linq; // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. services.AddSingleton(new StripeClient("<>")); private readonly StripeClient _client; public PaymentIntentApiController(StripeClient client) { _client = client; } // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new Customer var customer = _client.V1.Customers.Create(new CustomerCreateOptions()); // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new customer-configured Account var customerOptions = new Stripe.V2.Core.AccountCreateOptions { Configuration = new Stripe.V2.Core.AccountCreateConfigurationOptions { Customer = new Stripe.V2.Core.AccountCreateConfigurationCustomerOptions { Capabilities = new Stripe.V2.Core.AccountCreateConfigurationCustomerCapabilitiesOptions { AutomaticIndirectTax = new Stripe.V2.Core.AccountCreateConfigurationCustomerCapabilitiesAutomaticIndirectTaxOptions { Requested = true, }, }, } }, }; var account = _client.V2.Core.Accounts.Create(customerOptions); // Create a Tax Calculation for the items being sold var taxCalculation = CalculateTax(request.Items, "{{CURRENCY}}"); var paymentIntent = _client.V1.PaymentIntents.Create(new PaymentIntentCreateOptions { Customer = customer.Id, SetupFutureUsage = "off_session", CustomerAccount = account.Id, SetupFutureUsage = "off_session", Amount = CalculateOrderAmount(taxCalculation), Amount = CalculateOrderAmount(request.Items), Currency = "{{CURRENCY}}", // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions { Enabled = true, }, Hooks = new PaymentIntentHooksOptions { Inputs = new PaymentIntentHooksInputsOptions { Tax = new PaymentIntentHooksInputsTaxOptions { Calculation = taxCalculation.Id, }, }, }, Metadata = new Dictionary { { "tax_calculation", taxCalculation.Id }, }, }); return Json(new { clientSecret = paymentIntent.ClientSecret }); // Securely calculate the order amount, including tax [NonAction] public long CalculateOrderAmount(Calculation taxCalculation) { // Calculate the order total with any exclusive taxes on the server to prevent // people from directly manipulating the amount on the client return taxCalculation.AmountTotal; } private long CalculateOrderAmount(Item[] items) { // Calculate the order total on the server to prevent // people from directly manipulating the amount on the client long total = 0; foreach (Item item in items) { total += item.Amount; } return total; } [NonAction] public Calculation CalculateTax(Item[] items, string currency) { var lineItems = items.Select(item => BuildLineItem(item)).ToList(); var calculationCreateOptions = new CalculationCreateOptions { Currency = currency, CustomerDetails = new CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, LineItems = lineItems, }; var calculation = _client.V1.Tax.Calculations.Create(calculationCreateOptions); return calculation; } [NonAction] public CalculationLineItemOptions BuildLineItem(Item item) { return new CalculationLineItemOptions { Amount = item.Amount, // Amount in cents Reference = item.Id, // Unique reference for the item in the scope of the calculation }; } public void ChargeCustomer(string customerId) { // Lookup the payment methods available for the customer var availableMethods = _client.V1.PaymentMethods.List(new PaymentMethodListOptions { Customer = customerId, Type = "card", }); try { // Charge the customer and payment method immediately var paymentIntent = _client.V1.PaymentIntents.Create(new PaymentIntentCreateOptions { Amount = 1099, Currency = "{{CURRENCY}}", Customer = customerId, PaymentMethod = availableMethods.Data[0].Id, OffSession = true, Confirm = true }); } catch (StripeException e) { switch (e.StripeError.ErrorType) { case "card_error": // Error code will be authentication_required if authentication is needed Console.WriteLine("Error code: " + e.StripeError.Code); var paymentIntentId = e.StripeError.PaymentIntent.Id; var paymentIntent = _client.V1.PaymentIntents.Get(paymentIntentId); Console.WriteLine(paymentIntent.Id); break; default: break; } } } public void ChargeCustomer(string customerId) { // Lookup the payment methods available for the customer-configured Account var availableMethods = _client.V1.PaymentMethods.List(new PaymentMethodListOptions { CustomerAccount = customerId, Type = "card", }); try { // Charge the customer-configured Account and payment method immediately var paymentIntent = _client.V1.PaymentIntents.Create(new PaymentIntentCreateOptions { Amount = 1099, Currency = "{{CURRENCY}}", CustomerAccount = customerId, PaymentMethod = availableMethods.Data[0].Id, OffSession = true, Confirm = true }); } catch (StripeException e) { switch (e.StripeError.ErrorType) { case "card_error": // Error code will be authentication_required if authentication is needed Console.WriteLine("Error code: " + e.StripeError.Code); var paymentIntentId = e.StripeError.PaymentIntent.Id; var paymentIntent = _client.V1.PaymentIntents.Get(paymentIntentId); Console.WriteLine(paymentIntent.Id); break; default: break; } } } import com.stripe.model.Customer; import com.stripe.param.CustomerCreateParams; import com.stripe.model.v2.core.Account; import com.stripe.param.v2.core.AccountCreateParams; import com.stripe.model.PaymentMethod; import com.stripe.model.StripeCollection; import com.stripe.param.PaymentMethodListParams; import java.util.Arrays; import com.stripe.model.tax.Calculation; import com.stripe.param.tax.CalculationCreateParams; import com.stripe.param.tax.CalculationCreateParams.CustomerDetails; import com.stripe.param.tax.CalculationCreateParams.CustomerDetails.Address; import com.stripe.param.tax.CalculationCreateParams.CustomerDetails.AddressSource; import com.stripe.param.tax.CalculationCreateParams.LineItem; static Calculation calculateTax(List items, String currency) throws StripeException { List lineItems = items.stream() .map(Server::buildLineItem) .collect(Collectors.toList()); CalculationCreateParams.Builder createParamsBuilder = CalculationCreateParams.builder() .setCurrency(currency) .setCustomerDetails(CustomerDetails.builder() .setAddress(Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build()) .setAddressSource(AddressSource.SHIPPING) .build()) .addAllLineItem(lineItems); return client.v1().tax().calculations().create(createParamsBuilder.build()); } static LineItem buildLineItem(CreatePaymentItem item) { return LineItem.builder() .setAmount(item.getAmount()) // Amount in cents .setReference(item.getId()) // Unique reference for the item in the scope of the calculation .build(); } // Securely calculate the order amount, including tax static long calculateOrderAmount(Calculation taxCalculation) { // Calculate the order total with any exclusive taxes on the server to prevent // people from directly manipulating the amount on the client return taxCalculation.getAmountTotal(); } static int calculateOrderAmount(CreatePaymentItem[] items) { // Calculate the order total on the server to prevent // people from directly manipulating the amount on the client int total = 0; for (CreatePaymentItem item : items) { total += item.getAmount(); } return total; } // Call this function with the ID of the Customer you want to charge static void chargeCustomer(String customerId) throws StripeException { // Lookup the payment methods available for the customer PaymentMethodListParams listParams = new PaymentMethodListParams.Builder().setCustomer(customerId) .setType(PaymentMethodListParams.Type.CARD).build(); StripeCollection paymentMethods = client.v1().paymentMethods().list(listParams); PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder().setCurrency("{{CURRENCY}}") .setAmount(new Long(1099)) .setPaymentMethod(paymentMethods.getData().get(0).getId()) .setCustomer(customerId) .setConfirm(true) .setOffSession(true) .build(); try { // Charge the customer and payment method immediately PaymentIntent paymentIntent = client.v1().paymentIntents().create(createParams); } catch (CardException e) { // Error code will be authentication_required if authentication is needed System.out.println("Error code is : " + e.getCode()); String paymentIntentId = e.getStripeError().getPaymentIntent().getId(); PaymentIntent paymentIntent = client.v1().paymentIntents().retrieve(paymentIntentId); System.out.println(paymentIntent.getId()); } } // Call this function with the ID of the customer-configured Account you want to charge static void chargeCustomer(String customerId) throws StripeException { // Lookup the payment methods available for the customer-configured Account PaymentMethodListParams listParams = new PaymentMethodListParams.Builder().setCustomerAccount(customerId) .setType(PaymentMethodListParams.Type.CARD).build(); StripeCollection paymentMethods = client.v1().paymentMethods().list(listParams); PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder().setCurrency("{{CURRENCY}}") .setAmount(new Long(1099)) .setPaymentMethod(paymentMethods.getData().get(0).getId()) .setCustomerAccount(customerId) .setConfirm(true) .setOffSession(true) .build(); try { // Charge the customer-configured Account and payment method immediately PaymentIntent paymentIntent = client.v1().paymentIntents().create(createParams); } catch (CardException e) { // Error code will be authentication_required if authentication is needed System.out.println("Error code is : " + e.getCode()); String paymentIntentId = e.getStripeError().getPaymentIntent().getId(); PaymentIntent paymentIntent = client.v1().paymentIntents().retrieve(paymentIntentId); System.out.println(paymentIntent.getId()); } } // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. public static StripeClient client = new StripeClient("<>"); public static void main(String[] args) { port(4242); staticFiles.externalLocation(Paths.get("public").toAbsolutePath().toString()); // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new Customer CustomerCreateParams customerParams = new CustomerCreateParams.Builder().build(); Customer customer = client.v1().customers().create(customerParams); // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new customer-configured Account AccountCreateParams accountParams = AccountCreateParams .builder() .setConfiguration( AccountCreateParams.Configuration.builder() .setCustomer( AccountCreateParams.Configuration.Customer.builder() .setCapabilities( AccountCreateParams.Configuration.Customer.Capabilities.builder() .setAutomaticIndirectTax( AccountCreateParams.Configuration.Customer.Capabilities.AutomaticIndirectTax.builder() .setRequested(true) .build() ) .build() ) .build() ) .build() ) .build(); Account account = client.v2().core().accounts().create(accountParams); CreatePayment postBody = gson.fromJson(request.body(), CreatePayment.class); // Create a Tax Calculation for the items being sold Calculation taxCalculation = calculateTax(Arrays.asList(postBody.getItems()), "{{CURRENCY}}"); PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setCustomerAccount(account.getId()) .setSetupFutureUsage(PaymentIntentCreateParams.SetupFutureUsage.OFF_SESSION) .setAmount(calculateOrderAmount(taxCalculation)) .setAmount(new Long(calculateOrderAmount(postBody.getItems()))) .setCurrency("{{CURRENCY}}") // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. .setAutomaticPaymentMethods( PaymentIntentCreateParams.AutomaticPaymentMethods .builder() .setEnabled(true) .build() ) .setHooks( PaymentIntentCreateParams.Hooks .builder() .setInputs( PaymentIntentCreateParams.Hooks.Inputs .builder() .setTax( PaymentIntentCreateParams.Hooks.Inputs.Tax .builder() .setCalculation(taxCalculation.getId()) .build() ) .build() ) .build() ) .build(); // Create a PaymentIntent with the order amount and currency PaymentIntent paymentIntent = client.v1().paymentIntents().create(params); CreatePaymentResponse paymentResponse = new CreatePaymentResponse(paymentIntent.getClientSecret(), paymentIntent.getId()); return gson.toJson(paymentResponse); CreatePayment postBody = gson.fromJson(request.body(), CreatePayment.class); // Create a Tax Calculation for the items being sold Calculation taxCalculation = calculateTax(Arrays.asList(postBody.getItems()), "{{CURRENCY}}"); PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setCustomerAccount(customer.getId()) .setSetupFutureUsage(PaymentIntentCreateParams.SetupFutureUsage.OFF_SESSION) .setAmount(calculateOrderAmount(taxCalculation)) .setAmount(new Long(calculateOrderAmount(postBody.getItems()))) .setCurrency("{{CURRENCY}}") // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. .setAutomaticPaymentMethods( PaymentIntentCreateParams.AutomaticPaymentMethods .builder() .setEnabled(true) .build() ) .setHooks( PaymentIntentCreateParams.Hooks .builder() .setInputs( PaymentIntentCreateParams.Hooks.Inputs .builder() .setTax( PaymentIntentCreateParams.Hooks.Inputs.Tax .builder() .setCalculation(taxCalculation.getId()) .build() ) .build() ) .build() ) .build(); // Create a PaymentIntent with the order amount and currency PaymentIntent paymentIntent = client.v1().paymentIntents().create(params); CreatePaymentResponse paymentResponse = new CreatePaymentResponse(paymentIntent.getClientSecret(), paymentIntent.getId()); return gson.toJson(paymentResponse); import React, { useState, useEffect } from "react"; import { loadStripe } from "@stripe/stripe-js"; import { Elements } from "@stripe/react-stripe-js"; // Make sure to call loadStripe outside of a component’s render to avoid // recreating the Stripe object on every render. // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. const stripePromise = loadStripe("<>"); useEffect(() => { // Create PaymentIntent as soon as the page loads fetch("/create-payment-intent", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items: [{ id: "xl-tshirt", amount: 1000 }] }), }) .then((res) => res.json()) .then((data) => setClientSecret(data.clientSecret)); }, []); useEffect(() => { // Create PaymentIntent as soon as the page loads fetch("/create.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items: [{ id: "xl-tshirt", amount: 1000 }] }), }) .then((res) => res.json()) .then((data) => setClientSecret(data.clientSecret)); }, []); const appearance = { {{APPEARANCE}} }; {clientSecret && ( } /> } /> )} const clientSecret = new URLSearchParams(window.location.search).get( "payment_intent_client_secret" ); if (!clientSecret) { return; } stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => { if (!paymentIntent) { return; } setStatus(paymentIntent.status); setIntentId(paymentIntent.id); }); const stripe = useStripe(); const elements = useElements(); const [email, setEmail] = useState(''); const [message, setMessage] = useState(null); const [isLoading, setIsLoading] = useState(false); const { error } = await stripe.confirmPayment({ elements, confirmParams: { // Make sure to change this to your payment completion page return_url: "http://localhost:3000/complete", receipt_email: email, }, }); // This point will only be reached if there is an immediate error when // confirming the payment. Otherwise, your customer will be redirected to // your `return_url`. For some payment methods like iDEAL, your customer will // be redirected to an intermediate site first to authorize the payment, then // redirected to the `return_url`. if (error.type === "card_error" || error.type === "validation_error") { setMessage(error.message); } else { setMessage("An unexpected error occurred."); } setIsLoading(false); setEmail(e.target.value)} placeholder="Enter email address" /> #email { border-radius: 6px; margin-bottom: 16px; padding: 12px; border: 1px solid rgba(50, 50, 93, 0.1); max-height: 44px; font-size: 16px; width: 100%; background: white; box-sizing: border-box; }
const stripe = Stripe("<>"); // Fetches a payment intent and captures the client secret async function initialize() { const response = await fetch("/create-payment-intent", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items }), }); const { clientSecret } = await response.json(); const appearance = { {{APPEARANCE}} }; elements = stripe.elements({ appearance, clientSecret }); const paymentElementOptions = { layout: "accordion", }; const paymentElement = elements.create("payment", paymentElementOptions); paymentElement.mount("#payment-element"); } // Fetches a payment intent and captures the client secret async function initialize() { const { clientSecret } = await fetch("/create.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items }), }).then((r) => r.json()); elements = stripe.elements({ clientSecret }); const paymentElementOptions = { layout: "accordion", }; const paymentElement = elements.create("payment", paymentElementOptions); paymentElement.mount("#payment-element"); } async function handleSubmit(e) { e.preventDefault(); setLoading(true); const { error } = await stripe.confirmPayment({ elements, confirmParams: { // Make sure to change this to your payment completion page return_url: "http://localhost:4242/complete.html", receipt_email: document.getElementById("email").value, }, }); // This point will only be reached if there is an immediate error when // confirming the payment. Otherwise, your customer will be redirected to // your `return_url`. For some payment methods like iDEAL, your customer will // be redirected to an intermediate site first to authorize the payment, then // redirected to the `return_url`. if (error.type === "card_error" || error.type === "validation_error") { showMessage(error.message); } else { showMessage("An unexpected error occurred."); } setLoading(false); } async function handleSubmit(e) { e.preventDefault(); setLoading(true); const { error } = await stripe.confirmPayment({ elements, confirmParams: { // Make sure to change this to your payment completion page return_url: "http://localhost:4242/complete.html", receipt_email: document.getElementById("email").value, }, }); // This point will only be reached if there is an immediate error when // confirming the payment. Otherwise, your customer will be redirected to // your `return_url`. For some payment methods like iDEAL, your customer will // be redirected to an intermediate site first to authorize the payment, then // redirected to the `return_url`. if (error.type === "card_error" || error.type === "validation_error") { showMessage(error.message); } else { showMessage("An unexpected error occurred."); } setLoading(false); } #email { border-radius: 6px; margin-bottom: 16px; padding: 12px; border: 1px solid rgba(50, 50, 93, 0.1); max-height: 44px; font-size: 16px; width: 100%; background: white; box-sizing: border-box; } const stripe = Stripe("<>"); // Fetches the payment intent status after payment submission async function checkStatus() { const clientSecret = new URLSearchParams(window.location.search).get( "payment_intent_client_secret" ); if (!clientSecret) { setErrorState(); return; } const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret); setPaymentDetails(paymentIntent); } import { PaymentElement, useStripe, useElements, Elements } from '@stripe/react-stripe-js' import { loadStripe } from '@stripe/stripe-js' // Make sure to call loadStripe outside of a component’s render to avoid // recreating the Stripe object on every render. // This is your test publishable API key. const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY) const stripe = useStripe(); const elements = useElements(); const [email, setEmail] = useState(''); const [message, setMessage] = useState(null); const [isLoading, setIsLoading] = useState(false); const { error } = await stripe.confirmPayment({ elements, confirmParams: { // Make sure to change this to your payment completion page return_url: "http://localhost:3000/success", receipt_email: email, }, }); // This point will only be reached if there is an immediate error when // confirming the payment. Otherwise, your customer will be redirected to // your `return_url`. For some payment methods like iDEAL, your customer will // be redirected to an intermediate site first to authorize the payment, then // redirected to the `return_url`. if (error.type === "card_error" || error.type === "validation_error") { setMessage(error.message); } else { setMessage("An unexpected error occurred."); } setIsLoading(false); setEmail(e.target.value)} placeholder="Enter email address" /> const appearance = { {{APPEARANCE}} }; const { payment_intent: paymentIntentId } = await searchParams if (!paymentIntentId) redirect('/') const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId) if (!paymentIntent) redirect('/') const { status } = paymentIntent \# https://dashboard.stripe.com/apikeys NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=<> STRIPE_SECRET_KEY=<> \# Set this environment variable to support webhooks — https://stripe.com/docs/webhooks#verify-events # STRIPE_WEBHOOK_SECRET=whsec_12345 const calculateTax = async (items, currency) => { const taxCalculation = await stripe.tax.calculations.create({ currency, customer_details: { address: { line1: "920 5th Ave", city: "Seattle", state: "WA", postal_code: "98104", country: "US", }, address_source: "shipping", }, line_items: items.map((item) => buildLineItem(item)), }); return taxCalculation; }; const buildLineItem = (item) => { return { amount: item.amount, // Amount in cents reference: item.id, // Unique reference for the item in the scope of the calculation }; }; // Securely calculate the order amount, including tax const calculateOrderAmount = (items, taxCalculation) => { // Replace this constant with a calculation of the order's amount // Calculate the order total with any exclusive taxes on the server to prevent // people from directly manipulating the amount on the client let orderAmount = 1400; orderAmount += taxCalculation.tax_amount_exclusive; return orderAmount; }; const calculateOrderAmount = (items) => { // Replace this constant with a calculation of the order's amount // Calculate the order total on the server to prevent // people from directly manipulating the amount on the client return 1400; }; const chargeCustomer = async (customerId) => { // Lookup the payment methods available for the customer const paymentMethods = await stripe.paymentMethods.list({ customer: customerId, type: "card", }); try { // Charge the customer and payment method immediately const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: "eur", customer: customerId, payment_method: paymentMethods.data[0].id, off_session: true, confirm: true, }); } catch (err) { // Error code will be authentication_required if authentication is needed console.log("Error code is: ", err.code); const paymentIntentRetrieved = await stripe.paymentIntents.retrieve(err.raw.payment_intent.id); console.log("PI retrieved: ", paymentIntentRetrieved.id); } }; // Alternatively, set up a webhook to listen for the payment_intent.succeeded event // and attach the PaymentMethod to a new Customer const customer = await stripe.customers.create(); const items = [{ id: 'xl-tshirt', amount: 1000 }] const taxCalculation = await calculateTax(items, "eur"); const amount = await calculateOrderAmount(items, taxCalculation); // Create PaymentIntent as soon as the page loads const { client_secret: clientSecret } = await stripe.paymentIntents.create({ customer: customer.id, setup_future_usage: "off_session", amount, amount: calculateOrderAmount([{ id: 'xl-tshirt' }]), currency: 'eur', // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: { enabled: true, }, metadata: { tax_calculation: taxCalculation.id }, }) import 'server-only'; import Stripe from 'stripe'; export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); export async function POST(req) { import StripePaymentSheet private lazy var addressViewController: AddressViewController? = { return AddressViewController(configuration: self.addressConfiguration, delegate: self) }() private var addressDetails: AddressViewController.AddressDetails? private var addressConfiguration: AddressViewController.Configuration { return AddressViewController.Configuration(additionalFields: .init(phone: .optional)) } private lazy var addressButton: UIButton = { let button = UIButton(type: .custom) button.setTitle("Add shipping address", for: .normal) button.backgroundColor = .systemIndigo button.layer.cornerRadius = 5 button.contentEdgeInsets = UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12) button.addTarget(self, action: #selector(didTapShippingAddressButton), for: .touchUpInside) button.translatesAutoresizingMaskIntoConstraints = false return button }() StripeAPI.defaultPublishableKey = "<>" view.addSubview(addressButton) NSLayoutConstraint.activate([ addressButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16), addressButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16), addressButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -80) ]) func fetchPaymentIntent() { let url = Self.backendURL.appendingPathComponent("/create-payment-intent") let shoppingCartContent: [String: Any] = [ "items": [ ["id": "xl-shirt"] ["id": "xl-shirt", "amount": 1000] ] ] var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try? JSONSerialization.data(withJSONObject: shoppingCartContent) let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let response = response as? HTTPURLResponse, response.statusCode == 200, let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let clientSecret = json["clientSecret"] as? String else { let message = error?.localizedDescription ?? "Failed to decode response from server." self?.displayAlert(title: "Error loading page", message: message) return } print("Created PaymentIntent") self?.paymentIntentClientSecret = clientSecret DispatchQueue.main.async { self?.payButton.isEnabled = true } }) task.resume() } var configuration = PaymentSheet.Configuration() configuration.merchantDisplayName = "Example, Inc." configuration.allowsDelayedPaymentMethods = true configuration.primaryButtonColor = UIColor(red: 1.0, green: 0.82, blue: 0.04, alpha: 1.0) configuration.applePay = .init( merchantId: "com.example.appname", merchantCountryCode: "US" ) configuration.shippingDetails = { [weak self] in return self?.addressDetails } let paymentSheet = PaymentSheet( paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) paymentSheet.present(from: self) { [weak self] (paymentResult) in switch paymentResult { case .completed: self?.displayAlert(title: "Payment complete!") case .canceled: print("Payment canceled!") case .failed(let error): self?.displayAlert(title: "Payment failed", message: error.localizedDescription) } @objc func didTapShippingAddressButton() { present(UINavigationController(rootViewController: addressViewController!), animated: true) } // MARK: - AddressViewControllerDelegate extension CheckoutViewController: AddressViewControllerDelegate { func addressViewControllerDidFinish(_ addressViewController: AddressViewController, with address: AddressViewController.AddressDetails?) { addressViewController.dismiss(animated: true) self.addressDetails = address } } NSCameraUsageDescription Allow the app to scan cards. PaymentConfiguration.init( applicationContext, "<>" ) import androidx.compose.foundation.layout.Column import androidx.compose.ui.platform.LocalContext import com.stripe.android.PaymentConfiguration import com.stripe.android.paymentsheet.addresselement.AddressDetails import com.stripe.android.paymentsheet.addresselement.AddressLauncher import com.stripe.android.paymentsheet.addresselement.AddressLauncher.AdditionalFieldsConfiguration import com.stripe.android.paymentsheet.addresselement.AddressLauncherResult import com.stripe.android.paymentsheet.addresselement.rememberAddressLauncher private val addressConfiguration = AddressLauncher.Configuration.Builder() .additionalFields( AdditionalFieldsConfiguration( AdditionalFieldsConfiguration.FieldConfiguration.REQUIRED ) ) .allowedCountries(setOf("US", "CA", "GB")) .title("Shipping Address") .googlePlacesApiKey("(optional) YOUR KEY HERE") .build() when (paymentResult) { is PaymentSheetResult.Completed -> showToast("Payment complete!") is PaymentSheetResult.Canceled -> showToast("Payment canceled!") is PaymentSheetResult.Failed -> { error = paymentResult.error.localizedMessage ?: paymentResult.error.message } } val context = LocalContext.current var shippingDetails by remember { mutableStateOf(null) } val addressLauncher = rememberAddressLauncher { result -> when (result) { is AddressLauncherResult.Succeeded -> { shippingDetails = result.address showToast("Address selection complete!") } is AddressLauncherResult.Canceled -> showToast("Address selection canceled!") } } Column( modifier = Modifier.fillMaxWidth() ) { AddressButton { addressLauncher.present( publishableKey = PaymentConfiguration.getInstance(context).publishableKey, configuration = addressConfiguration ) } PayButton( enabled = paymentIntentClientSecret != null, onClick = { paymentIntentClientSecret?.let { onPayClicked( paymentSheet = paymentSheet, paymentIntentClientSecret = it, shippingDetails = shippingDetails, ) } } ) } PayButton( enabled = paymentIntentClientSecret != null, onClick = { paymentIntentClientSecret?.let { onPayClicked( paymentSheet = paymentSheet, paymentIntentClientSecret = it, ) } } ) @Composable private fun AddressButton( onClick: () -> Unit ) { Button( modifier = Modifier.fillMaxWidth(), onClick = onClick ) { Text("Add shipping address") } } private suspend fun fetchPaymentIntent(): Result = suspendCoroutine { continuation -> val url = "$BACKEND_URL/create-payment-intent" val shoppingCartContent = """ { "items": [ {"id":"xl-tshirt"} {"id":"xl-tshirt", "amount":1000} ] } """ val mediaType = "application/json; charset=utf-8".toMediaType() val body = shoppingCartContent.toRequestBody(mediaType) val request = Request.Builder() .url(url) .post(body) .build() OkHttpClient() .newCall(request) .enqueue(object: Callback { override fun onFailure(call: Call, e: IOException) { continuation.resume(Result.failure(e)) } override fun onResponse(call: Call, response: Response) { if (!response.isSuccessful) { continuation.resume(Result.failure(Exception(response.message))) } else { val clientSecret = extractClientSecretFromResponse(response) clientSecret?.let { secret -> continuation.resume(Result.success(secret)) } ?: run { val error = Exception("Could not find payment intent client secret in response!") continuation.resume(Result.failure(error)) } } } }) } private fun extractClientSecretFromResponse(response: Response): String? { return try { val responseData = response.body?.string() val responseJson = responseData?.let { JSONObject(it) } ?: JSONObject() responseJson.getString("clientSecret") } catch (exception: JSONException) { null } } shippingDetails: AddressDetails?, val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Example, Inc.") .shippingDetails(shippingDetails) .allowsDelayedPaymentMethods(true) .appearance( PaymentSheet.Appearance( primaryButton = PaymentSheet.PrimaryButton( colorsLight = PaymentSheet.PrimaryButtonColors( background = Color(red = 248, green = 72, blue = 94), onBackground = Color.White, border = Color.Unspecified ) ) ) ) .googlePay( PaymentSheet.GooglePayConfiguration( environment = PaymentSheet.GooglePayConfiguration.Environment.Test, countryCode = "US" ) ) .build() // Present Payment Sheet paymentSheet.presentWithPaymentIntent(paymentIntentClientSecret, configuration) PaymentConfiguration.init( getApplicationContext(), "<>" ); import com.stripe.android.paymentsheet.addresselement.AddressDetails; import com.stripe.android.paymentsheet.addresselement.AddressLauncher; import com.stripe.android.paymentsheet.addresselement.AddressLauncherResult; private AddressLauncher addressLauncher; private AddressDetails shippingDetails; private Button addressButton; private final AddressLauncher.Configuration configuration = new AddressLauncher.Configuration.Builder() .additionalFields( new AddressLauncher.AdditionalFieldsConfiguration( AddressLauncher.AdditionalFieldsConfiguration.FieldConfiguration.REQUIRED ) ) .allowedCountries(new HashSet<>(Arrays.asList("US", "CA", "GB"))) .title("Shipping Address") .googlePlacesApiKey("(optional) YOUR KEY HERE") .build(); // Hook up the address button addressButton = findViewById(R.id.address_button); addressButton.setOnClickListener(this::onAddressClicked); addressLauncher = new AddressLauncher(this, this::onAddressLauncherResult); private void fetchPaymentIntent() { final String shoppingCartContent = "{\"items\": [ {\"id\":\"xl-tshirt\"}]}"; final String shoppingCartContent = "{\"items\": [ {\"id\":\"xl-tshirt\", \"amount\":1000}]}"; final RequestBody requestBody = RequestBody.create( shoppingCartContent, MediaType.get("application/json; charset=utf-8") ); Request request = new Request.Builder() .url(BACKEND_URL + "/create-payment-intent") .post(requestBody) .build(); new OkHttpClient() .newCall(request) .enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { showAlert("Failed to load data", "Error: " + e.toString()); } @Override public void onResponse( @NonNull Call call, @NonNull Response response ) throws IOException { if (!response.isSuccessful()) { showAlert( "Failed to load page", "Error: " + response.toString() ); } else { final JSONObject responseJson = parseResponse(response.body()); paymentIntentClientSecret = responseJson.optString("clientSecret"); runOnUiThread(() -> payButton.setEnabled(true)); Log.i(TAG, "Retrieved PaymentIntent"); } } }); } PaymentSheet.Configuration configuration = new PaymentSheet.Configuration.Builder("Example, Inc.") .allowsDelayedPaymentMethods(true) .primaryButtonColor(ColorStateList.valueOf(Color.rgb(248, 72, 94))) .googlePay(new PaymentSheet.GooglePayConfiguration( PaymentSheet.GooglePayConfiguration.Environment.Test, "US")) .build(); // Present Payment Sheet paymentSheet.presentWithPaymentIntent(paymentIntentClientSecret, configuration); private void onAddressClicked(View view) { AddressLauncher.Configuration addressConfiguration = new AddressLauncher.Configuration.Builder().address(shippingDetails).build(); String publishableKey = PaymentConfiguration.getInstance(this.getApplicationContext()).getPublishableKey(); addressLauncher.present( publishableKey, addressConfiguration ); } if (paymentSheetResult instanceof PaymentSheetResult.Completed) { showToast("Payment complete!"); } else if (paymentSheetResult instanceof PaymentSheetResult.Canceled) { Log.i(TAG, "Payment canceled!"); } else if (paymentSheetResult instanceof PaymentSheetResult.Failed) { Throwable error = ((PaymentSheetResult.Failed) paymentSheetResult).getError(); showAlert("Payment failed", error.getLocalizedMessage()); } private void onAddressLauncherResult(AddressLauncherResult result) { // TODO: Handle result and update your UI if (result instanceof AddressLauncherResult.Succeeded) { shippingDetails = ((AddressLauncherResult.Succeeded) result).getAddress(); } else if (result instanceof AddressLauncherResult.Canceled) { // TODO: Handle cancel } } { "name": "stripe-sample", "version": "1.0.0", "description": "A sample Stripe implementation", "main": "server.js", "scripts": { "start": "node server.js" }, "author": "stripe-samples", "license": "ISC", "dependencies": { "express": "^4.17.1", "stripe": "^21.0.1" } } { "name": "stripe-sample", "version": "0.1.0", "dependencies": { "@stripe/react-stripe-js": "^3.7.0", "@stripe/stripe-js": "^7.3.0", "express": "^4.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "^3.4.0", "stripe": "21.0.1" }, "devDependencies": { "concurrently": "4.1.2" }, "homepage": "http://localhost:3000/checkout", "proxy": "http://localhost:4242", "scripts": { "start-client": "react-scripts start", "start-server": "node server.js", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "start": "concurrently \"yarn start-client\" \"yarn start-server\"" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } require github.com/stripe/stripe-go/v85 v85.0.0 certifi==2026.1.4 chardet==5.2.0 click==8.3.1 Flask==3.1.2 idna==3.11 itsdangerous==2.2.0 Jinja2==3.1.6 MarkupSafe==3.0.3 requests==2.32.5 stripe==15.0.0 toml==0.10.2 Werkzeug==3.1.5 { "name": "stripe-sample", "version": "0.2.0", "license": "ISC", "dependencies": { "@stripe/react-stripe-js": "^3.7.0", "@stripe/stripe-js": "^7.3.0", "express": "^4.21.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.26.2", "react-scripts": "^5.0.1", "stripe": "^16.12.0" }, "devDependencies": { "@babel/plugin-transform-private-property-in-object": "^7.25.7", "concurrently": "^9.0.1" }, "homepage": "http://localhost:3000/checkout", "proxy": "http://localhost:4242", "scripts": { "start-client": "react-scripts start", "start-server": "node server.js", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "start": "concurrently \"yarn start-client\" \"yarn start-server\"" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } { "name": "client", "version": "0.1.0", "private": true, "dependencies": { "@stripe/react-stripe-js": "^3.7.0", "@stripe/stripe-js": "^7.3.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.26.1", "react-scripts": "^5.0.1" }, "homepage": "http://localhost:3000/checkout", "proxy": "http://localhost:4242", "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } 1. Build the server ~~~ pip3 install -r requirements.txt ~~~ 1. Build the server ~~~ bundle install ~~~ 1. Build the server ~~~ composer install ~~~ 1. Build the server ~~~ dotnet restore ~~~ 1. Build the server ~~~ mvn package ~~~ 2. Run the server ~~~ export FLASK_APP=server.py python3 -m flask run --port=4242 ~~~ 2. Run the server ~~~ ruby server.rb -o 0.0.0.0 ~~~ 2. Run the server ~~~ php -S 127.0.0.1:4242 --docroot=public ~~~ 2. Run the server ~~~ dotnet run ~~~ 2. Run the server ~~~ java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server ~~~ 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout) 3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout) 3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout) 3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout) 3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout) 3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html) 1. Run the server ~~~ go run server.go ~~~ 2. Build the client app ~~~ npm install ~~~ 3. Run the client app ~~~ npm start ~~~ 4. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout) 1. Run the server ~~~ go run server.go ~~~ 2. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html) 1. Build the application ~~~ npm install ~~~ 2. Run the application ~~~ npm start ~~~ 3. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout) \## API Keys This code sample uses a public sample test API key. Don’t submit any personally identifiable information in requests made with this key. The "View details" link to see the PaymentIntent details in the Dashboard won't work until you use your own test [API key](https://docs.stripe.com/keys). 1. Build the server ~~~ npm install ~~~ 2. Run the server ~~~ npm start ~~~ 3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html) \### Development 1. Build the application ~~~shell $ npm install ~~~ 2. Download and run the [Stripe CLI](https://stripe.com/docs/stripe-cli). The Stripe CLI is a developer tool that helps you build, test, and manage your integration with Stripe directly from the command line. ~~~shell $ stripe listen --forward-to localhost:3000/api/webhooks ~~~ 3. Run the application ~~~shell $ STRIPE_WEBHOOK_SECRET=$(stripe listen --print-secret) npm run dev ~~~ 4. Go to [localhost:3000](http://localhost:3000) ### Production 1. Build the application ~~~shell $ npm install $ npm build ~~~ 2. Run the application ~~~shell $ npm start ~~~ ### 安装 Stripe Node 库 安装软件包并将它导入到您的代码中。或者,如果您要从头开始且需要 package.json 文件,请用代码编辑器中的 Download 链接来下载项目文件。 #### npm 安装库: ```bash npm install --save stripe ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-node) 下载 stripe-node 库源代码。 ### 安装 Stripe Ruby 库 安装 Stripe ruby gem,并在代码中要求使用它。或者,如果您要从头开始且需要 Gemfile 的话,请用代码编辑器中的链接来下载项目文件。 #### Terminal 安装 gem: ```bash gem install stripe ``` #### Bundler 将这一行添加到您的 Gemfile: ```bash gem 'stripe' ``` #### GitHub 也可直接[从 GitHub](https://github.com/stripe/stripe-ruby) 下载 stripe-ruby gem 源代码。 ### 安装 Stripe Java 库 将依赖项添加到您的版本并导入库。或者,如果您要从头开始且需要 pom.xml 样本文件 (Maven) 的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### Maven 将以下依赖项添加到您的 POM,并将 {VERSION} 替换为您想使用的版本号。 ```bash \ncom.stripe\nstripe-java\n{VERSION}\n ``` #### Gradle 将依赖项添加到您的 build.gradle 文件,并将 {VERSION} 替换为您想使用的版本号。 ```bash implementation "com.stripe:stripe-java:{VERSION}" ``` #### GitHub 直接[从 GitHub](https://github.com/stripe/stripe-java/releases/latest) 下载 JAR。 ### 安装 Stripe Python 软件包 安装 Stripe 软件包并将它导入到您的代码。或者,如果您要从头开始且需要 requirements.txt 文件的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### pip 通过 pip 安装软件包: ```bash pip3 install stripe ``` #### GitHub 直接[从 GitHub](https://github.com/stripe/stripe-python) 下载 stripe-python 库的源代码。 ### 安装 Stripe PHP 库 用 composer 安装库,并用您的秘密 API 密钥初始化。或者,如果您要从头开始且需要 composer.json 文件的话,可以用代码编辑器中的 Download 链接来下载文件。 #### Composer 安装库: ```bash composer require stripe/stripe-php ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-php) 下载 stripe-php 库源代码。 ### 设置您的服务器 将依赖项添加到您的版本并导入库。或者,如果您要从头开始且需要 go.mod 文件的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### Go 请务必用 Go 模块进行初始化: ```bash go get -u github.com/stripe/stripe-go/v85 ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-go) 下载 stripe-go 模块源代码。 ### 安装 Stripe.net 库 使用 .NET 或 NuGet 安装软件包。或者,如果您要从头开始,请下载包含已配置的 .csproj 文件的文件。 #### dotnet 安装库: ```bash dotnet add package Stripe.net ``` #### NuGet 安装库: ```bash Install-Package Stripe.net ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-dotnet) 下载 Stripe.net 库源代码。 ### 安装 Stripe 库 安装软件包并将其导入到您的代码中。或者,如果您要从头开始且需要 `package.json` 文件,请用代码编辑器中的链接来下载项目文件。 安装库: ```bash npm install --save stripe @stripe/stripe-js next ``` ### 创建 PaymentIntent 在服务器上添加一个创建 [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) 的端点。PaymentIntent 跟踪客户的支付生命周期,记录任何失败的支付尝试,并确保客户仅被收取一次费用。在响应中返回 PaymentIntent 的*客户端密钥* (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))以在客户端完成支付。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 将 Stripe 添加到您的 React 应用 使用 *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) 以及 [Stripe Elements UI 库](https://docs.stripe.com/sdks/stripejs-react.md),确保付款详情直接进入 Stripe 而不会到达您的服务器,从而保持 *PCI 合规* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business)。 ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` ### 将 Stripe 添加到您的 React 应用 使用 *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) 以及 [Stripe Elements UI 库](https://docs.stripe.com/sdks/stripejs-react.md),确保付款详情直接进入 Stripe 而不会到达您的服务器,从而保持 *PCI 合规* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business)。 ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` ### Load Stripe.js 用您的 Stripe [API 公钥](https://docs.stripe.com/keys.md#obtain-api-keys)调用 `loadStripe()`,从而配置 Stripe 库。 ### Load Stripe.js 用您的 Stripe [API 公钥](https://docs.stripe.com/keys.md#obtain-api-keys)调用 `loadStripe()`,从而配置 Stripe 库。 ### Load Stripe.js 使用 *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs),确保支付详情直接发送到 Stripe 而不接触您的服务器,从而保持 *PCI 合规* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business)。始终从 js.stripe.com 加载 Stripe.js 以保持合规。请勿将脚本包含在捆绑包中或自行托管它。 ### 定义支付表单 为要装载的每个 Element 在结账表单中添加一个空占位符 `div`。Stripe 在每个 `div` 中插入一个 iframe,以安全地收集客户的电子邮件地址和支付信息。 ### 初始化 Stripe.js 用您的 [API 公钥](https://docs.stripe.com/keys.md#obtain-api-keys)初始化 Stripe.js。您将使用 Stripe.js 创建 Payment Element 并在客户端完成付款。 ### 获取 PaymentIntent 在加载您的结账页面后,立即向您的服务器端点发出请求以创建一个新的 PaymentIntent。您的端点返回的 `clientSecret` 用于完成支付。 ### 初始化 Stripe Elements 将 `loadStripe` 中产生的 promise 传递给 Elements 提供程序。这样即可让子组件通过 Elements 使用者访问 Stripe 服务。此外,将客户端私钥作为一种选项传递给 Elements 提供程序。 ### 初始化 Stripe Elements 将 `loadStripe` 中产生的 promise 传递给 Elements 提供程序。这样即可让子组件通过 Elements 使用者访问 Stripe 服务。此外,将客户端私钥作为一种选项传递给 Elements 提供程序。 ### 初始化 Stripe Elements 用客户端私钥初始化 [Stripe Elements UI 库](https://docs.stripe.com/js/elements_object/create)。Elements 管理收集银行卡详情所需的 UI 组件。 ### 设置状态 初始化一些状态来跟踪付款、显示错误及管理用户界面。 ### 设置状态 初始化一些状态来跟踪付款、显示错误及管理用户界面。 ### 存储给 Stripe 的参考信息 用 `useStripe()` 和 `useElements()` 钩子访问您的 CheckoutForm 组件中的 Stripe 库。如果您需要通过 Class Component 访问 Element,请改用 [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer)。 ### 存储给 Stripe 的参考信息 用 `useStripe()` 和 `useElements()` 钩子访问您的 CheckoutForm 组件中的 Stripe 库。如果您需要通过 Class Component 访问 Element,请改为使用 [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer)。 ### 添加 PaymentElement 将 [PaymentElement](https://docs.stripe.com/js/elements_object/create_payment_element) 添加到您的支付表单。它嵌入了一个带有动态表单的 iframe,用于收集各种支付方式的支付信息。您的客户可以选择一种支付方式类型,然后表单会自动收集他们选择的所有必要的支付信息。 ### 添加 PaymentElement 将 [PaymentElement](https://docs.stripe.com/js/elements_object/create_payment_element) 添加到您的支付表单。它嵌入了一个带有动态表单的 iframe,用于收集各种支付方式的支付信息。您的客户可以选择一种支付方式类型,然后表单会自动收集他们选择的所有必要的支付信息。 ### 创建 PaymentElement 创建一个 [PaymentElement](https://docs.stripe.com/js/elements_object/create_payment_element),并将其挂载到支付表单的占位符 `
`。这会嵌入一个带有动态表单的 iframe,该表单显示 PaymentIntent 中可用的已配置的支付方式类型,允许您的客户选择支付方式。该表单会自动收集所选支付方式类型的相关支付信息。 ### (可选)设置 Payment Element 的样式 通过创建[外观对象](https://docs.stripe.com/elements/appearance-api.md) 并将其作为选项传递给 Elements 提供商,来定制 Payment Element 用户界面。使用您公司的配色方案和字体,使其与结账页面的其余部分相匹配。通过使用[字体集](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-fonts) 初始化 Elements 来使用自定义字体(例如来自 Google Fonts 的字体)。 确保打开右侧的预览以实时查看更改。 > 预览演示的某些部分可能与您的实际结账页面不一致。上述设置仅代表[外观对象](https://docs.stripe.com/elements/appearance-api.md) 变量的子集,而[外观对象](https://docs.stripe.com/elements/appearance-api.md) 仅控制 Stripe Elements 的某些属性。您负责设置结账页面其余部分的样式。 ### (可选)设置 Payment Element 的样式 通过创建[外观对象](https://docs.stripe.com/elements/appearance-api.md) 并将其作为选项传递给 Elements 提供商,来定制 Payment Element 用户界面。使用您公司的配色方案和字体,使其与结账页面的其余部分相匹配。通过使用[字体集](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-fonts) 初始化 Elements 来使用自定义字体(例如来自 Google Fonts 的字体)。 确保打开右侧的预览以实时查看更改。 > 预览演示的某些内容可能与您的实际结账页面有出入。上述设置仅表示 Appearance 对象变量的一个子集,Appearance 对象仅控制 Stripe Element 的某些属性。您负责设计结账页面其余部分的样式。 ### (可选)设置 Payment Element 的样式 通过创建[外观对象](https://docs.stripe.com/elements/appearance-api.md),并使用它初始化 Elements 来自定义 Payment Element 用户界面。使用您公司的配色方案和字体,使其与结账页面的其余部分相匹配。通过使用[字体集](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-fonts) 初始化 Elements 来使用自定义字体(例如来自 Google Fonts 的字体)。 确保打开右侧的预览以实时查看更改。 > 预览演示的某些部分可能与您的实际结账页面不一致。上述设置仅代表[外观对象](https://docs.stripe.com/elements/appearance-api.md) 变量的子集,而[外观对象](https://docs.stripe.com/elements/appearance-api.md) 仅控制 Stripe Elements 的某些属性。您负责设置结账页面其余部分的样式。 ### 处理提交事件 侦听表单的提交事件,知道何时通过 Stripe API 确认付款。 ### 完成付款 客户点击支付按钮时,使用 PaymentElement 调用 [confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) 并传递 [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url),以指示 Stripe 在客户完成支付后将其重定向到何处。对于需要身份验证的支付,Stripe 会显示 *3D Secure* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments) 身份验证模式,或者根据支付方式将客户重定向到身份验证页面。客户完成身份验证流程后,会被重定向到 `return_url`。 ### 完成付款 客户点击支付按钮时,使用 PaymentElement 调用 [confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) 并传递 [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url),以指示 Stripe 在客户完成支付后将其重定向到何处。对于需要身份验证的支付,Stripe 会显示 *3D Secure* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments) 身份验证模式,或者根据支付方式将客户重定向到身份验证页面。客户完成身份验证流程后,会被重定向到 `return_url`。 ### 完成付款 使用 Element 实例和 [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) 调用 [confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment),指示 Stripe 在客户完成支付后将其重定向到何处。对于需要身份验证的支付,Stripe 会显示 *3D Secure* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments) 身份验证模式,或者根据支付方式将客户重定向到身份验证页面。客户完成身份验证流程后,会被重定向到 `return_url`。 ### 处理错误 如果有任何即时[错误](https://docs.stripe.com/error-codes.md)(例如,您客户的卡被拒绝),则 Stripe.js 返回一个错误。向客户显示此错误消息,以便他们重试。 ### 显示支付状态消息 当 Stripe 将客户重定向到 `return_url` 时,`payment_intent_client_secret` 查询参数会加上 Stripe.js。用它来检索 [PaymentIntent 状态更新](https://docs.stripe.com/payments/payment-intents/verifying-status.md),并确定向客户显示的内容。 ### 显示支付状态消息 当 Stripe 将客户重定向到 `return_url` 时,`payment_intent` 查询参数会加上 Stripe.js。用它来检索 [PaymentIntent 状态更新](https://docs.stripe.com/payments/payment-intents/verifying-status.md),并确定向客户显示的内容。 ### 使用 Webhook Stripe 在支付过程中和支付完成后会发送多个事件。为 [Webhook 端点](https://docs.stripe.com/webhooks/quickstart.md)创建一个[事件接收端](https://docs.stripe.com/event-destinations.md),以接收这些事件并运行操作,例如,向客户发送订单确认邮件、在数据库中记录销售情况或启动配送流程。Stripe 建议处理 [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded), [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing), and [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) 事件。 侦听这些事件,而不是等待客户端回调。在客户端,客户可能会在执行回调之前关闭浏览器窗口或退出应用程序,并且恶意客户端可能会操纵响应。设置您的集成来侦听异步事件,这样才能用单一集成用用接受[不同类型的支付方式](https://stripe.com/payments/payment-methods-guide)。 ### 运行应用程序 运行 React 应用程序和服务器。请转到 [localhost:3000/checkout](http://localhost:3000/checkout),查看您的结账页面。 ```bash npm start ``` ### 运行应用程序 运行 Next.js 应用。前往 [localhost:3000](http://localhost:3000),查看您的结账页面。 ```bash npm run dev ``` ### 运行应用程序 运行您的 Node 服务器并转至 [localhost:4242/checkout.html](http://localhost:4242/checkout.html)。 ```bash npm start ``` ### 运行服务器应用程序 运行 React 应用程序和服务器。请转到 [localhost:3000/checkout](http://localhost:3000/checkout),查看您的结账页面。 ```bash ruby server.rb ``` ### 运行应用程序 运行您的 Ruby 服务器并转至 [localhost:4242/checkout.html](http://localhost:4242/checkout.html)。 ```bash ruby server.rb ``` ### 运行服务器应用程序 运行 React 应用程序和服务器。请转到 [localhost:3000/checkout](http://localhost:3000/checkout),查看您的结账页面。 ```bash python3 -m flask run --port=4242 ``` ### 运行应用程序 运行您的 Python 服务器并转至 [localhost:4242/checkout.html](http://localhost:4242/checkout.html)。 ```bash python3 -m flask run --port=4242 ``` ### 运行服务器应用程序 运行 React 应用程序和服务器。请转到 [localhost:3000/checkout](http://localhost:3000/checkout),查看您的结账页面。 ```bash php -S 127.0.0.1:4242 --docroot=public ``` ### 运行应用程序 运行您的服务器并转至 [localhost:4242/checkout.html](http://localhost:4242/checkout.html)。 ```bash php -S 127.0.0.1:4242 --docroot=public ``` ### 运行服务器应用程序 运行 React 应用程序和服务器。请转到 [localhost:3000/checkout](http://localhost:3000/checkout),查看您的结账页面。 ```bash go run server.go ``` ### 运行应用程序 运行您的 Go 服务器并转至 [localhost:4242/checkout.html](http://localhost:4242/checkout.html)。 ```bash go run server.go ``` ### 运行服务器应用程序 运行 React 应用程序和服务器。请转到 [localhost:3000/checkout](http://localhost:3000/checkout),查看您的结账页面。 ```bash dotnet run ``` ### 运行应用程序 运行您的 ASP.NET MVC 服务器并转至 [localhost:4242/checkout.html](http://localhost:4242/checkout.html)。 ```bash dotnet run ``` ### 运行应用程序 运行您的服务器并转至 [localhost:4242/checkout.html](http://localhost:4242/checkout.html)。 ```bash java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server ``` ### 运行服务器应用程序 运行 React 应用程序和服务器。请转到 [localhost:3000/checkout](http://localhost:3000/checkout),查看您的结账页面。 ```bash java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server ``` ### 运行应用程序 运行 React 应用并前往 [localhost:3000/checkout](http://localhost:3000/checkout)。 ```bash npm start ``` ### 进行测试付款 要验证集成是否有效,请使用[测试支付信息](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=elements&api-integration=paymentintents#web-test-the-integration)进行测试支付。 ### 在管理平台查看付款 导航到 [Stripe 管理平台](https://dashboard.stripe.com/test/payments)查看您的测试支付。 ## 接受付款并增强您的集成 您现在即可使用 Stripe 收款了。继续执行下面的步骤以添加更多功能。 ### 自动收税 计算并收取您的 Stripe 交易的正确税额。使用 Stripe Tax 之前,您需要在[管理平台](https://dashboard.stripe.com/tax)中将其激活。进一步了解 [Stripe Tax](https://docs.stripe.com/tax.md) 及[如何将它添加到您的支付集成](https://docs.stripe.com/tax/custom.md)。 ### 使用 Stripe Tax API 计算税款 使用 [Stripe 税务 API](https://docs.stripe.com/api/tax/calculations/create.md) 计算交易税费。在请求正文中提供订单的 `currency`、`customer_details` 和 `line_items`。 使用生成的税务计算的 `tax_amount_exclusive` 属性将不含税金额添加到订单的总额中。 ### 支付成功后记录税务交易 将税费计算关联 至 PaymentIntent,请使用 `hooks [inputs][tax][calculation]`。 这会记录您 Stripe 账户中已收取的税款,之后您可以导出这些税款用于会计目的,并触发其他 [Stripe 操作](https://docs.stripe.com/tax/payment-intent.md#automatic-actions)。 ### 发送邮件收据 Stripe 可以使用您的品牌徽标和颜色主题给您的客户发送电子邮件收据,具体可在[管理平台](https://dashboard.stripe.com/settings/branding)中配置。 ### 收集客户的邮件地址 在您的支付表单中添加一个输入字段来收集邮件地址。 ### 向状态中添加邮件地址 添加一个变量来跟踪客户输入的邮件地址。 ### 向状态中添加邮件地址 添加一个变量来跟踪客户输入的邮件地址。 ### 向 Stripe 提供邮件地址 将提供的邮件地址作为 `receipt_email` 值传入。在真实模式下支付成功时,Stripe 会发送一个邮件收据(但在*沙盒* (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)中不会发送)。 ### 支付后保存支付详情 SaaS 或有经常性客户的电商企业通常会这样做。 ### 导入额外额 Stripe 资源 导入 Stripe `customer` 和 `paymentmethod` 软件包。用这些软件包来存储有关客户的信息。 ### 导入额外额 Stripe 资源 导入 Stripe 的 PaymentMethod 和 Customer 模型。用这些模型来存储您的 Customer 的相关信息。 ### 创建客户 Stripe 将卡存储在一个 *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) 对象上。在创建 PaymentIntent 前,先创建一个新的 Customer。您还可以存储客户的姓名、电子邮件、收货地址和其他详细信息。 ### 创建客户 Stripe 将银行卡存储在代表[客户](https://docs.stripe.com/connect/account-capabilities.md?accounts-namespace=v2#customer)的[账户](https://docs.stripe.com/api/v2/core/accounts/object.md)对象中。在创建 PaymentIntent 之前,先创建账户。您还可以在账户中存储姓名、电子邮件、收货地址及其他信息。 ### 将客户添加到 PaymentIntent 将 Customer ID 传递给 PaymentIntent 并将 `setup_future_usage` 设置为 `off_session`。`setup_future_usage` 会告诉 Stripe 您打算如何使用支付方式——某些地区(例如欧洲和印度)在重复使用支付信息方面有具体要求。[了解更多](https://docs.stripe.com/payments/payment-intents.md#future-usage)有关应用 `setup_future_usage` 的最有效方法。您还可以查看[支持的支付方式列表](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability)。PaymentIntent 成功后,Stripe 会自动将付款详情(*PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) 对象中) [attaches](https://docs.stripe.com/api/payment_methods/attach.md) 到您的 Customer。 ### 将客户添加到 PaymentIntent 将账户 ID 传给 PaymentIntent,并将 `setup_future_usage` 设置为 `off_session`。`setup_future_usage`会告知 Stripe 您计划如何使用此支付方式——某些地区(如欧洲和印度)对重复使用支付详情有相关要求。[了解更多](https://docs.stripe.com/payments/payment-intents.md#future-usage)关于如何最有效地应用 `setup_future_usage` 的信息。您还可以查看[支持的支付方式列表](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability)。PaymentIntent 成功后,Stripe 会自动将支付详情(在*PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs)对象中)[附加](https://docs.stripe.com/api/payment_methods/attach.md)到客户配置的账户。 ### 对保存的 PaymentMethod 扣款 当您准备好再次对 PaymentMethod 扣款时,请使用客户 ID、您要扣款的 PaymentMethod 的 ID 创建一个新的 PaymentIntent,并将 `off_session` 和 `confirm` 标志设置为 true。 ### 安装 Stripe Node 库 安装软件包并将它导入到您的代码中。或者,如果您要从头开始且需要 package.json 文件,请用代码编辑器中的 Download 链接来下载项目文件。 #### npm 安装库: ```bash npm install --save stripe ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-node) 下载 stripe-node 库源代码。 ### 安装 Stripe Ruby 库 安装 Stripe ruby gem,并在代码中要求使用它。或者,如果您要从头开始且需要 Gemfile 的话,请用代码编辑器中的链接来下载项目文件。 #### Terminal 安装 gem: ```bash gem install stripe ``` #### Bundler 将这一行添加到您的 Gemfile: ```bash gem 'stripe' ``` #### GitHub 也可直接[从 GitHub](https://github.com/stripe/stripe-ruby) 下载 stripe-ruby gem 源代码。 ### 安装 Stripe Java 库 将依赖项添加到您的版本并导入库。或者,如果您要从头开始且需要 pom.xml 样本文件 (Maven) 的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### Maven 将以下依赖项添加到您的 POM,并将 {VERSION} 替换为您想使用的版本号。 ```bash \ncom.stripe\nstripe-java\n{VERSION}\n ``` #### Gradle 将依赖项添加到您的 build.gradle 文件,并将 {VERSION} 替换为您想使用的版本号。 ```bash implementation "com.stripe:stripe-java:{VERSION}" ``` #### GitHub 直接[从 GitHub](https://github.com/stripe/stripe-java/releases/latest) 下载 JAR。 ### 安装 Stripe Python 软件包 安装 Stripe 软件包并将它导入到您的代码。或者,如果您要从头开始且需要 requirements.txt 文件的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### pip 通过 pip 安装软件包: ```bash pip3 install stripe ``` #### GitHub 直接[从 GitHub](https://github.com/stripe/stripe-python) 下载 stripe-python 库的源代码。 ### 安装 Stripe PHP 库 用 composer 安装库,并用您的秘密 API 密钥初始化。或者,如果您要从头开始且需要 composer.json 文件的话,可以用代码编辑器中的 Download 链接来下载文件。 #### Composer 安装库: ```bash composer require stripe/stripe-php ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-php) 下载 stripe-php 库源代码。 ### 设置您的服务器 将依赖项添加到您的版本并导入库。或者,如果您要从头开始且需要 go.mod 文件的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### Go 请务必用 Go 模块进行初始化: ```bash go get -u github.com/stripe/stripe-go/v85 ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-go) 下载 stripe-go 模块源代码。 ### 安装 Stripe.net 库 使用 .NET 或 NuGet 安装软件包。或者,如果您要从头开始,请下载包含已配置的 .csproj 文件的文件。 #### dotnet 安装库: ```bash dotnet add package Stripe.net ``` #### NuGet 安装库: ```bash Install-Package Stripe.net ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-dotnet) 下载 Stripe.net 库源代码。 ### 安装 Stripe 库 安装软件包并将其导入到您的代码中。或者,如果您要从头开始且需要 `package.json` 文件,请用代码编辑器中的链接来下载项目文件。 安装库: ```bash npm install --save stripe @stripe/stripe-js next ``` ### 创建 PaymentIntent 在服务器上添加一个创建 [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) 的端点。PaymentIntent 跟踪客户的支付生命周期,记录任何失败的支付尝试,并确保客户仅被收取一次费用。在响应中返回 PaymentIntent 的*客户端密钥* (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))以在客户端完成支付。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 安装 SDK Stripe iOS SDK 是[开源](https://github.com/stripe/stripe-ios)的且[配备完整文档](https://stripe.dev/stripe-ios/),并且与支持 iOS 13 或更高版本作系统的应用兼容。将 Stripe SDK 导入到您的结账屏幕的视图控制器中。 #### Swift Package Manager 在 Xcode 中,选择**文件** > **添加工具包依赖…**并输入 `https://github.com/stripe/stripe-ios-spm` 作为仓库 URL。从我们的[发布页面](https://github.com/stripe/stripe-ios/releases)选择最新的版本号,然后将 `StripePaymentSheet` 模态添加到您的目标应用程序。 #### CocoaPods 将这一行代码添加到您的 Podfile,并用 .xcworkspace 文件在 Xcode 中打开您的项目,不要在这里用 .xcodeproj 打开。 ```bash pod 'StripePaymentSheet' ``` #### Carthage 将这一行代码添加到您的 Cartfile。 ```bash github "stripe/stripe-ios" ``` #### 手动框架 要在项目中包含 Stripe,请从 [GitHub 上的版本](https://github.com/stripe/stripe-ios/releases)下载并解压缩 Stripe.xcframework.zip。将所需的 xcframework 文件拖拽到您的 Xcode 项目中的“Embedded Binaries”设置中。确保选择“需要时复制项”。 ### 设置 SDK 使用您的 Stripe [可发布 API 密钥](https://docs.stripe.com/keys.md#obtain-api-keys)配置 Stripe SDK。在 SDK 中硬编码可发布 API 密钥仅用于演示。在生产环境中,您必须从服务器检索 API 密钥。 ### 获取 PaymentIntent 视图加载后,立即向您的服务器请求 PaymentIntent。存储服务器返回的 PaymentIntent 的*客户端私钥* (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))的引用;Payment Sheet 稍后将使用这个私钥来进行一笔付款。 ### 配置并展示 Payment Sheet 用之前检索到的客户端密钥创建一个 `PaymentSheet` 实例,并从视图控制器中展示它。 将 `PaymentSheet.Configuration` 结构用于[自定义](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) Payment Sheet。 ### 处理支付结果 用完成块处理支付结果。 如果付款失败并显示[错误](https://docs.stripe.com/error-codes.md),则向客户显示相应的消息,以便他们采取行动并重试。如果没有出现错误,则告诉客户付款成功! ### 进行测试付款 #### iOS 要验证集成是否有效,请使用[测试支付信息](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios#ios-test-the-integration)进行测试支付。 #### Android 要验证集成是否有效,请使用[测试支付信息](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=android#android-test-the-integration)进行测试支付。 ### 在管理平台查看付款 导航至 [Stripe 管理平台](https://dashboard.stripe.com/test/payments),查看您的测试付款。 ## 接受付款并增强您的集成 您现在即可使用 Stripe 收款了。继续执行下面的步骤以添加更多功能。 ### 自动收税 计算并收取您的 Stripe 交易的正确税额。使用 Stripe Tax 之前,您需要在[管理平台](https://dashboard.stripe.com/tax)中将其激活。进一步了解 [Stripe Tax](https://docs.stripe.com/tax.md) 及[如何将它添加到您的支付集成](https://docs.stripe.com/tax/custom.md)。 ### 使用 Stripe Tax API 计算税款 使用 [Stripe 税务 API](https://docs.stripe.com/api/tax/calculations/create.md) 计算交易税费。在请求正文中提供订单的 `currency`、`customer_details` 和 `line_items`。 使用生成的税务计算的 `tax_amount_exclusive` 属性将不含税金额添加到订单的总额中。 ### 支付成功后记录税务交易 将税费计算关联 至 PaymentIntent,请使用 `hooks [inputs][tax][calculation]`。 这会记录您 Stripe 账户中已收取的税款,之后您可以导出这些税款用于会计目的,并触发其他 [Stripe 操作](https://docs.stripe.com/tax/payment-intent.md#automatic-actions)。 ### 允许延迟的支付方式 有些支付方式无法保证您会在结账结束时收到客户的资金,因为结算需要时间(例如,大多数银行借记,例如 SEPA 或 ACH)或需要客户作才能完成(例如,OXXO、Konbini、Boleto)。使用该标志启用延迟型支付方式。 如果启用此功能,请确保您的服务器集成监听 [Webhook](https://docs.stripe.com/payments/payment-methods.md#payment-notification) 以获取支付是否成功的通知。 ### 添加 Apple Pay 支持 要启用 Apple Pay,请提供您的 [Apple Pay 商家 ID](https://support.stripe.com/questions/enable-apple-pay-on-your-stripe-account) 和您的 Stripe 账户的[国家/地区代码](https://dashboard.stripe.com/settings/account)。 ### 添加 Google Pay 支持 要使用 Google Pay,请先在您的 AndroidManifest.xml 中启用 Google Pay API。 初始化 [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) 时,通过传递 [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) 对象以及 Google Pay 环境(产品或测试)和[您的企业的国家/地区代码](https://dashboard.stripe.com/settings/account)来启用 Google Pay。 ### 自定义主按钮颜色 考虑为主按钮使用自定义颜色,以更好地匹配您的品牌或应用的视觉标识。 ### 启用银行卡扫描 扫描银行卡可以消除手动输入银行卡信息的麻烦,从而提高转化率。要启用银行卡扫描,请在您的应用的 `Info.plist` 中设置 `NSCameraUsageDescription`,并提供访问摄像头的原因(例如,“要扫描银行卡”)。 > 只有运行 iOS 13 或更高版本的设备支持银行卡扫描。 ### 启用银行卡扫描 扫描银行卡可以消除手动输入银行卡的麻烦,从而提高转化率。要启用银行卡扫描,将 `stripecardscan` 添加到您的 [app/build.gradle](https://developer.android.com/studio/build/dependencies) 文件的 `dependencies` 块中。 #### Groovy ```groovy implementation 'com.stripe:stripecardscan:23.3.0' ``` ### 支付后保存支付详情 SaaS 或有经常性客户的电商企业通常会这样做。 ### 导入额外额 Stripe 资源 导入 Stripe `customer` 和 `paymentmethod` 软件包。用这些软件包来存储有关客户的信息。 ### 导入额外额 Stripe 资源 导入 Stripe 的 PaymentMethod 和 Customer 模型。用这些模型来存储您的 Customer 的相关信息。 ### 创建客户 Stripe 将卡存储在一个 *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) 对象上。在创建 PaymentIntent 前,先创建一个新的 Customer。您还可以存储客户的姓名、电子邮件、收货地址和其他详细信息。 ### 创建客户 Stripe 将银行卡存储在代表[客户](https://docs.stripe.com/connect/account-capabilities.md?accounts-namespace=v2#customer)的[账户](https://docs.stripe.com/api/v2/core/accounts/object.md)对象中。在创建 PaymentIntent 之前,先创建账户。您还可以在账户中存储姓名、电子邮件、收货地址及其他信息。 ### 将客户添加到 PaymentIntent 将 Customer ID 传递给 PaymentIntent 并将 `setup_future_usage` 设置为 `off_session`。`setup_future_usage` 会告诉 Stripe 您打算如何使用支付方式——某些地区(例如欧洲和印度)在重复使用支付信息方面有具体要求。[了解更多](https://docs.stripe.com/payments/payment-intents.md#future-usage)有关应用 `setup_future_usage` 的最有效方法。您还可以查看[支持的支付方式列表](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability)。PaymentIntent 成功后,Stripe 会自动将付款详情(*PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) 对象中) [attaches](https://docs.stripe.com/api/payment_methods/attach.md) 到您的 Customer。 ### 将客户添加到 PaymentIntent 将账户 ID 传给 PaymentIntent,并将 `setup_future_usage` 设置为 `off_session`。`setup_future_usage`会告知 Stripe 您计划如何使用此支付方式——某些地区(如欧洲和印度)对重复使用支付详情有相关要求。[了解更多](https://docs.stripe.com/payments/payment-intents.md#future-usage)关于如何最有效地应用 `setup_future_usage` 的信息。您还可以查看[支持的支付方式列表](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability)。PaymentIntent 成功后,Stripe 会自动将支付详情(在*PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs)对象中)[附加](https://docs.stripe.com/api/payment_methods/attach.md)到客户配置的账户。 ### 对保存的 PaymentMethod 扣款 当您准备好再次对 PaymentMethod 扣款时,请使用客户 ID、您要扣款的 PaymentMethod 的 ID 创建一个新的 PaymentIntent,并将 `off_session` 和 `confirm` 标志设置为 true。 ### 使用 Address Element 收集地址 收集客户的本地和国际收货地址或账单地址。 ### 使用 Address Element 收集地址 收集客户的本地和国际收货地址或账单地址。 如果您使用的是 Address Element,则可以选择使用 [Google Places SDK](https://developers.google.com/maps/documentation/places/android-sdk/overview) 来获取地址自动填写建议。要启用自动完成建议,请将 `places` 添加到您的 [app/build.gradle](https://developer.android.com/studio/build/dependencies) 文件的依赖块中: #### Groovy ```groovy implementation 'com.google.android.libraries.places:places:2.6.0' ``` ### 安装 Stripe Node 库 安装软件包并将它导入到您的代码中。或者,如果您要从头开始且需要 package.json 文件,请用代码编辑器中的 Download 链接来下载项目文件。 #### npm 安装库: ```bash npm install --save stripe ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-node) 下载 stripe-node 库源代码。 ### 安装 Stripe Ruby 库 安装 Stripe ruby gem,并在代码中要求使用它。或者,如果您要从头开始且需要 Gemfile 的话,请用代码编辑器中的链接来下载项目文件。 #### Terminal 安装 gem: ```bash gem install stripe ``` #### Bundler 将这一行添加到您的 Gemfile: ```bash gem 'stripe' ``` #### GitHub 也可直接[从 GitHub](https://github.com/stripe/stripe-ruby) 下载 stripe-ruby gem 源代码。 ### 安装 Stripe Java 库 将依赖项添加到您的版本并导入库。或者,如果您要从头开始且需要 pom.xml 样本文件 (Maven) 的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### Maven 将以下依赖项添加到您的 POM,并将 {VERSION} 替换为您想使用的版本号。 ```bash \ncom.stripe\nstripe-java\n{VERSION}\n ``` #### Gradle 将依赖项添加到您的 build.gradle 文件,并将 {VERSION} 替换为您想使用的版本号。 ```bash implementation "com.stripe:stripe-java:{VERSION}" ``` #### GitHub 直接[从 GitHub](https://github.com/stripe/stripe-java/releases/latest) 下载 JAR。 ### 安装 Stripe Python 软件包 安装 Stripe 软件包并将它导入到您的代码。或者,如果您要从头开始且需要 requirements.txt 文件的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### pip 通过 pip 安装软件包: ```bash pip3 install stripe ``` #### GitHub 直接[从 GitHub](https://github.com/stripe/stripe-python) 下载 stripe-python 库的源代码。 ### 安装 Stripe PHP 库 用 composer 安装库,并用您的秘密 API 密钥初始化。或者,如果您要从头开始且需要 composer.json 文件的话,可以用代码编辑器中的 Download 链接来下载文件。 #### Composer 安装库: ```bash composer require stripe/stripe-php ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-php) 下载 stripe-php 库源代码。 ### 设置您的服务器 将依赖项添加到您的版本并导入库。或者,如果您要从头开始且需要 go.mod 文件的话,可以用代码编辑器中的 Download 链接来下载项目文件。 #### Go 请务必用 Go 模块进行初始化: ```bash go get -u github.com/stripe/stripe-go/v85 ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-go) 下载 stripe-go 模块源代码。 ### 安装 Stripe.net 库 使用 .NET 或 NuGet 安装软件包。或者,如果您要从头开始,请下载包含已配置的 .csproj 文件的文件。 #### dotnet 安装库: ```bash dotnet add package Stripe.net ``` #### NuGet 安装库: ```bash Install-Package Stripe.net ``` #### GitHub 也可以直接[从 GitHub](https://github.com/stripe/stripe-dotnet) 下载 Stripe.net 库源代码。 ### 安装 Stripe 库 安装软件包并将其导入到您的代码中。或者,如果您要从头开始且需要 `package.json` 文件,请用代码编辑器中的链接来下载项目文件。 安装库: ```bash npm install --save stripe @stripe/stripe-js next ``` ### 创建 PaymentIntent 在服务器上添加一个创建 [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) 的端点。PaymentIntent 跟踪客户的支付生命周期,记录任何失败的支付尝试,并确保客户仅被收取一次费用。在响应中返回 PaymentIntent 的*客户端密钥* (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))以在客户端完成支付。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 配置支付方式 Stripe 默认使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)启用银行卡和其他常见支付方式。您可以从[管理平台](https://dashboard.stripe.com/settings/payment_methods)更新和配置支付方式,不需要代码。Stripe 根据资格和支付方式偏好筛选支付方式,然后根据金额、货币和买家位置等因素按概率进行排序和显示。 ### 安装 SDK Stripe Android SDK 是[开源](https://github.com/stripe/stripe-android)的且[配备了完整文档](https://stripe.dev/stripe-android/),而且与运行 Android 5.0(API 21 级)及更高版本的设备兼容。 要安装 SDK,请将 `stripe-android` 添加到您的 `build.gradle` 文件的依赖项块中: #### Groovy ```groovy implementation 'com.stripe:stripe-android:23.3.0' ``` > 有关最新 SDK 版本及过往版本的详情,请查看 GitHub 上的[版本页面](https://github.com/stripe/stripe-android/releases)。 ### 设置 SDK 使用您的 Stripe [可发布 API 密钥](https://docs.stripe.com/keys.md#obtain-api-keys)配置 Stripe SDK。在 SDK 中硬编码可发布 API 密钥仅用于演示。在生产环境中,您必须从服务器检索 API 密钥。 ### 获取 PaymentIntent 视图加载后,立即向您的服务器请求 PaymentIntent。存储服务器返回的 PaymentIntent 的*客户端私钥* (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))的引用;Payment Sheet 稍后将使用这个私钥来进行一笔付款。 ### 配置并展示 Payment Sheet 用之前检索到的客户端密钥创建一个 `PaymentSheet` 实例,并从视图控制器中展示它。 将 `PaymentSheet.Configuration` 结构用于[自定义](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) Payment Sheet。 ### 处理支付结果 用完成块处理支付结果。 如果付款失败并显示[错误](https://docs.stripe.com/error-codes.md),则向客户显示相应的消息,以便他们采取行动并重试。如果没有出现错误,则告诉客户付款成功! ### 进行测试付款 #### iOS 要验证集成是否有效,请使用[测试支付信息](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios#ios-test-the-integration)进行测试支付。 #### Android 要验证集成是否有效,请使用[测试支付信息](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=android#android-test-the-integration)进行测试支付。 ### 在管理平台查看付款 导航至 [Stripe 管理平台](https://dashboard.stripe.com/test/payments),查看您的测试付款。 ## 接受付款并增强您的集成 您现在即可使用 Stripe 收款了。继续执行下面的步骤以添加更多功能。 ### 自动收税 计算并收取您的 Stripe 交易的正确税额。使用 Stripe Tax 之前,您需要在[管理平台](https://dashboard.stripe.com/tax)中将其激活。进一步了解 [Stripe Tax](https://docs.stripe.com/tax.md) 及[如何将它添加到您的支付集成](https://docs.stripe.com/tax/custom.md)。 ### 使用 Stripe Tax API 计算税款 使用 [Stripe 税务 API](https://docs.stripe.com/api/tax/calculations/create.md) 计算交易税费。在请求正文中提供订单的 `currency`、`customer_details` 和 `line_items`。 使用生成的税务计算的 `tax_amount_exclusive` 属性将不含税金额添加到订单的总额中。 ### 支付成功后记录税务交易 将税费计算关联 至 PaymentIntent,请使用 `hooks [inputs][tax][calculation]`。 这会记录您 Stripe 账户中已收取的税款,之后您可以导出这些税款用于会计目的,并触发其他 [Stripe 操作](https://docs.stripe.com/tax/payment-intent.md#automatic-actions)。 ### 允许延迟的支付方式 有些支付方式无法保证您会在结账结束时收到客户的资金,因为结算需要时间(例如,大多数银行借记,例如 SEPA 或 ACH)或需要客户作才能完成(例如,OXXO、Konbini、Boleto)。使用该标志启用延迟型支付方式。 如果启用此功能,请确保您的服务器集成监听 [Webhook](https://docs.stripe.com/payments/payment-methods.md#payment-notification) 以获取支付是否成功的通知。 ### 添加 Apple Pay 支持 要启用 Apple Pay,请提供您的 [Apple Pay 商家 ID](https://support.stripe.com/questions/enable-apple-pay-on-your-stripe-account) 和您的 Stripe 账户的[国家/地区代码](https://dashboard.stripe.com/settings/account)。 ### 添加 Google Pay 支持 要使用 Google Pay,请先在您的 AndroidManifest.xml 中启用 Google Pay API。 初始化 [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) 时,通过传递 [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) 对象以及 Google Pay 环境(产品或测试)和[您的企业的国家/地区代码](https://dashboard.stripe.com/settings/account)来启用 Google Pay。 ### 自定义主按钮颜色 考虑为主按钮使用自定义颜色,以更好地匹配您的品牌或应用的视觉标识。 ### 启用银行卡扫描 扫描银行卡可以消除手动输入银行卡信息的麻烦,从而提高转化率。要启用银行卡扫描,请在您的应用的 `Info.plist` 中设置 `NSCameraUsageDescription`,并提供访问摄像头的原因(例如,“要扫描银行卡”)。 > 只有运行 iOS 13 或更高版本的设备支持银行卡扫描。 ### 启用银行卡扫描 扫描银行卡可以消除手动输入银行卡的麻烦,从而提高转化率。要启用银行卡扫描,将 `stripecardscan` 添加到您的 [app/build.gradle](https://developer.android.com/studio/build/dependencies) 文件的 `dependencies` 块中。 #### Groovy ```groovy implementation 'com.stripe:stripecardscan:23.3.0' ``` ### 支付后保存支付详情 SaaS 或有经常性客户的电商企业通常会这样做。 ### 导入额外额 Stripe 资源 导入 Stripe `customer` 和 `paymentmethod` 软件包。用这些软件包来存储有关客户的信息。 ### 导入额外额 Stripe 资源 导入 Stripe 的 PaymentMethod 和 Customer 模型。用这些模型来存储您的 Customer 的相关信息。 ### 创建客户 Stripe 将卡存储在一个 *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) 对象上。在创建 PaymentIntent 前,先创建一个新的 Customer。您还可以存储客户的姓名、电子邮件、收货地址和其他详细信息。 ### 创建客户 Stripe 将银行卡存储在代表[客户](https://docs.stripe.com/connect/account-capabilities.md?accounts-namespace=v2#customer)的[账户](https://docs.stripe.com/api/v2/core/accounts/object.md)对象中。在创建 PaymentIntent 之前,先创建账户。您还可以在账户中存储姓名、电子邮件、收货地址及其他信息。 ### 将客户添加到 PaymentIntent 将 Customer ID 传递给 PaymentIntent 并将 `setup_future_usage` 设置为 `off_session`。`setup_future_usage` 会告诉 Stripe 您打算如何使用支付方式——某些地区(例如欧洲和印度)在重复使用支付信息方面有具体要求。[了解更多](https://docs.stripe.com/payments/payment-intents.md#future-usage)有关应用 `setup_future_usage` 的最有效方法。您还可以查看[支持的支付方式列表](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability)。PaymentIntent 成功后,Stripe 会自动将付款详情(*PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) 对象中) [attaches](https://docs.stripe.com/api/payment_methods/attach.md) 到您的 Customer。 ### 将客户添加到 PaymentIntent 将账户 ID 传给 PaymentIntent,并将 `setup_future_usage` 设置为 `off_session`。`setup_future_usage`会告知 Stripe 您计划如何使用此支付方式——某些地区(如欧洲和印度)对重复使用支付详情有相关要求。[了解更多](https://docs.stripe.com/payments/payment-intents.md#future-usage)关于如何最有效地应用 `setup_future_usage` 的信息。您还可以查看[支持的支付方式列表](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability)。PaymentIntent 成功后,Stripe 会自动将支付详情(在*PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs)对象中)[附加](https://docs.stripe.com/api/payment_methods/attach.md)到客户配置的账户。 ### 对保存的 PaymentMethod 扣款 当您准备好再次对 PaymentMethod 扣款时,请使用客户 ID、您要扣款的 PaymentMethod 的 ID 创建一个新的 PaymentIntent,并将 `off_session` 和 `confirm` 标志设置为 true。 ### 使用 Address Element 收集地址 收集客户的本地和国际收货地址或账单地址。 ### 使用 Address Element 收集地址 收集客户的本地和国际收货地址或账单地址。 如果您使用的是 Address Element,则可以选择使用 [Google Places SDK](https://developers.google.com/maps/documentation/places/android-sdk/overview) 来获取地址自动填写建议。要启用自动完成建议,请将 `places` 添加到您的 [app/build.gradle](https://developer.android.com/studio/build/dependencies) 文件的依赖块中: #### Groovy ```groovy implementation 'com.google.android.libraries.places:places:2.6.0' ``` ## 后续步骤 #### 网页 #### [收集账单地址详情](https://docs.stripe.com/elements/address-element.md) 默认情况下,Payment Element 仅收集必要的账单地址信息。要收集客户完整的账单地址(例如,计算数字商品和服务的税额)或收货地址,请使用 Address Element。 #### iOS #### Android #### [提现](https://docs.stripe.com/payouts.md) 了解如何将资金从您的 Stripe 账户转到您的银行账户。 #### [退款](https://docs.stripe.com/refunds.md) 用 Stripe API 或管理平台处理退款请求。 #### [履约](https://docs.stripe.com/webhooks/quickstart.md) 创建一个事件目标端,将事件发送到您的 Webhook 端点,以便在付款成功后履行订单并处理其他关键事件。