Organization + added logs
This commit is contained in:
1 parent
fe6f3b6672
commit
7b2523e2b1
8 files changed
+33
-15
No files matched your search
@@ -0,0 +1,143 @@
|
||||
package stripe
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stripe/stripe-go/v72"
|
||||
"github.com/stripe/stripe-go/v72/checkout/session"
|
||||
"github.com/stripe/stripe-go/v72/paymentintent"
|
||||
"log"
|
||||
"payment-poc/database"
|
||||
"payment-poc/state"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
ApiKey string
|
||||
BackendUrl string
|
||||
}
|
||||
|
||||
func (s *Service) UpdatePayment(entry database.PaymentEntry) (updatedEntry database.PaymentEntry, err error) {
|
||||
pi, err := paymentintent.Get(*entry.PaymentIntentId, nil)
|
||||
if err != nil {
|
||||
return entry, err
|
||||
}
|
||||
newState := determineState(pi.Status)
|
||||
|
||||
if entry.State != newState && newState != "" {
|
||||
log.Printf("[%s] updated state for %s -> %s", entry.Id.String(), entry.State, newState)
|
||||
if pi.AmountReceived > 0 {
|
||||
entry.Amount = &pi.AmountReceived
|
||||
}
|
||||
entry.State = newState
|
||||
}
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
func determineState(status stripe.PaymentIntentStatus) state.PaymentState {
|
||||
switch status {
|
||||
case stripe.PaymentIntentStatusCanceled:
|
||||
return state.StateCanceled
|
||||
case stripe.PaymentIntentStatusProcessing:
|
||||
return state.StatePending
|
||||
case stripe.PaymentIntentStatusRequiresAction:
|
||||
return state.StatePending
|
||||
case stripe.PaymentIntentStatusRequiresCapture:
|
||||
return state.StateAccepted
|
||||
case stripe.PaymentIntentStatusRequiresConfirmation:
|
||||
return state.StatePending
|
||||
case stripe.PaymentIntentStatusRequiresPaymentMethod:
|
||||
return state.StateVoided
|
||||
case stripe.PaymentIntentStatusSucceeded:
|
||||
return state.StateCompleted
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *Service) CreatePaymentUrl(entry database.PaymentEntry) (database.PaymentEntry, string, error) {
|
||||
entry, url, err := s.InitializePayment(entry)
|
||||
if err != nil {
|
||||
return entry, "", err
|
||||
}
|
||||
return entry, url, nil
|
||||
}
|
||||
|
||||
func (s *Service) InitializePayment(entry database.PaymentEntry) (database.PaymentEntry, string, error) {
|
||||
|
||||
currency := string(stripe.CurrencyEUR)
|
||||
productName := "Example product"
|
||||
productDescription := "Simple example product"
|
||||
|
||||
params := &stripe.CheckoutSessionParams{
|
||||
LineItems: []*stripe.CheckoutSessionLineItemParams{
|
||||
{
|
||||
PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{
|
||||
Currency: ¤cy,
|
||||
ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{
|
||||
Name: &productName,
|
||||
Description: &productDescription,
|
||||
},
|
||||
UnitAmount: &entry.TotalAmount,
|
||||
},
|
||||
Quantity: stripe.Int64(1),
|
||||
},
|
||||
},
|
||||
Mode: stripe.String(string(stripe.CheckoutSessionModePayment)),
|
||||
PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{
|
||||
CaptureMethod: stripe.String("manual"),
|
||||
},
|
||||
SuccessURL: stripe.String(s.BackendUrl + "/stripe/success?token=" + entry.Id.String()),
|
||||
CancelURL: stripe.String(s.BackendUrl + "/stripe/cancel?token=" + entry.Id.String()),
|
||||
}
|
||||
result, err := session.New(params)
|
||||
if err != nil {
|
||||
return database.PaymentEntry{}, "", err
|
||||
}
|
||||
entry.State = state.StateInitialized
|
||||
entry.PaymentIntentId = &result.PaymentIntent.ID
|
||||
|
||||
return entry, result.URL, nil
|
||||
}
|
||||
|
||||
func (s *Service) CompleteTransaction(entry database.PaymentEntry, amount int64) (database.PaymentEntry, error) {
|
||||
params := &stripe.PaymentIntentCaptureParams{
|
||||
AmountToCapture: stripe.Int64(amount),
|
||||
}
|
||||
pi, err := paymentintent.Capture(*entry.PaymentIntentId, params)
|
||||
if err != nil {
|
||||
return database.PaymentEntry{}, err
|
||||
}
|
||||
log.Printf("received state on completion: %v", pi.Status)
|
||||
newState := determineState(pi.Status)
|
||||
entry.State = newState
|
||||
if newState == state.StateCompleted || newState == state.StatePending {
|
||||
entry.Amount = &pi.AmountReceived
|
||||
}
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
func (s *Service) CancelTransaction(entry database.PaymentEntry) (database.PaymentEntry, error) {
|
||||
params := &stripe.PaymentIntentCancelParams{}
|
||||
pi, err := paymentintent.Cancel(*entry.PaymentIntentId, params)
|
||||
if err != nil {
|
||||
return database.PaymentEntry{}, err
|
||||
}
|
||||
log.Printf("received state on completion: %v", pi.Status)
|
||||
if pi.Status == stripe.PaymentIntentStatusCanceled {
|
||||
entry.State = state.StateCanceled
|
||||
}
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
func (s *Service) HandleResponse(c *gin.Context, provider *database.PaymentEntryProvider, paymentState state.PaymentState) (string, error) {
|
||||
id := uuid.MustParse(c.Query("token"))
|
||||
entry, err := provider.FetchById(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
entry.State = paymentState
|
||||
if _, err := provider.UpdateEntry(entry); err != nil {
|
||||
return "", err
|
||||
}
|
||||
log.Printf("[%s:%s] received authorization response", entry.Id.String(), entry.State)
|
||||
return "/entries/" + entry.Id.String(), nil
|
||||
}
|
||||
Reference in new issue
Block a user