Skip to content

Commit

Permalink
[fix,support] #144
Browse files Browse the repository at this point in the history
  • Loading branch information
yoneyan committed Aug 7, 2022
1 parent 89de601 commit d99e415
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 153 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/spf13/cobra v1.5.0
github.com/spf13/viper v1.12.0
github.com/stripe/stripe-go/v72 v72.122.0
github.com/stripe/stripe-go/v73 v73.0.1
gorm.io/driver/mysql v1.3.5
gorm.io/gorm v1.23.8
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stripe/stripe-go/v72 v72.122.0 h1:eRXWqnEwGny6dneQ5BsxGzUCED5n180u8n665JHlut8=
github.com/stripe/stripe-go/v72 v72.122.0/go.mod h1:QwqJQtduHubZht9mek5sds9CtQcKFdsykV9ZepRWwo0=
github.com/stripe/stripe-go/v73 v73.0.1 h1:k34+CDTY4nI+PCHbmwF6s4N3o0sE3d5IiuC4dO8UI1g=
github.com/stripe/stripe-go/v73 v73.0.1/go.mod h1:4FBC7C8KkIXDS94N/YTWd0bZlOa2mbGJkx8lAu9ixCQ=
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
Expand Down
5 changes: 2 additions & 3 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,8 @@ func UserRestAPI() {
//
// Payment
//
v1.POST("/payment/membership", payment.MembershipPayment)
v1.PUT("/payment/card", payment.ChangeCardPayment)
v1.GET("/payment/card", payment.ChangeCardPaymentInit)
v1.POST("/payment/subscribe", payment.PostSubscribeGettingURL)
v1.GET("/payment", payment.GetBillingPortalURL)

//
// Support/Request
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/core/payment/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const (
)

type Input struct {
ItemID uint `json:"item_id"`
Plan string `json:"plan"` // yearly, monthly
}

type ChangeCardPaymentInit struct {
Expand Down
4 changes: 2 additions & 2 deletions pkg/api/core/payment/v0/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/homenoc/dsbd-backend/pkg/api/core/payment"
"github.com/homenoc/dsbd-backend/pkg/api/core/tool/config"
dbPayment "github.com/homenoc/dsbd-backend/pkg/api/store/payment/v0"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v72/refund"
"github.com/stripe/stripe-go/v73"
"github.com/stripe/stripe-go/v73/refund"
"gorm.io/gorm"
"net/http"
"strconv"
Expand Down
198 changes: 57 additions & 141 deletions pkg/api/core/payment/v0/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,197 +5,113 @@ import (
"github.com/homenoc/dsbd-backend/pkg/api/core"
auth "github.com/homenoc/dsbd-backend/pkg/api/core/auth/v0"
"github.com/homenoc/dsbd-backend/pkg/api/core/common"
"github.com/homenoc/dsbd-backend/pkg/api/core/group"
"github.com/homenoc/dsbd-backend/pkg/api/core/payment"
"github.com/homenoc/dsbd-backend/pkg/api/core/tool/config"
dbGroup "github.com/homenoc/dsbd-backend/pkg/api/store/group/v0"
dbPayment "github.com/homenoc/dsbd-backend/pkg/api/store/payment/v0"
dbPaymentMembershipTemplate "github.com/homenoc/dsbd-backend/pkg/api/store/template/payment_membership/v0"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v72/customer"
"github.com/stripe/stripe-go/v72/paymentmethod"
"github.com/stripe/stripe-go/v72/setupintent"
"github.com/stripe/stripe-go/v72/sub"
"gorm.io/gorm"
"log"
"github.com/stripe/stripe-go/v73"
billingSession "github.com/stripe/stripe-go/v73/billingportal/session"
"github.com/stripe/stripe-go/v73/checkout/session"
"net/http"
"strconv"
"time"
)

func MembershipPayment(c *gin.Context) {
var input payment.Input
func PostSubscribeGettingURL(c *gin.Context) {
userToken := c.Request.Header.Get("USER_TOKEN")
accessToken := c.Request.Header.Get("ACCESS_TOKEN")

var input payment.Input
err := c.BindJSON(&input)
if err != nil {
log.Println(err)
c.JSON(http.StatusBadRequest, common.Error{Error: err.Error()})
return
}

result := auth.GroupAuthorization(0, core.Token{UserToken: userToken, AccessToken: accessToken})
if result.Err != nil {
c.JSON(http.StatusUnauthorized, common.Error{Error: result.Err.Error()})
return
}
var priceID = ""

if result.User.Group.StripeSubscriptionID != nil && *result.User.Group.StripeSubscriptionID != "" {
c.JSON(http.StatusBadRequest, common.Error{Error: "Error: Subscription."})
// search plan
for _, oneMembership := range config.Conf.Template.Membership {
if oneMembership.Plan == input.Plan {
priceID = oneMembership.PriceID
}
}
if priceID == "" {
c.JSON(http.StatusBadRequest, common.Error{Error: "invalid plan"})
return
}

if *result.User.Group.Student {
c.JSON(http.StatusBadRequest, common.Error{Error: "Error: You are student."})
resultAuth := auth.GroupAuthorization(0, core.Token{UserToken: userToken, AccessToken: accessToken})
if resultAuth.Err != nil {
c.JSON(http.StatusUnauthorized, common.Error{Error: resultAuth.Err.Error()})
return
}

resultTemplate, err := dbPaymentMembershipTemplate.Get(input.ItemID)
if err != nil {
c.JSON(http.StatusBadRequest, common.Error{Error: "template is not found..."})
// exist check: stripeCustomerID
if *resultAuth.User.Group.StripeCustomerID == "" {
c.JSON(http.StatusInternalServerError, common.Error{Error: "stripe customer id not found..."})
return
}

if result.User.Group.StripeCustomerID == nil {
c.JSON(http.StatusInternalServerError, common.Error{Error: "stripe customerID is not exists."})
// exist check: stripeCustomerID
if *resultAuth.User.Group.StripeCustomerID == "" {
c.JSON(http.StatusInternalServerError, common.Error{Error: "stripe customer id not found..."})
return
}

stripe.Key = config.Conf.Stripe.SecretKey

params := &stripe.SubscriptionParams{
Items: []*stripe.SubscriptionItemsParams{
date := time.Now()
params := &stripe.CheckoutSessionParams{
Mode: stripe.String(string(stripe.CheckoutSessionModeSubscription)),
Customer: resultAuth.User.Group.StripeCustomerID,
LineItems: []*stripe.CheckoutSessionLineItemParams{
{
Price: stripe.String(resultTemplate.PriceID),
Price: stripe.String(priceID),
Quantity: stripe.Int64(1),
},
},
PaymentBehavior: stripe.String("default_incomplete"),
Customer: stripe.String(*result.User.Group.StripeCustomerID),
}
params.AddExpand("latest_invoice.payment_intent")

pi, err := sub.New(params)
log.Printf("pi.New: %v\n", pi.LatestInvoice.PaymentIntent.ClientSecret)
if err != nil {
log.Printf("pi.New: %v", err)
c.JSON(http.StatusInternalServerError, common.Error{Error: "payment_membership system error"})
return
}

dbPayment.Create(&core.Payment{
GroupID: result.User.GroupID,
PaymentIntentID: pi.LatestInvoice.PaymentIntent.ID,
Type: core.PaymentMembership,
Paid: &[]bool{false}[0],
Fee: resultTemplate.Fee,
})

dbGroup.Update(group.UpdateMembership, core.Group{
Model: gorm.Model{ID: *result.User.GroupID},
StripeCustomerID: result.User.Group.StripeCustomerID,
StripeSubscriptionID: &pi.ID,
PaymentMembershipTemplateID: &resultTemplate.ID,
})

c.JSON(http.StatusOK, payment.ResultByUser{
ClientSecret: pi.LatestInvoice.PaymentIntent.ClientSecret,
})
}

func ChangeCardPayment(c *gin.Context) {
var input payment.ChangeCardPaymentInit
userToken := c.Request.Header.Get("USER_TOKEN")
accessToken := c.Request.Header.Get("ACCESS_TOKEN")

err := c.BindJSON(&input)
if err != nil {
log.Println(err)
c.JSON(http.StatusBadRequest, common.Error{Error: err.Error()})
return
}

result := auth.GroupAuthorization(0, core.Token{UserToken: userToken, AccessToken: accessToken})
if result.Err != nil {
c.JSON(http.StatusUnauthorized, common.Error{Error: result.Err.Error()})
return
}

stripe.Key = config.Conf.Stripe.SecretKey

if result.User.Group.StripeCustomerID == nil {
c.JSON(http.StatusInternalServerError, common.Error{Error: "stripe customerID is not exists."})
return
}

if result.User.Group.StripeSubscriptionID == nil {
c.JSON(http.StatusInternalServerError, common.Error{Error: "stripe subscriptionID is not exists."})
return
}

//attach
pm, err := paymentmethod.Attach(input.PaymentMethodID, &stripe.PaymentMethodAttachParams{
Customer: stripe.String(*result.User.Group.StripeCustomerID),
})
if err != nil {
log.Printf("Error: %v", err)
c.JSON(http.StatusInternalServerError, common.Error{Error: "payment_membership system error"})
return
}
log.Println(pm)

// change card on user
cus, err := customer.Update(*result.User.Group.StripeCustomerID, &stripe.CustomerParams{
InvoiceSettings: &stripe.CustomerInvoiceSettingsParams{
DefaultPaymentMethod: stripe.String(input.PaymentMethodID),
SuccessURL: stripe.String(config.Conf.Controller.User.Url),
//CancelURL: stripe.String("https://example.com/cancel"),
ExpiresAt: stripe.Int64(date.Add(time.Minute * 30).Unix()),
SubscriptionData: &stripe.CheckoutSessionSubscriptionDataParams{
Metadata: map[string]string{
"type": "membership",
"group_id": strconv.Itoa(int(resultAuth.User.Group.ID)),
"name": "Yuto Yoneda",
"log": "[" + strconv.Itoa(int(resultAuth.User.ID)) + "] " + resultAuth.User.Name +
"_[" + strconv.Itoa(int(resultAuth.User.Group.ID)) + "] " + resultAuth.User.Group.Org,
},
},
})
if err != nil {
log.Printf("Error: %v", err)
c.JSON(http.StatusInternalServerError, common.Error{Error: "payment_membership system error"})
return
}

log.Printf(cus.ID)
s, err := session.New(params)

_, err = sub.Update(*result.User.Group.StripeSubscriptionID, &stripe.SubscriptionParams{
DefaultPaymentMethod: stripe.String(input.PaymentMethodID),
})
if err != nil {
log.Printf("Error: %v", err)
c.JSON(http.StatusInternalServerError, common.Error{Error: "payment_membership system error"})
c.JSON(http.StatusInternalServerError, common.Error{Error: err.Error()})
return
}

c.JSON(http.StatusOK, common.Result{})
c.JSON(http.StatusOK, map[string]string{"url": s.URL})
}

func ChangeCardPaymentInit(c *gin.Context) {
func GetBillingPortalURL(c *gin.Context) {
userToken := c.Request.Header.Get("USER_TOKEN")
accessToken := c.Request.Header.Get("ACCESS_TOKEN")

result := auth.UserAuthorization(core.Token{UserToken: userToken, AccessToken: accessToken})
if result.Err != nil {
c.JSON(http.StatusUnauthorized, common.Error{Error: result.Err.Error()})
resultAuth := auth.GroupAuthorization(0, core.Token{UserToken: userToken, AccessToken: accessToken})
if resultAuth.Err != nil {
c.JSON(http.StatusUnauthorized, common.Error{Error: resultAuth.Err.Error()})
return
}

stripe.Key = config.Conf.Stripe.SecretKey

// get subscription
params := &stripe.SetupIntentParams{
PaymentMethodTypes: []*string{
stripe.String("card"),
},
params := &stripe.BillingPortalSessionParams{
Customer: stripe.String("cus_MBBRylUHxUQvVc"),
Configuration: stripe.String(config.Conf.Stripe.MembershipConfiguration),
ReturnURL: stripe.String(config.Conf.Controller.User.Url),
}

si, err := setupintent.New(params)
log.Printf("si.New: %v\n", si.ClientSecret)
s, err := billingSession.New(params)
if err != nil {
log.Printf("si.New: %v", err)
c.JSON(http.StatusInternalServerError, common.Error{Error: "payment_membership system error"})
c.JSON(http.StatusInternalServerError, common.Error{Error: err.Error()})
return
}

c.JSON(http.StatusOK, payment.ResultByUser{
ClientSecret: si.ClientSecret,
})
c.JSON(http.StatusOK, map[string]string{"url": s.URL})
}
2 changes: 1 addition & 1 deletion pkg/api/core/payment/v0/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"github.com/homenoc/dsbd-backend/pkg/api/core/tool/config"
"github.com/homenoc/dsbd-backend/pkg/api/core/tool/notification"
"github.com/slack-go/slack"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v73"
"strconv"
"strings"
)
Expand Down
6 changes: 3 additions & 3 deletions pkg/api/core/payment/v0/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/homenoc/dsbd-backend/pkg/api/core/common"
"github.com/homenoc/dsbd-backend/pkg/api/core/tool/config"
dbPayment "github.com/homenoc/dsbd-backend/pkg/api/store/payment/v0"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v72/webhook"
"github.com/stripe/stripe-go/v73"
"github.com/stripe/stripe-go/v73/webhook"
"io/ioutil"
"log"
"net/http"
Expand Down Expand Up @@ -68,7 +68,7 @@ func GetStripeWebHook(c *gin.Context) {
paymentIntent := event.Data.Object["payment_intent"].(string)
if dataType == "donate" {
dbPayment.Create(&core.Payment{
Type: core.PaymentMembership,
Type: core.PaymentDonate,
GroupID: nil,
Refund: &[]bool{false}[0],
PaymentIntentID: paymentIntent,
Expand Down
22 changes: 20 additions & 2 deletions pkg/api/core/tool/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
Radius Radius `json:"radius"`
Slack Slack `json:"slack"`
Log Log `json:"log"`
Template Template `json:"template"`
}

type Controller struct {
Expand All @@ -45,8 +46,9 @@ type Web struct {
}

type Stripe struct {
WebhookSecretKey string `json:"webhook_secret_key"`
SecretKey string `json:"secret_key"`
WebhookSecretKey string `json:"webhook_secret_key"`
SecretKey string `json:"secret_key"`
MembershipConfiguration string `json:"membership_configuration"`
}

type AdminAuth struct {
Expand Down Expand Up @@ -106,6 +108,22 @@ type SlackChannels struct {
PaymentLog string `json:"payment_log"`
}

type Template struct {
Membership []Membership `json:"membership"`
NTT []string `json:"NTT"`
V4 []string `json:"v4"`
V6 []string `json:"v6"`
V4Route []string `json:"v4_route"`
V6Route []string `json:"v6_route"`
}

type Membership struct {
Title string `json:"title"`
Plan string `json:"plan"`
PriceID string `json:"price_id"`
Fee string `json:"fee"`
}

type Log struct {
Path string `json:"path"`
}
Expand Down

0 comments on commit d99e415

Please sign in to comment.