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 != "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)
}
What do I need to do to get my subscriptions to complete payment?
CodePudding user response:
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?