Skip to content

Commit

Permalink
Fix missing info on order for 2-step transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
mraerino committed Sep 8, 2019
1 parent e72cbad commit c5fa3d5
Showing 1 changed file with 46 additions and 35 deletions.
81 changes: 46 additions & 35 deletions api/payments.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,41 @@ func (a *API) PaymentListForOrder(w http.ResponseWriter, r *http.Request) error
return sendJSON(w, http.StatusOK, order.Transactions)
}

// PaymentCreate is the endpoint for creating a payment for an order
func (a *API) PaymentCreate(w http.ResponseWriter, r *http.Request) error {
func paymentComplete(r *http.Request, tx *gorm.DB, tr *models.Transaction, order *models.Order) {
ctx := r.Context()
log := getLogEntry(r)
config := gcontext.GetConfig(ctx)

tr.Status = models.PaidState
tx.Create(tr)
order.PaymentState = models.PaidState
tx.Save(order)

if config.Webhooks.Payment != "" {
hook, err := models.NewHook("payment", config.SiteURL, config.Webhooks.Payment, order.UserID, config.Webhooks.Secret, order)
if err != nil {
log.WithError(err).Error("Failed to process webhook")
}
tx.Save(hook)
}
}

func sendOrderConfirmation(ctx context.Context, log logrus.FieldLogger, tr *models.Transaction) {
mailer := gcontext.GetMailer(ctx)

err1 := mailer.OrderConfirmationMail(tr)
err2 := mailer.OrderReceivedMail(tr)

if err1 != nil || err2 != nil {
log.Errorf("Error sending order confirmation mails: %v %v", err1, err2)
}
}

// PaymentCreate is the endpoint for creating a payment for an order
func (a *API) PaymentCreate(w http.ResponseWriter, r *http.Request) error {
ctx := r.Context()
log := getLogEntry(r)

params := PaymentParams{Currency: "USD"}
err := json.NewDecoder(r.Body).Decode(&params)
if err != nil {
Expand Down Expand Up @@ -156,21 +184,28 @@ func (a *API) PaymentCreate(w http.ResponseWriter, r *http.Request) error {
return internalServerError("We failed to authorize the amount for this order: %v", err)
}

invoiceNumber, err := models.NextInvoiceNumber(tx, order.InstanceID)
if err != nil {
tx.Rollback()
return internalServerError("We failed to generate a valid invoice ID, please try again later: %v", err)
invoiceNumber := order.InvoiceNumber
if invoiceNumber == 0 {
var err error
invoiceNumber, err = models.NextInvoiceNumber(tx, order.InstanceID)
if err != nil {
tx.Rollback()
return internalServerError("We failed to generate a valid invoice ID, please try again later: %v", err)
}
order.InvoiceNumber = invoiceNumber
}

tr := models.NewTransaction(order)
processorID, err := charge(params.Amount, params.Currency, order, invoiceNumber)
tr.ProcessorID = processorID
tr.InvoiceNumber = invoiceNumber
order.PaymentProcessor = provider.Name()

if pendingErr, ok := err.(*payments.PaymentPendingError); ok {
tr.Status = models.PendingState
tr.ProviderMetadata = pendingErr.Metadata()
tx.Create(tr)
tx.Save(order)
tx.Commit()
return sendJSON(w, 200, tr)
}
Expand All @@ -184,32 +219,10 @@ func (a *API) PaymentCreate(w http.ResponseWriter, r *http.Request) error {
return internalServerError("There was an error charging your card: %v", err).WithInternalError(err)
}

// mark order and transaction as paid
tr.Status = models.PaidState
tx.Create(tr)
order.PaymentProcessor = provider.Name()
order.PaymentState = models.PaidState
order.InvoiceNumber = invoiceNumber
tx.Save(order)

if config.Webhooks.Payment != "" {
hook, err := models.NewHook("payment", config.SiteURL, config.Webhooks.Payment, order.UserID, config.Webhooks.Secret, order)
if err != nil {
log.WithError(err).Error("Failed to process webhook")
}
tx.Save(hook)
}

paymentComplete(r, tx, tr, order)
tx.Commit()

go func() {
err1 := mailer.OrderConfirmationMail(tr)
err2 := mailer.OrderReceivedMail(tr)

if err1 != nil || err2 != nil {
log.Errorf("Error sending order confirmation mails: %v %v", err1, err2)
}
}()
go sendOrderConfirmation(ctx, log, tr)

return sendJSON(w, http.StatusOK, tr)
}
Expand Down Expand Up @@ -271,15 +284,13 @@ func (a *API) PaymentConfirm(w http.ResponseWriter, r *http.Request) error {
trans.InvoiceNumber = invoiceNumber
}

trans.Status = models.PaidState
tx.Save(trans)
order.State = models.PaidState
order.InvoiceNumber = trans.InvoiceNumber
tx.Save(order)
paymentComplete(r, tx, trans, order)
if err := tx.Commit().Error; err != nil {
return internalServerError("Saving payment failed").WithInternalError(err)
}

go sendOrderConfirmation(ctx, log, trans)

return sendJSON(w, 200, trans)
}

Expand Down

0 comments on commit c5fa3d5

Please sign in to comment.