首页 > 解决方案 > Stripe create customer for one time charge

问题描述

I am working with stripe to build a donation form in python Django. Some donations are one-time and others are recurring. What I want to do is create a customer object with both types of charges, so we can gather mailing address, email address, etc for each donation.

The problem I am having, is I can process a one-time payment using the stripe token. But I can't figure out how to do it with a customer. This is what I have tried to so far. The error I receive is No such token: cus_asdfasdfasdf. Any idea what I'm doing wrong?

Javascript on donate.html page:

var stripe = Stripe('public_key');
var elements = stripe.elements();
var card = elements.create('card');
card.mount('#card-element');

// Create a token or display an error when the form is submitted.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
  event.preventDefault();

  stripe.createPaymentMethod({
      type: 'card',
      card: card,
      billing_details: {
        email: 'my_email@gmail.com',
      },
    }).then(function(result) {
        stripePaymentMethodHandler(result.PaymentMethod)
    });

  stripe.createToken(card).then(function(result) {
    if (result.error) {
      // Inform the customer that there was an error.
      var errorElement = document.getElementById('card-errors');
      errorElement.textContent = result.error.message;
    } else {
      // Send the token to your server.
      stripeTokenHandler(result.token);
    }
  });
});

function stripePaymentMethodHandler(token) {
  // Insert the token ID into the form so it gets submitted to the server
  var form = document.getElementById('payment-form');
  var paymentMethodInput = document.createElement('input');
  paymentMethodInput.setAttribute('type', 'hidden');
  paymentMethodInput.setAttribute('name', 'paymentMethodToken');
  paymentMethodInput.setAttribute('value', token);
  form.appendChild(paymentMethodInput);
}

function stripeTokenHandler(token) {
  // Insert the token ID into the form so it gets submitted to the server
  var form = document.getElementById('payment-form');
  var hiddenInput = document.createElement('input');
  hiddenInput.setAttribute('type', 'hidden');
  hiddenInput.setAttribute('name', 'stripeToken');
  hiddenInput.setAttribute('value', token.id);
  form.appendChild(hiddenInput);

  // Submit the form
  form.submit();
}

View in django:

from django.shortcuts import render
import stripe
from transcal.settings import STRIPE_SECRET_KEY
from .forms import DonateForm

stripe.api_key = STRIPE_SECRET_KEY


def donate(request):
    if request.method == 'POST':
        stripe.api_key = STRIPE_SECRET_KEY

        # Get the payment token ID submitted by the form:
        token = request.POST.get('stripeToken')
        amount = request.POST.get('amount')
        payment_method = request.POST.get('paymentMethodToken')
        single_or_recurring = request.POST.get('single_or_recurring')

        customer = stripe.Customer.create(
            description="Customer for jenny.rosen@example.com",
            name='Joe',
            email='joe@gmail.com',
            payment_method=payment_method
        )

        if single_or_recurring == 'recurring':
            # charge subscription
            stripe.Subscription.create(
                customer=customer,
                items=[
                    {
                        "plan": "my_plan_id",
                    },
                ],
                expand=["latest_invoice.payment_intent"]
            )
        else:
            # charge one time
            stripe.Charge.create(
                amount=amount,
                currency='usd',
                description='Example charge',
                source=customer
            )

    return render(request, 'donate.html')

标签: pythondjangostripe-payments

解决方案


It looks like you are using Payment Methods here, and with these you will need to explicitly specify the Payment Method in addition to the Customer when creating a one-off transaction or a subscription.

You can get Payment Methods attached to a Customer with stripe.PaymentMethod.list

Specifically, for one-off charges made with Payment Methods, you must use the Payment Intent API to create a Charge instead of the Charge API. You can associate a Payment Intent with a Customer.

For your subscription call: when creating a Subscription with stripe.Subscription.create you will want to specify the customer AND default_payment_method (pm_xxxyyyzz) attached to the customer that you wish the subscription to charge.


推荐阅读