Skip to content

Commit b1e9311

Browse files
committed
Initial release
0 parents  commit b1e9311

219 files changed

Lines changed: 20619 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.babelrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"presets": ["next/babel"],
3+
"plugins": [["styled-components", { "ssr": true }], [
4+
"@babel/plugin-proposal-decorators",
5+
{
6+
"legacy": true
7+
}
8+
]]
9+
}

.env.sample

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This is a sample .env file
2+
# Copy or rename this file to .env to make app installable on BigCommerce
3+
# Follow the instructions in the readme file on how to get the BigCommerce App info needed here
4+
5+
# Environment
6+
ENV_NAME=Local Dev
7+
NODE_ENV=development
8+
9+
# Base Details
10+
NEXT_PUBLIC_APP_URL=https://xxxxx-xxx-xxx-xx-x.ngrok.io
11+
BCRYPT_SALT_ROUND=10
12+
13+
# Prisma Database Config
14+
DATABASE_URL=file:./sqlite.db
15+
16+
# BigCommerce Single Click App Details
17+
# Found at https://devtools.bigcommerce.com/my/apps
18+
NEXT_PUBLIC_APP_ID=12345
19+
BC_APP_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
20+
BC_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
21+
BC_APP_CALLBACK_URL=$NEXT_PUBLIC_APP_URL/api/auth
22+
23+
# BigCommerce Channel Name
24+
SUBSCRIPTION_CHANNEL_NAME=Stripe Subscriptions
25+
26+
# BigCommerce Customer Attribute Field & Metafield Names
27+
SUBSCRIPTION_CUSTOMER_ATTRIBUTE_NAME=stripe_customer_id
28+
SUBSCRIPTION_IDS_ATTRIBUTE_NAME=stripe_subscription_ids
29+
SUBSCRIPTION_METAFIELD_KEY=subscription_config
30+
SUBSCRIPTION_METAFIELD_NAMESPACE=Stripe Billing
31+
32+
# BigCommerce Content Mode
33+
# 'script' or 'widget'
34+
STOREFRONT_CONTENT_MODE=script
35+
36+
# Stripe API & Connect Details
37+
STRIPE_SECRET_KEY=xx_xxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
38+
NEXT_PUBLIC_STRIPE_CLIENT_ID=xx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
39+
NEXT_PUBLIC_STRIPE_REDIRECT_URL=$NEXT_PUBLIC_APP_URL/stripe/callback

.eslintignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
next.config.js
2+
/src/types/
3+
**/node_modules
4+
node_modules/*
5+
node_modules
6+
node_modules/**
7+
./node_modules/**

.eslintrc.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
node: true,
5+
es2020: true,
6+
jest: true
7+
},
8+
parser: "@typescript-eslint/parser", // Specifies the ESLint parser
9+
parserOptions: {
10+
ecmaVersion: 2020,
11+
sourceType: "module",
12+
ecmaFeatures: {
13+
jsx: true
14+
}
15+
},
16+
plugins: ["@typescript-eslint", "react", "react-hooks", "prettier"],
17+
extends: [
18+
"plugin:@typescript-eslint/recommended",
19+
"plugin:react/recommended",
20+
"plugin:import/errors",
21+
"plugin:import/warnings",
22+
"plugin:import/typescript",
23+
"prettier",
24+
"plugin:prettier/recommended"
25+
],
26+
rules: {
27+
"@typescript-eslint/no-unused-vars": [
28+
"error",
29+
{
30+
vars: "all",
31+
args: "after-used",
32+
ignoreRestSiblings: false
33+
}
34+
],
35+
"@typescript-eslint/no-explicit-any": 0,
36+
"@typescript-eslint/explicit-function-return-type": 0,
37+
"@typescript-eslint/no-namespace": 0,
38+
"@typescript-eslint/explicit-module-boundary-types": 0,
39+
"import/extensions": [1, { extensions: [".js", ".jsx", ".ts", ".tsx"] }],
40+
"import/no-extraneous-dependencies": [
41+
"error",
42+
{
43+
devDependencies: true
44+
}
45+
],
46+
"react/jsx-filename-extension": [
47+
1,
48+
{ extensions: [".js", ".jsx", ".ts", ".tsx"] }
49+
],
50+
"react/react-in-jsx-scope": 0,
51+
"react/jsx-first-prop-new-line": 0,
52+
"react/prop-types": 0,
53+
"react/jsx-props-no-spreading": [2, { custom: "ignore" }],
54+
"jsx-a11y/anchor-is-valid": 0,
55+
"prettier/prettier": ["error", {}, { usePrettierrc: true }],
56+
"react-hooks/rules-of-hooks": 2,
57+
"react-hooks/exhaustive-deps": 2,
58+
"no-bitwise": 0,
59+
"import/no-extraneous-dependencies": 0
60+
},
61+
settings: {
62+
"import/resolver": {
63+
node: {
64+
extensions: [".js", ".jsx", ".ts", ".tsx"]
65+
},
66+
typescript: {}
67+
},
68+
react: {
69+
version: "detect"
70+
}
71+
}
72+
};

.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# sqlite database
12+
/prisma/*.db
13+
/prisma/*.db-journal
14+
15+
# next.js
16+
/.next/
17+
/out/
18+
19+
# production
20+
/build
21+
22+
# misc
23+
.DS_Store
24+
25+
# debug
26+
npm-debug.log*
27+
yarn-debug.log*
28+
yarn-error.log*
29+
30+
# local env files
31+
.env
32+
.env.local
33+
.env.development.local
34+
.env.test.local
35+
.env.production.local
36+
.vscode
37+
.vercel

.prettierrc.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = {
2+
tabWidth: 2,
3+
printWidth: 80,
4+
endOfLine: 'auto',
5+
arrowParens: 'avoid',
6+
trailingComma: 'none',
7+
semi: true,
8+
useTabs: false,
9+
singleQuote: false,
10+
bracketSpacing: true
11+
};

README.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# BigCommerce Subscription Foundation
2+
3+
🚀 Fast tracks builds of custom subscription experiences on the BigCommerce platform. Save 100s of hours.
4+
5+
💰 **Pre-integrated into Stripe Billing**, including authentication, merchant onboarding, subscription product management, subscription creation, and customer-facing subscription management.
6+
7+
💅 Utilizes the Channels Toolkit to provide a natively integrated subscription channel that fits nicely within the BigCommerce Control Panel.
8+
9+
| Product Management | Storefront Widget |
10+
| ---------------------------------------- | ------------------------------------- |
11+
| ![App Preview](sample-control-panel.png) | ![App Preview](sample-storefront.png) |
12+
13+
## Getting Started
14+
15+
Run:
16+
17+
```bash
18+
npm install
19+
npx prisma generate
20+
npm run dev
21+
```
22+
23+
_Note: `npx prisma generate` is what creates the DB client. If you miss this step, you'll see an error about it missing._
24+
25+
The app should now be running at: http://localhost:3000
26+
27+
## Environment
28+
29+
At a minimum, the following .env variables need to be updated for the app to run successfully
30+
31+
`NEXT_PUBLIC_APP_URL`: This should be a publicly accessible URL so the BigCommerce Stripe webhooks can be recieved. See the section on ngrok below.
32+
33+
`NEXT_PUBLIC_APP_ID`, `BC_APP_CLIENT_ID`, and `BC_APP_SECRET`: Follow the BigCommerce setup instructions below to get these.
34+
35+
`STRIPE_SECRET_KEY` and `NEXT_PUBLIC_STRIPE_CLIENT_ID`: Follow the Stripe setup instructions below to get these.
36+
37+
## Using ngrok
38+
39+
In order webhooks to be received, we recommend setting up ngrok locally on your machine to create a public facing URL that tunnels to your localhost: https://ngrok.com/
40+
41+
After you are running the app, you'd run this in directory ngrok is located within: `./ngrok http localhost:3000`
42+
43+
## BigCommerce Setup
44+
45+
This app gets access to the BigCommerce API by being installed on store. You'll need two things to test out the this flow:
46+
47+
1. Create BigCommerce store: go to https://www.bigcommerce.com/essentials/ and signup for a free trial if you don't have one
48+
49+
2. Create BigCommerce app: go to https://devtools.bigcommerce.com and create a draft app with the following callbacks (in the 2nd, 'Technical' step of app creation):
50+
51+
- Auth Callback URL: http://localhost:3000/api/auth
52+
- Load Callback URL: http://localhost:3000/api/load
53+
- Uninstall Callback URL: http://localhost:3000/api/uninstall
54+
55+
_If you are using ngrok, provide the ngrok URL instead of localhost._
56+
57+
In the next section below, set the following OAuth Scopes for the app:
58+
59+
```
60+
Orders: MODIFY
61+
Order Transactions: MODIFY
62+
Products: MODIFY
63+
Customers: MODIFY
64+
Content: MODIFY
65+
Carts: MODIFY
66+
Channel Listings: MODIFY
67+
Channel Settings: MODIFY
68+
Information & Settings: MODIFY
69+
Sites & Routes: READ-ONLY
70+
Storefront API Tokens: GENERATE TOKENS
71+
```
72+
73+
3. After creating the app, click on 'View Client ID' within the Dev Tools app list to get your Client ID and Client Secret that should be used in the local .env file.
74+
75+
## Stripe Setup
76+
77+
The app is setup to connect multiple BC Stores into one instance. Because of this, you’ll need two Stripe accounts. One for the ‘Connect’ account which the app will use and another which is what the merchant connects to the app and BC store (in the payments area) themselves.
78+
79+
To accomplish this:
80+
81+
1. Create a Stripe account you’ll use to accept payments and manage subscriptions on BigCommerce: https://stripe.com/
82+
2. After that account is created, log into the Stripe Dashboard: https://dashboard.stripe.com/
83+
3. Create a separate Stripe account that will be what the application uses to OAuth the merchant
84+
1. This can be done by selecting ‘+ New Account’ after clicking the name of the current account on the top left of your Stripe Dashboard
85+
2. Pick a name for this account, like ‘BigCommerce App’ that helps you differentiate it from the Stripe payment account
86+
4. Get your Stripe secret key here: https://dashboard.stripe.com/test/apikeys
87+
1. Reveal the secret key under ’Standard Keys’
88+
2. Copy it into your STRIPE_SECRET_KEY env variable
89+
5. Enable Stripe Connect for Platforms here: https://dashboard.stripe.com/test/connect/accounts/overview
90+
1. Select ‘Platform or Marketplace’ and continue
91+
2. While not required for testing, as part of going live later, you’ll need to fill out the platform profile. We suggest using these answers at that point:
92+
- Select ‘Other’ for industry
93+
- Select ‘From your seller/service provider’s website or app’ for where customers purchase products or services
94+
- Select ‘The name of the seller/service provider using your platform’ for whose name is on the customer’s credit card statement
95+
- Select ‘The seller/service provider using your platform’ for who should be contacted if customers have a dispute or complaint
96+
6. Configure your Connect settings here: https://dashboard.stripe.com/test/settings/connect
97+
1. Copy ’Test mode client ID’ into your NEXT_PUBLIC_STRIPE_CLIENT_ID env variable
98+
2. Under ‘OAuth settings’ enable ‘OAuth for Standard accounts’
99+
3. Under ‘Redirects’ add the following URI: https://{your-app-domain}}/stripe/callback
100+
- Since we’re recommending using ngrok for local development the url would look similar to https://xxxx-xxx-xxx-xx-x.ngrok.io/stripe/callback
101+
7. Your app should now be set up to handle Stripe OAuth, API requests, and webhooks
102+
1. Remember the merchant must OAuth the same Stripe payments account (what you created first) to this app that their BigCommerce store uses. Otherwise, the payment intent created when the shopper pays for the original order won’t be readable when creating subscriptions.
103+
2. When testing:
104+
- Make sure test mode is set to ‘Yes’ in the merchant’s Stripe settings within BigCommerce: https://login.bigcommerce.com/deep-links/settings/payment/stripev3
105+
- A vaulted card must be used when checking out. Turn on that functionality by going to ‘Stored Credit Cards’ in the Stripe payments section in BigCommerce and toggling on ‘Enable stored credit cards with Stripe’
106+
- When checking out on the BigCommerce store, you can save the card by logging in as a customer (or creating a new account during checkout) and selecting ‘save this card for later’ in the payments step.
107+
108+
## Managing Subscription Products
109+
110+
Subscription specific product configuration, like available intervals and the discount associated with them, is done within the app, inside Channel Manager. Only products that are listed on the subscription channel show up here. You can list products to the channel from within the Products section of the BigCommerce control panel.
111+
112+
## Prisma Database Config
113+
114+
To host publicly, you'll most likely want to switch away from SQLite. To do this you would:
115+
116+
1. Update the `/prisma/schema.prisma` file with a `provider` other `sqlite` (i.e. `mysql`. info on options are here: https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/data-sources/)
117+
2. Update the `DATABASE_URL` var in `/prisma/.env` to match your new DB connection string
118+
3. Run `npx prisma migrate dev` (this creates tables and inserts related data as defined in `/prisma/migrations/*` into the DB)
119+
4. Run `npx prisma generate` (this generates a new client for the app using the new DB provider setting)
120+
121+
After all this, if you run `npx prisma studio` you'll be able to access this database locally via a visual editor and verify the table have been created.
122+
123+
## Learn More
124+
125+
Looking to help the world's leading brands and the next generation of successful merchants take flight? To learn more about developing on top of the BigCommerce platform, take a look at the following resources:
126+
127+
- [BigCommerce Developer Center](https://developer.bigcommerce.com/) - Learn more about BigCommerce platform features, APIs and SDKs
128+
- [BigDesign](https://developer.bigcommerce.com/big-design/) - An interactive site for BigCommerce's React Components with live code editing
129+
- [Building BigCommerce Apps](https://developer.bigcommerce.com/api-docs/getting-started/building-apps-bigcommerce/building-apps) - Learn how to build apps for the BigCommerce marketplace
130+
131+
## Troubleshooting
132+
133+
### Seeing {"error": "Not found"} when installing the app
134+
135+
If you don't request the proper scopes, the /api/auth request might fail. Check your scopes in the BigCommerc Dev Tools area. Look at the scopes listed above in the "BigCommerce Setup" section above.

backend/auth/get-auth-string.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Store, User } from "@prisma/client";
2+
3+
const getAuthString = (user: User, store: Store) => {
4+
return `token=${user.token}&store_id=${store.id}`;
5+
};
6+
7+
export default getAuthString;

0 commit comments

Comments
 (0)