尽管已附加付款详细信息,但Stripe支付未完成。

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

Stripe payment incomplete despite payment details being attached?

问题

使用测试数据,我可以创建一个客户并附加一个支付方式,但是我的所有订阅都处于这种状态。以下是我目前用于创建订阅的代码:

// StripeCreateSubscription create a new subscription with fixed price for user
func StripeCreateSubscription(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		SendResponse(w, utils.MakeError("you can only POST to the stripe create customer route"), http.StatusMethodNotAllowed)
		return
	}

	// Decode the JSON payload
	type requestPayload struct {
		PaymentMethodID string `json:"paymentMethodId"`
		PriceID         string `json:"priceId"`
	}

	var payload requestPayload
	if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
		sendSystemError(w, fmt.Errorf("decode request payload: %v", err))
		return
	}

	// Get the user from the context of who made the request
	uid := r.Context().Value("user_id").(int)

	u := models.User{}
	if err := u.FindByID(uid); err != nil {
		sendSystemError(w, fmt.Errorf("find user by id: %v", err))
		return
	}
	if u.StripeCustomerID == "" {
		sendSystemError(w, errors.New("no customer for the user"))
		return
	}

	// Attach the payment method to the customer
	paymentParams := &stripe.PaymentMethodAttachParams{
		Customer: stripe.String(u.StripeCustomerID),
	}

	pm, err := paymentmethod.Attach(
		payload.PaymentMethodID,
		paymentParams,
	)

	if err != nil {
		sendSystemError(w, fmt.Errorf("attaching payment method failed: %v", err))
	}

	// Check if the user has any active subscriptions, and cancel the others if they're adding one.
	listParams := &stripe.SubscriptionListParams{
		Customer: u.StripeCustomerID,
		Status:   "all",
	}
	listParams.AddExpand("data.default_payment_method")

	iter := sub.List(listParams)
	subscriptions := iter.SubscriptionList().Data
	if len(subscriptions) > 0 {
		Log.Info(fmt.Sprintf("%v subscriptions found for %v. Cancelling...", len(subscriptions), u.Username))
		for i := 0; i < len(subscriptions); i++ {
			if subscriptions[i].Status != "canceled" && subscriptions[i].Status != "incomplete_expired" {
				Log.Info(fmt.Sprintf("Cancelling %v. Status %v", subscriptions[i].ID, subscriptions[i].Status))
				subscription, err := sub.Cancel(subscriptions[i].ID, nil)
				if err != nil {
					sendSystemError(w, fmt.Errorf("cancel subscription: %v", err))
					return
				}
				Log.Info(fmt.Sprintf("Cancelled %v", subscription.ID))
			}
		}
		Log.Info("Old subscriptions cancelled.")
		time.Sleep(5 * time.Second)
	}

	// Create subscription
	subscriptionParams := &stripe.SubscriptionParams{
		Customer: stripe.String(u.StripeCustomerID),
		Items: []*stripe.SubscriptionItemsParams{
			{
				Price: stripe.String(payload.PriceID),
			},
		},
		PaymentBehavior:      stripe.String("default_incomplete"),
		DefaultPaymentMethod: stripe.String(payload.PaymentMethodID),
	}
	subscriptionParams.AddExpand("latest_invoice.payment_intent")
	newSub, err := sub.New(subscriptionParams)
	if err != nil {
		sendSystemError(w, fmt.Errorf("new subscription: %v", err))
		return
	}

	// If everything looks good, then send some info back to the user
	output := map[string]interface{}{
		"subscriptionId": newSub.ID,
		"clientSecret":   newSub.LatestInvoice.PaymentIntent.ClientSecret,
	}
	SendResponse(w, output, 200)
}

我需要做什么才能使我的订阅完成付款?

英文:

尽管已附加付款详细信息,但Stripe支付未完成。

Using test data I can create a customer and attach a payment method, but all of my subscriptions are left in this state. Here's my code for creating a subscription currently:

