Skip to content

Commit

Permalink
Implement paypal and stripe payment flows (#3)
Browse files Browse the repository at this point in the history
* Implement paypal and stripe payment flows

* Comment token

* Add unique constraint on order provider_id

* Improve error

* Leave a todo

* Leave a warn

* Improve
  • Loading branch information
polldo authored Dec 14, 2022
1 parent db145a8 commit 4ff0bb6
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 45 deletions.
12 changes: 12 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import (
"github.com/alexedwards/scs/v2"
"github.com/gorilla/mux"
"github.com/jmoiron/sqlx"
"github.com/plutov/paypal/v4"
"github.com/polldo/govod/api/background"
"github.com/polldo/govod/api/middleware"
"github.com/polldo/govod/api/web"
"github.com/polldo/govod/config"
"github.com/polldo/govod/core/auth"
"github.com/polldo/govod/core/cart"
"github.com/polldo/govod/core/course"
"github.com/polldo/govod/core/order"
"github.com/polldo/govod/core/token"
"github.com/polldo/govod/core/user"
"github.com/polldo/govod/core/video"
"github.com/sirupsen/logrus"
stripecl "github.com/stripe/stripe-go/v74/client"
)

// APIConfig contains all the mandatory dependencies required by handlers.
Expand All @@ -27,6 +31,9 @@ type APIConfig struct {
Session *scs.SessionManager
Mailer token.Mailer
Background *background.Background
Paypal *paypal.Client
Stripe *stripecl.API
StripeCfg config.Stripe
}

// api represents our server api.
Expand Down Expand Up @@ -81,6 +88,11 @@ func APIMux(cfg APIConfig) http.Handler {
a.Handle(http.MethodPut, "/cart/items", cart.HandleCreateItem(cfg.DB), authen)
a.Handle(http.MethodDelete, "/cart/items/{course_id}", cart.HandleDeleteItem(cfg.DB), authen)

a.Handle(http.MethodPost, "/orders/paypal", order.HandlePaypalCheckout(cfg.DB, cfg.Paypal), authen)
a.Handle(http.MethodPost, "/orders/paypal/{id}/capture", order.HandlePaypalCapture(cfg.DB, cfg.Paypal), authen)
a.Handle(http.MethodPost, "/orders/stripe", order.HandleStripeCheckout(cfg.DB, cfg.Stripe, cfg.StripeCfg), authen)
a.Handle(http.MethodPost, "/orders/stripe/capture", order.HandleStripeCapture(cfg.DB, cfg.StripeCfg))

return a.Router
}

Expand Down
24 changes: 24 additions & 0 deletions cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import (

"github.com/alexedwards/scs/v2"
"github.com/ardanlabs/conf/v3"
"github.com/plutov/paypal/v4"
"github.com/polldo/govod/api"
"github.com/polldo/govod/api/background"
"github.com/polldo/govod/config"
"github.com/polldo/govod/database"
"github.com/polldo/govod/email"
"github.com/sirupsen/logrus"
stripecl "github.com/stripe/stripe-go/v74/client"
)

func main() {
Expand Down Expand Up @@ -63,13 +65,35 @@ func Run(logger *logrus.Logger) error {
// Init a background manager to safely spawn go-routines.
bg := background.New(logger)

// Build the paypal client to allow payments.
pp, err := paypal.NewClient(
cfg.Paypal.ClientID,
cfg.Paypal.Secret,
cfg.Paypal.URL,
)
if err != nil {
return fmt.Errorf("failed to build the paypal client: %w", err)
}

// The paypal token must be retrieved manually only the first time.
if _, err = pp.GetAccessToken(context.TODO()); err != nil {
return fmt.Errorf("failed to get the first paypal access token: %w", err)
}

// Build the stripe client to allow payments.
strp := &stripecl.API{}
strp.Init(cfg.Stripe.APISecret, nil)

// Construct the mux for the API calls.
mux := api.APIMux(api.APIConfig{
Log: logger,
DB: db,
Session: sessionManager,
Mailer: mail,
Background: bg,
Paypal: pp,
Stripe: strp,
StripeCfg: cfg.Stripe,
})

// Construct a server to service the requests against the mux.
Expand Down
21 changes: 18 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
)

type Config struct {
Web Web
DB DB
Email Email
Web Web
DB DB
Email Email
Paypal Paypal
Stripe Stripe
}

type Web struct {
Expand All @@ -34,3 +36,16 @@ type Email struct {
Address string
Password string
}

type Stripe struct {
APISecret string
WebhookSecret string
SuccessURL string
CancelURL string
}

type Paypal struct {
ClientID string
Secret string
URL string `conf:"default:https://api.sandbox.paypal.com"`
}
Loading

0 comments on commit 4ff0bb6

Please sign in to comment.