将一个费用与Stripe的客户关联

huangapple go评论109阅读模式
英文:

Associate a charge with a customer with Stripe

问题

我正在创建一个简单的网页,其中Stripe Checkout将提示用户输入他们的信用卡信息,生成一个令牌,并将其发送到我的后端Go Web服务器,以处理该令牌的付款。我遇到的问题是,当我获得令牌后,我尝试创建一个客户并将源设置为Stripe生成的令牌,但每次都会收到以下响应:

charge failed: {"type":"invalid_request_error","message":"Customer cus_######### does not have a linked source with ID tok_#########.","code":"missing","param":"source","request_id":"req_######","status":404}

创建客户并将卡与该客户关联起来是完全正常的。但是,基于Stripe生成的令牌对卡进行收费失败。尽管在我的Stripe仪表板中该客户的日志中显示了尝试的收费。所以,它试图将收费与正确的客户关联起来,但是失败了,因为令牌是在没有特定客户的情况下生成的?我真的不知道发生了什么。

我在后端接受令牌并处理所有内容的代码如下:

stripe.Key = "sk_test_################"

customerParams := &stripe.CustomerParams{
    Desc:  "Customer for xyz.com",
    Email: "test@email.com",
}

err := customerParams.SetSource("tok_####################")
if err != nil {
    return nil, err
}

cus, err := customer.New(customerParams)
if err != nil {
    return nil, err
}

// Charge the user's card
cp := &stripe.ChargeParams{
    Amount:   100,
    Currency: "usd",
    Desc:     "some description",
    Customer: cus.ID,
}

err = cp.SetSource("tok_####################")
if err != nil {
    return nil, err
}

err = charge.New(cp)

此外,如果我从此示例中删除客户部分,使用上述代码进行收费就可以正常进行。显然,它只是没有将收费与客户关联起来。但是,一旦我尝试在收费中设置客户,它就会失败。

英文:

I am creating a simple web page where the Stripe Checkout will prompt the user for their card info, generate a token, and send it to my backend Go webserver that processes the payment for that token. The issue I'm having is that when I get the token, I try and create a customer and set the source to the token created by Stripe, but I get this response everytime:

charge failed: {"type":"invalid_request_error","message":"Customer cus_######### does not have a linked source with ID tok_#########.","code":"missing","param":"source","request_id":"req_######","status":404}

Creating the customer and associating the card with that customer works just fine. But, charging the card based on the token Stripe generated fails. Even though in the logs for that customer in my Stripe Dashboard it shows the attempted charge. So, it's trying to associate the charge with the correct customer, but failing because the token was generated without a specific customer in mind? I'm not really sure what is going on.

The code I have on the backend that accepts the token and processes everything is below:

stripe.Key = "sk_test_################"

customerParams := &stripe.CustomerParams{
	Desc:          "Customer for xyz.com",
	Email:         "test@email.com",
}

err := customerParams.SetSource("tok_####################")
if err != nil {
	return nil, err
}

cus, err := customer.New(customerParams)
if err != nil {
	return nil, err
}

// Charge the user's card
cp := &stripe.ChargeParams{
	Amount:   100,
	Currency: "usd",
	Desc:     "some description",
	Customer: cus.ID,
}

err = cp.SetSource("tok_####################")
if err != nil {
	return nil, err
}

err = charge.New(cp)

Also, if I remove the customer portion of this example, the charge goes through just fine with the above code. It just doesn't associate the charge with a customer obviously. However, as soon as I try to set the customer on the charge it fails.

答案1

得分: 2

问题的原因是在设置新客户的来源之后,我又在收费参数上设置了令牌来源。以下代码可以按预期创建新客户并将新收费与客户关联:

stripe.Key = "sk_test_################"

customerParams := &stripe.CustomerParams{
    Desc:  "Customer for xyz.com",
    Email: "test@email.com",
}

err := customerParams.SetSource("tok_####################")
if err != nil {
    return nil, err
}

cus, err := customer.New(customerParams)
if err != nil {
    return nil, err
}

// Charge the user's card
cp := &stripe.ChargeParams{
    Amount:   100,
    Currency: "usd",
    Desc:     "some description",
    Customer: cus.ID,
}

err = charge.New(cp)
英文:

Turns out the issue was setting the token source on the charge params after I had already set the source of the new customer I was charging. The following worked as expected to create a new customer and associate the new charge with the customer:

stripe.Key = "sk_test_################"

customerParams := &stripe.CustomerParams{
    Desc:          "Customer for xyz.com",
    Email:         "test@email.com",
}

err := customerParams.SetSource("tok_####################")
if err != nil {
    return nil, err
}

cus, err := customer.New(customerParams)
if err != nil {
    return nil, err
}

// Charge the user's card
cp := &stripe.ChargeParams{
    Amount:   100,
    Currency: "usd",
    Desc:     "some description",
    Customer: cus.ID,
}

err = charge.New(cp)

答案2

得分: 0

这是预料之中的情况:你刚刚创建的客户没有关联的付款来源,所以他们无法支付你的1.00美元费用。你可以通过在创建客户时使用测试令牌之一来使上述操作成功:

customerParams := &stripe.CustomerParams{
    Desc:          "Customer for xyz.com",
    Email:         "test@email.com",
    Source:        "test_visa"
}

关于测试卡和付款来源的更多信息,请参阅:https://stripe.com/docs/testing#cards

当然,在生产应用程序中,你肯定会使用 Elements 或 Checkout 来对卡号进行令牌化,以确保原始信用卡号仅通过 Stripe 而不是你的应用程序服务器传递:
https://stripe.com/docs/elements

英文:

That's expected: the customer you just created doesn't have a payment source attached, so they can't pay your $1.00 charge. You can make the above succeed by, for example, using one of the test tokens when you create the customer:

customerParams := &stripe.CustomerParams{
    Desc:          "Customer for xyz.com",
    Email:         "test@email.com",
    Source:        "test_visa"
}

More on test cards and sources here: https://stripe.com/docs/testing#cards

You will of course want to use Elements or Checkout to tokenize card numbers in your production application, which makes sure that raw credit card numbers pass only to Stripe and not your application servers:
https://stripe.com/docs/elements

答案3

得分: 0

我在stripe订阅中遇到了同样的问题。

总的来说,如果一个客户已经存在但没有有效的付款来源:

  1. 你需要在事后为客户添加/关联一个来源 将来源附加到现有客户对象 或者,

  2. 使用来自结账的新令牌更新现有客户,即 更新客户

    func updateCustomer(custID, email, source string) (cus *stripe.Customer, err error){ params := &stripe.CustomerParams{ Email:email, } params.SetSource(source) cus, err = customer.Update(custID, params) return }

英文:

I had the same problem with stripe subscriptions.

Bottom line, if a customer already exists without a valid payment source;

  1. You either need add/associate a source to a customer after the fact Attaching a Source to an existing Customer object or,

  2. Update existing customer with a new token as the source from checkout i.e
    update customer

    func updateCustomer(custID, email, source string) (cus *stripe.Customer, err error){
    params := &stripe.CustomerParams{
    Email:email,
    }
    params.SetSource(source)
    cus, err = customer.Update(custID, params)
    return
    }

huangapple
  • 本文由 发表于 2017年4月21日 22:53:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/43545819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定