// StripeCreateSubscription create a new subscription with fixed price for user
func StripeCreateSubscription(w http.ResponseWriter, r *http.Request) {
if r.Method != &quot;POST&quot; {
SendResponse(w, utils.MakeError(&quot;you can only POST to the stripe create customer route&quot;), http.StatusMethodNotAllowed)
return
}
// Decode the JSON payload
type requestPayload struct {
PaymentMethodID string `json:&quot;paymentMethodId&quot;`
PriceID         string `json:&quot;priceId&quot;`
}
var payload requestPayload
if err := json.NewDecoder(r.Body).Decode(&amp;payload); err != nil {
sendSystemError(w, fmt.Errorf(&quot;decode request payload: %v&quot;, err))
return
}
// Get the user from the context of who made the request
uid := r.Context().Value(&quot;user_id&quot;).(int)
u := models.User{}
if err := u.FindByID(uid); err != nil {
sendSystemError(w, fmt.Errorf(&quot;find user by id: %v&quot;, err))
return
}
if u.StripeCustomerID == &quot;&quot; {
sendSystemError(w, errors.New(&quot;no customer for the user&quot;))
return
}
// Attach the payment method to the customer
paymentParams := &amp;stripe.PaymentMethodAttachParams{
Customer: stripe.String(u.StripeCustomerID),
}
pm, err := paymentmethod.Attach(
payload.PaymentMethodID,
paymentParams,
)
if err != nil {
sendSystemError(w, fmt.Errorf(&quot;attaching payment method failed: %v&quot;, err))
}
// Check if the user has any active subscriptions, and cancel the others if they&#39;re adding one.
listParams := &amp;stripe.SubscriptionListParams{
Customer: u.StripeCustomerID,
Status:   &quot;all&quot;,
}
listParams.AddExpand(&quot;data.default_payment_method&quot;)
iter := sub.List(listParams)
subscriptions := iter.SubscriptionList().Data
if len(subscriptions) &gt; 0 {
Log.Info(fmt.Sprintf(&quot;%v subscriptions found for %v. Cancelling...&quot;, len(subscriptions), u.Username))
for i := 0; i &lt; len(subscriptions); i++ {
if subscriptions[i].Status != &quot;canceled&quot; &amp;&amp; subscriptions[i].Status != &quot;incomplete_expired&quot; {
Log.Info(fmt.Sprintf(&quot;Cancelling %v. Status %v&quot;, subscriptions[i].ID, subscriptions[i].Status))
subscription, err := sub.Cancel(subscriptions[i].ID, nil)
if err != nil {
sendSystemError(w, fmt.Errorf(&quot;cancel subscription: %v&quot;, err))
return
}
Log.Info(fmt.Sprintf(&quot;Cancelled %v&quot;, subscription.ID))
}
}
Log.Info(&quot;Old subscriptions cancelled.&quot;)
time.Sleep(5 * time.Second)
}
// Create subscription
subscriptionParams := &amp;stripe.SubscriptionParams{
Customer: stripe.String(u.StripeCustomerID),
Items: []*stripe.SubscriptionItemsParams{
{
Price: stripe.String(payload.PriceID),
},
},
PaymentBehavior:      stripe.String(&quot;default_incomplete&quot;),
DefaultPaymentMethod: stripe.String(payload.PaymentMethodID),
}
subscriptionParams.AddExpand(&quot;latest_invoice.payment_intent&quot;)
newSub, err := sub.New(subscriptionParams)
if err != nil {
sendSystemError(w, fmt.Errorf(&quot;new subscription: %v&quot;, err))
return
}
// If everything looks good, then send some info back to the user
output := map[string]interface{}{
&quot;subscriptionId&quot;: newSub.ID,
&quot;clientSecret&quot;:   newSub.LatestInvoice.PaymentIntent.ClientSecret,
}
SendResponse(w, output, 200)
}

What do I need to do to get my subscriptions to complete payment?

答案1

得分: 0

使用default_incomplete,就像固定价格订阅指南所示,当您创建订阅时,明确地保持初始发票未尝试。要完成设置,您需要使用来自应用程序客户端端的客户端密钥,通过Payment Element(或Card Element确认付款。您似乎已经在发送client_secret,您在使用它吗?

英文:

Using default_incomplete like the fixed-price subscription guide shows explicitly keeps the initial invoice unattempted when you create the subscription. To complete the setup, you need to confirm the payment with the Payment Element (or with the Card Element) using that client secret from the client-side of your application. You already appear to be sending the client_secret back, are you using it?

huangapple
  • 本文由 发表于 2021年11月21日 07:38:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/70050743.html
匿名

发表评论

匿名网友

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

确定