Skip to content

Commit

Permalink
fix(billing): Upgraded to stripe v76 + fixed billing portal
Browse files Browse the repository at this point in the history
The billing portal will no longer allow the email address to be changed,
the email must instead be changed inside monetr directly (once support
is added). This also bumps the stripe library to the latest version.
  • Loading branch information
elliotcourant committed May 27, 2024
1 parent 6f89f96 commit f4b0460
Show file tree
Hide file tree
Showing 23 changed files with 52 additions and 131 deletions.
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ require (
github.com/klauspost/cpuid/v2 v2.2.7
github.com/labstack/echo/v4 v4.11.4
github.com/mileusna/useragent v1.3.4
github.com/nyaruka/phonenumbers v1.3.5
github.com/oklog/ulid/v2 v2.1.0
github.com/pkg/errors v0.9.1
github.com/plaid/plaid-go/v20 v20.1.0
Expand All @@ -39,7 +38,7 @@ require (
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.17.0
github.com/stretchr/testify v1.8.4
github.com/stripe/stripe-go/v72 v72.122.0
github.com/stripe/stripe-go/v76 v76.25.0
github.com/teambition/rrule-go v1.8.2
github.com/vmihailenco/msgpack/v5 v5.3.5
github.com/wneessen/go-mail v0.4.1
Expand Down
8 changes: 3 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nyaruka/phonenumbers v1.3.4 h1:bF1Wdh++fxw09s3surhVeBhXEcUKG07pHeP8HQXqjn8=
github.com/nyaruka/phonenumbers v1.3.4/go.mod h1:Ut+eFwikULbmCenH6InMKL9csUNLyxHuBLyfkpum11s=
github.com/nyaruka/phonenumbers v1.3.5/go.mod h1:Ut+eFwikULbmCenH6InMKL9csUNLyxHuBLyfkpum11s=
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand Down Expand Up @@ -430,8 +427,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
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/v76 v76.25.0 h1:kmDoOTvdQSTQssQzWZQQkgbAR2Q8eXdMWbN/ylNalWA=
github.com/stripe/stripe-go/v76 v76.25.0/go.mod h1:rw1MxjlAKKcZ+3FOXgTHgwiOa2ya6CPq6ykpJ0Q6Po4=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8=
Expand Down Expand Up @@ -608,6 +605,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
Expand Down
6 changes: 3 additions & 3 deletions interface/src/pages/account/subscribe/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useCallback, useState } from 'react';
import axios from 'axios';
import { useSnackbar } from 'notistack';

import { MBaseButton } from '@monetr/interface/components/MButton';
Expand All @@ -7,7 +8,6 @@ import MLogo from '@monetr/interface/components/MLogo';
import MSpan from '@monetr/interface/components/MSpan';
import { useAppConfiguration } from '@monetr/interface/hooks/useAppConfiguration';
import { useAuthenticationSink } from '@monetr/interface/hooks/useAuthentication';
import request from '@monetr/interface/util/request';

export default function SubscribePage(): JSX.Element {
const { enqueueSnackbar } = useSnackbar();
Expand All @@ -21,14 +21,14 @@ export default function SubscribePage(): JSX.Element {
setLoading(true);
let promise: Promise<any>;
if (initialPlan && !hasSubscription) {
promise = request().post('/billing/create_checkout', {
promise = axios.post('/api/billing/create_checkout', {
priceId: '',
cancelPath: '/logout',
});
} else if (hasSubscription) {
// If the customer has a subscription then we want to just manage it. This will allow a customer to fix a
// subscription for a card that has failed payment or something similar.
promise = request().get('/billing/portal');
promise = axios.get('/api/billing/portal');
}

promise
Expand Down
2 changes: 1 addition & 1 deletion server/billing/easy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/monetr/monetr/server/pubsub"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v76"
)

func buildAccountCacheKey(accountId ID[Account]) string {
Expand Down
2 changes: 1 addition & 1 deletion server/billing/paywall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/monetr/monetr/server/internal/myownsanity"
"github.com/monetr/monetr/server/internal/testutils"
"github.com/stretchr/testify/assert"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v76"
)

func TestBaseBasicPaywall_GetHasSubscription(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion server/billing/stripe.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/monetr/monetr/server/pubsub"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v76"
)

type StripeWebhookHandler interface {
Expand Down
32 changes: 13 additions & 19 deletions server/controller/billing.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
"net/url"
"strings"
"time"

"github.com/labstack/echo/v4"
Expand All @@ -12,7 +13,7 @@ import (
"github.com/monetr/monetr/server/crumbs"
"github.com/monetr/monetr/server/internal/myownsanity"
"github.com/monetr/monetr/server/stripe_helper"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v76"
)

// Create Checkout Session
Expand Down Expand Up @@ -149,24 +150,21 @@ func (c *Controller) handlePostCreateCheckout(ctx echo.Context) error {
}

successUrl := fmt.Sprintf(
"%s://%s/account/subscribe/after?session={CHECKOUT_SESSION_ID}",
c.configuration.ExternalURLProtocol,
c.configuration.UIDomainName,
"%s/account/subscribe/after?session={CHECKOUT_SESSION_ID}",
c.configuration.GetUIURL(),
)
cancelUrl := fmt.Sprintf(
"%s://%s/account/subscribe",
c.configuration.ExternalURLProtocol,
c.configuration.UIDomainName,
"%s/account/subscribe",
c.configuration.GetUIURL(),
)
// If a custom cancel path was specified by the requester then use that path. Note: it can only be a path, not a
// completely custom URL.
// TODO This still has a code smell to it. If this isn't necessary I think we should just remove it outright.
if request.CancelPath != nil {
cancelUrl = fmt.Sprintf(
"%s://%s%s",
c.configuration.ExternalURLProtocol,
c.configuration.UIDomainName,
*request.CancelPath,
"%s/%s",
c.configuration.GetUIURL(),
strings.TrimPrefix(*request.CancelPath, "/"),
)
}

Expand Down Expand Up @@ -200,8 +198,6 @@ func (c *Controller) handlePostCreateCheckout(ctx echo.Context) error {
Discounts: nil,
LineItems: []*stripe.CheckoutSessionLineItemParams{
{
// Number of bank accounts?
Amount: nil,
Quantity: stripe.Int64(1),
Price: &plan.StripePriceId,
},
Expand All @@ -214,10 +210,8 @@ func (c *Controller) handlePostCreateCheckout(ctx echo.Context) error {
PaymentMethodOptions: nil,
SetupIntentData: nil,
ShippingAddressCollection: nil,
ShippingRates: nil,
SubmitType: nil,
SubscriptionData: &stripe.CheckoutSessionSubscriptionDataParams{
Coupon: nil,
DefaultTaxRates: nil,
Metadata: map[string]string{
"environment": c.configuration.Environment,
Expand Down Expand Up @@ -370,14 +364,14 @@ func (c *Controller) handleGetStripePortal(ctx echo.Context) error {
}
}

// Return the user to the UI home page when they return the monetr. If they are authenticated this will show them
// the transactions view, or will prompt them for credentials if they are no longer authenticated.
returnUrl := fmt.Sprintf("%s://%s", c.configuration.ExternalURLProtocol, c.configuration.UIDomainName)
// Return the user to the UI home page when they return the monetr. If they
// are authenticated this will show them the transactions view, or will prompt
// them for credentials if they are no longer authenticated.
params := &stripe.BillingPortalSessionParams{
Configuration: nil,
Customer: account.StripeCustomerId,
OnBehalfOf: nil,
ReturnURL: stripe.String(returnUrl),
ReturnURL: stripe.String(c.configuration.GetUIURL()),
}

session, err := c.stripe.NewPortalSession(c.getContext(ctx), params)
Expand Down
2 changes: 1 addition & 1 deletion server/controller/stripe.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"github.com/labstack/echo/v4"
"github.com/monetr/monetr/server/crumbs"
"github.com/stripe/stripe-go/v72/webhook"
"github.com/stripe/stripe-go/v76/webhook"
)

func (c *Controller) handleStripeWebhook(ctx echo.Context) error {
Expand Down
2 changes: 1 addition & 1 deletion server/internal/fixtures/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/monetr/monetr/server/models"
"github.com/monetr/monetr/server/repository"
"github.com/stretchr/testify/require"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v76"
"github.com/xlzd/gotp"
)

Expand Down
14 changes: 5 additions & 9 deletions server/internal/mock_stripe/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package mock_stripe

import (
"fmt"
"io/ioutil"
"io"
"net/http"
"net/url"
"strconv"
Expand All @@ -13,14 +13,14 @@ import (
"github.com/monetr/monetr/server/internal/mock_http_helper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v76"
)

func (m *MockStripeHelper) MockNewCheckoutSession(t *testing.T) {
mock_http_helper.NewHttpMockJsonResponder(t,
"POST", RegexPath(t, `/v1/checkout/sessions\z`),
func(t *testing.T, request *http.Request) (interface{}, int) {
body, err := ioutil.ReadAll(request.Body)
body, err := io.ReadAll(request.Body)
require.NoError(t, err, "failed to read request body")

form, err := url.ParseQuery(string(body))
Expand Down Expand Up @@ -86,7 +86,6 @@ func (m *MockStripeHelper) MockNewCheckoutSession(t *testing.T) {
},
CustomerDetails: nil,
CustomerEmail: "",
Deleted: false,
ID: "",
LineItems: &stripe.LineItemList{
Data: lineItems,
Expand All @@ -101,7 +100,6 @@ func (m *MockStripeHelper) MockNewCheckoutSession(t *testing.T) {
PaymentMethodTypes: nil,
PaymentStatus: "",
SetupIntent: nil,
Shipping: nil,
ShippingAddressCollection: nil,
SubmitType: "",
Subscription: nil,
Expand Down Expand Up @@ -193,13 +191,11 @@ func (m *MockStripeHelper) CompleteCheckoutSession(t *testing.T, checkoutSession
NextPendingInvoiceItemInvoice: 0,
Object: "subscription",
OnBehalfOf: nil,
PauseCollection: stripe.SubscriptionPauseCollection{},
PauseCollection: nil,
PaymentSettings: nil,
PendingInvoiceItemInterval: stripe.SubscriptionPendingInvoiceItemInterval{},
PendingInvoiceItemInterval: nil,
PendingSetupIntent: nil,
PendingUpdate: nil,
Plan: nil,
Quantity: 0,
Schedule: nil,
StartDate: 0,
Status: stripe.SubscriptionStatusActive,
Expand Down
7 changes: 4 additions & 3 deletions server/internal/mock_stripe/checkout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package mock_stripe

import (
"fmt"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"github.com/stripe/stripe-go/v72"
"net/http"
"testing"

"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"github.com/stripe/stripe-go/v76"
)

func TestMockStripeGetCompletedCheckoutSession(t *testing.T) {
Expand Down
6 changes: 3 additions & 3 deletions server/internal/mock_stripe/customers.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package mock_stripe

import (
"io/ioutil"
"io"
"net/http"
"net/url"
"testing"
"time"

"github.com/monetr/monetr/server/internal/mock_http_helper"
"github.com/stretchr/testify/require"
"github.com/stripe/stripe-go/v72"
"github.com/stripe/stripe-go/v76"
)

func (m *MockStripeHelper) MockStripeCreateCustomerSuccess(t *testing.T) {
mock_http_helper.NewHttpMockJsonResponder(t,
"POST", "/v1/customers",
func(t *testing.T, request *http.Request) (interface{}, int) {
body, err := ioutil.ReadAll(request.Body)
body, err := io.ReadAll(request.Body)
require.NoError(t, err, "failed to read request body")

form, err := url.ParseQuery(string(body))
Expand Down
Loading

0 comments on commit f4b0460

Please sign in to comment.