|
|
|
|
@@ -392,17 +392,15 @@ func (h *CartHandler) ConvertCart(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
// Charge the card. The idempotency key is tied to the order ID so retries
|
|
|
|
|
// never produce a double charge.
|
|
|
|
|
piParams := &stripe.PaymentIntentParams{
|
|
|
|
|
Amount: stripe.Int64(int64(total)),
|
|
|
|
|
Currency: stripe.String(string(stripe.CurrencyUSD)),
|
|
|
|
|
Customer: stripe.String(user.StripeCustomerID),
|
|
|
|
|
PaymentMethod: stripe.String(paymentMethodID),
|
|
|
|
|
OffSession: stripe.Bool(true),
|
|
|
|
|
AutomaticPaymentMethods: &stripe.PaymentIntentAutomaticPaymentMethodsParams{
|
|
|
|
|
Enabled: stripe.Bool(true),
|
|
|
|
|
AllowRedirects: stripe.String("never"),
|
|
|
|
|
},
|
|
|
|
|
Confirm: stripe.Bool(true),
|
|
|
|
|
Description: stripe.String(fmt.Sprintf("terminal.shop order #%d", order.ID)),
|
|
|
|
|
Amount: stripe.Int64(int64(total)),
|
|
|
|
|
Currency: stripe.String(string(stripe.CurrencyUSD)),
|
|
|
|
|
Customer: stripe.String(user.StripeCustomerID),
|
|
|
|
|
PaymentMethod: stripe.String(paymentMethodID),
|
|
|
|
|
OffSession: stripe.Bool(true),
|
|
|
|
|
PaymentMethodTypes: stripe.StringSlice([]string{"card"}),
|
|
|
|
|
ReturnURL: stripe.String(h.appURL + "/post-3ds"),
|
|
|
|
|
Confirm: stripe.Bool(true),
|
|
|
|
|
Description: stripe.String(fmt.Sprintf("terminal.shop order #%d", order.ID)),
|
|
|
|
|
Shipping: &stripe.ShippingDetailsParams{
|
|
|
|
|
Name: stripe.String(address.Name),
|
|
|
|
|
Address: &stripe.AddressParams{
|
|
|
|
|
@@ -508,6 +506,16 @@ func (h *CartHandler) ConvertCart(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
func (h *CartHandler) respondRequiresAction(w http.ResponseWriter, order *models.Order, pi *stripe.PaymentIntent) {
|
|
|
|
|
db := database.GetDB()
|
|
|
|
|
|
|
|
|
|
// PaymentIntents returned inside a *stripe.Error are partial — next_action
|
|
|
|
|
// is often nil. Re-fetch from Stripe to get the canonical PI with the 3DS
|
|
|
|
|
// challenge URL populated.
|
|
|
|
|
if pi.NextAction == nil || pi.NextAction.RedirectToURL == nil || pi.NextAction.RedirectToURL.URL == "" {
|
|
|
|
|
fresh, ferr := paymentintent.Get(pi.ID, nil)
|
|
|
|
|
if ferr == nil && fresh != nil {
|
|
|
|
|
pi = fresh
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if pi.NextAction == nil || pi.NextAction.RedirectToURL == nil || pi.NextAction.RedirectToURL.URL == "" {
|
|
|
|
|
middleware.RecordCartConversion("sca_missing_next_action")
|
|
|
|
|
db.Model(order).Update("status", models.OrderStatusFailed)
|
|
|
|
|
|