You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django集成Stripe实现ACH支付基础问题咨询

你说的流程完全没错!这正是Stripe ACH支付的标准落地路径,我来帮你把这个流程拆解成Django里可操作的步骤,顺便补充一些容易踩坑的细节:

一、先确认你的核心流程是正确的

你梳理的步骤完全符合Stripe的安全规范,不过有个小更新:现在Stripe更推荐使用Payment Method API(替代旧的bank account token)来处理银行账户信息,本质逻辑一致,但兼容性和扩展性更好:

  • 前端用Stripe Elements(封装后的安全组件,比纯stripe.js更易用)收集银行账户敏感信息,数据不会传到你的服务器
  • 提交后从Stripe获取payment_method_id(替代旧的令牌)
  • 后端用这个ID关联到Stripe Customer对象,后续就能发起ACH转账
二、Django集成Stripe ACH的具体步骤

1. 环境准备

  • 安装Stripe官方Python SDK:
    pip install stripe
    
  • 在Django的settings.py中配置Stripe密钥(测试/生产环境密钥分开):
    STRIPE_SECRET_KEY = "你的测试/生产Secret Key"
    STRIPE_PUBLISHABLE_KEY = "你的测试/生产Publishable Key"
    

2. 前端页面:收集银行账户信息

用Stripe Elements创建安全的表单,避免直接处理敏感数据:

<!-- Django模板中的HTML代码 -->
{% load static %}

<script src="https://js.stripe.com/v3/"></script>
<div id="bank-account-element" class="form-control"></div>
<button id="submit-bank-btn" class="btn btn-primary mt-3">关联银行账户</button>

<script>
  // 从Django上下文传入公钥
  const stripe = Stripe('{{ STRIPE_PUBLISHABLE_KEY }}');
  const elements = stripe.elements();

  // 创建银行账户输入组件
  const bankAccountElement = elements.create('bankAccount', {
    country: 'US',
    currency: 'usd',
    placeholder: {
      routingNumber: '000123456',
      accountNumber: '1234567890'
    }
  });
  bankAccountElement.mount('#bank-account-element');

  // 提交处理逻辑
  const submitBtn = document.getElementById('submit-bank-btn');
  submitBtn.addEventListener('click', async () => {
    submitBtn.disabled = true;

    // 创建Payment Method
    const { error, paymentMethod } = await stripe.createPaymentMethod({
      type: 'us_bank_account',
      card: bankAccountElement,
      billing_details: {
        name: '{{ user.get_full_name }}',
        email: '{{ user.email }}'
      }
    });

    if (!error) {
      // 把Payment Method ID传到后端
      const response = await fetch('{% url "associate_bank" %}', {
        method: 'POST',
        headers: {
          'X-CSRFToken': '{{ csrf_token }}',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ payment_method_id: paymentMethod.id })
      });

      const result = await response.json();
      if (result.success) {
        alert('银行账户关联成功!请留意账户内的小额验证转账');
      } else {
        alert(`关联失败:${result.error}`);
      }
    } else {
      alert(`输入错误:${error.message}`);
    }
    submitBtn.disabled = false;
  });
</script>

3. 后端视图:关联账户到Stripe Customer

首先需要给用户模型添加Stripe Customer ID字段(扩展默认User模型):

# models.py
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    stripe_customer_id = models.CharField(max_length=255, blank=True, null=True)

执行迁移后,编写视图处理前端请求:

# views.py
import stripe
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required

stripe.api_key = settings.STRIPE_SECRET_KEY

@login_required
@require_POST
def associate_bank(request):
    data = request.json
    payment_method_id = data.get('payment_method_id')
    if not payment_method_id:
        return JsonResponse({'success': False, 'error': '缺少支付方法ID'})

    try:
        user = request.user
        # 为用户创建或获取已有的Stripe Customer
        if not user.stripe_customer_id:
            customer = stripe.Customer.create(
                email=user.email,
                name=user.get_full_name()
            )
            user.stripe_customer_id = customer.id
            user.save()

        # 将Payment Method关联到Customer
        stripe.PaymentMethod.attach(
            payment_method_id,
            customer=user.stripe_customer_id
        )

        # 可选:设置为默认支付方法
        stripe.Customer.modify(
            user.stripe_customer_id,
            invoice_settings={'default_payment_method': payment_method_id}
        )

        return JsonResponse({'success': True})
    except stripe.error.StripeError as e:
        return JsonResponse({'success': False, 'error': str(e)})

记得在urls.py中添加对应的路由:

path('associate-bank/', views.associate_bank, name='associate_bank')

4. 发起ACH转账(后续业务逻辑)

关联成功后,就可以创建PaymentIntent发起ACH支付:

@login_required
@require_POST
def create_ach_payment(request):
    user = request.user
    if not user.stripe_customer_id:
        return JsonResponse({'success': False, 'error': '用户未关联Stripe账户'})

    try:
        # 金额单位为分,示例为10美元
        payment_intent = stripe.PaymentIntent.create(
            amount=1000,
            currency='usd',
            customer=user.stripe_customer_id,
            payment_method_types=['us_bank_account'],
            confirm=True,
            description='测试ACH支付'
        )
        return JsonResponse({'success': True, 'payment_id': payment_intent.id})
    except stripe.error.StripeError as e:
        return JsonResponse({'success': False, 'error': str(e)})
三、关键注意事项
  • 必须用HTTPS:生产环境必须部署HTTPS,否则Stripe Elements无法加载
  • 银行账户验证:Stripe会自动发起微验证(两笔<1美元的转账,用户需输入确认金额),或者支持部分银行的即时验证
  • Webhook监听:ACH支付是延迟结算的,必须配置Stripe Webhook监听payment_intent.succeeded、payment_intent.failed等事件,异步更新业务状态

内容的提问来源于stack exchange,提问作者Micah Pearce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:28:28