Skip to content

Commit 4582fae

Browse files
authored
Merge pull request #22 from astoria-tech/azlyth/stripe-sandbox
Integrate with Stripe (test mode)
2 parents b1f3464 + f1f9db2 commit 4582fae

File tree

15 files changed

+1135
-19
lines changed

15 files changed

+1135
-19
lines changed

.cursorignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
/.envrc
2-
**/.envrc
1+
.envrc

compose.yaml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010
- /app/node_modules
1111
environment:
1212
- NODE_ENV=development
13+
- NEXT_PUBLIC_STRIPE_KEY=${NEXT_PUBLIC_STRIPE_KEY}
1314
depends_on:
1415
- backend
1516

@@ -21,6 +22,7 @@ services:
2122
- LOCALMART_UBER_DIRECT_CUSTOMER_ID=${LOCALMART_UBER_DIRECT_CUSTOMER_ID}
2223
- LOCALMART_UBER_DIRECT_CLIENT_ID=${LOCALMART_UBER_DIRECT_CLIENT_ID}
2324
- LOCALMART_UBER_DIRECT_CLIENT_SECRET=${LOCALMART_UBER_DIRECT_CLIENT_SECRET}
25+
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
2426
- PYTHONPATH=/app
2527
ports:
2628
- "8000:8000"
@@ -30,6 +32,15 @@ services:
3032
depends_on:
3133
- pocketbase
3234

35+
stripe-cli:
36+
image: stripe/stripe-cli
37+
container_name: stripe-cli
38+
command: "listen --api-key ${STRIPE_SECRET_KEY} --forward-to backend:8000/api/v0/webhooks/stripe"
39+
environment:
40+
- STRIPE_API_KEY=${STRIPE_SECRET_KEY}
41+
depends_on:
42+
- backend
43+
3344
pocketbase:
3445
image: ghcr.io/muchobien/pocketbase:latest
3546
ports:
@@ -68,4 +79,4 @@ services:
6879
- meilisearch
6980

7081
volumes:
71-
pocketbase_data:
82+
pocketbase_data:
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/// <reference path="../pb_data/types.d.ts" />
2+
migrate((app) => {
3+
const collection = new Collection({
4+
"createRule": "@request.auth.id != ''",
5+
"deleteRule": "@request.auth.id = user.id",
6+
"fields": [
7+
{
8+
"id": "user_relation",
9+
"name": "user",
10+
"type": "relation",
11+
"required": true,
12+
"presentable": false,
13+
"system": false,
14+
"cascadeDelete": true,
15+
"collectionId": "_pb_users_auth_",
16+
"maxSelect": 1,
17+
"minSelect": 1
18+
},
19+
{
20+
"id": "stripe_payment_method",
21+
"name": "stripe_payment_method_id",
22+
"type": "text",
23+
"required": true,
24+
"presentable": false,
25+
"system": false,
26+
"hidden": false
27+
},
28+
{
29+
"id": "last4",
30+
"name": "last4",
31+
"type": "text",
32+
"required": true,
33+
"presentable": false,
34+
"system": false,
35+
"hidden": false
36+
},
37+
{
38+
"id": "brand",
39+
"name": "brand",
40+
"type": "text",
41+
"required": true,
42+
"presentable": false,
43+
"system": false,
44+
"hidden": false
45+
},
46+
{
47+
"id": "exp_month",
48+
"name": "exp_month",
49+
"type": "number",
50+
"required": true,
51+
"presentable": false,
52+
"system": false,
53+
"hidden": false,
54+
"min": 1,
55+
"max": 12,
56+
"onlyInt": true
57+
},
58+
{
59+
"id": "exp_year",
60+
"name": "exp_year",
61+
"type": "number",
62+
"required": true,
63+
"presentable": false,
64+
"system": false,
65+
"hidden": false,
66+
"min": 2024,
67+
"onlyInt": true
68+
},
69+
{
70+
"id": "is_default",
71+
"name": "is_default",
72+
"type": "bool",
73+
"required": true,
74+
"presentable": false,
75+
"system": false,
76+
"hidden": false
77+
},
78+
{
79+
"id": "created",
80+
"name": "created",
81+
"type": "autodate",
82+
"required": false,
83+
"presentable": false,
84+
"system": false,
85+
"hidden": false,
86+
"onCreate": true,
87+
"onUpdate": false
88+
},
89+
{
90+
"id": "updated",
91+
"name": "updated",
92+
"type": "autodate",
93+
"required": false,
94+
"presentable": false,
95+
"system": false,
96+
"hidden": false,
97+
"onCreate": true,
98+
"onUpdate": true
99+
}
100+
],
101+
"id": "payment_methods",
102+
"indexes": ["CREATE UNIQUE INDEX idx_unique_payment_method ON payment_methods (user, stripe_payment_method_id)"],
103+
"listRule": "@request.auth.id = user.id",
104+
"name": "payment_methods",
105+
"system": false,
106+
"type": "base",
107+
"updateRule": "@request.auth.id = user.id",
108+
"viewRule": "@request.auth.id = user.id"
109+
});
110+
111+
return app.save(collection);
112+
}, (app) => {
113+
const collection = app.findCollectionByNameOrId("payment_methods");
114+
return app.delete(collection);
115+
})
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/// <reference path="../pb_data/types.d.ts" />
2+
migrate((app) => {
3+
const collection = app.findCollectionByNameOrId("pbc_3527180448");
4+
5+
// add payment intent field
6+
collection.fields.addAt(collection.fields.length, new Field({
7+
"id": "stripe_payment_intent",
8+
"name": "stripe_payment_intent_id",
9+
"type": "text",
10+
"required": false,
11+
"presentable": false,
12+
"system": false,
13+
"hidden": false,
14+
"autogeneratePattern": "",
15+
"max": 0,
16+
"min": 0,
17+
"pattern": "",
18+
"primaryKey": false
19+
}));
20+
21+
// add payment method relation
22+
collection.fields.addAt(collection.fields.length, new Field({
23+
"id": "stripe_payment_method",
24+
"name": "payment_method",
25+
"type": "relation",
26+
"required": false,
27+
"presentable": false,
28+
"system": false,
29+
"hidden": false,
30+
"collectionId": "payment_methods",
31+
"cascadeDelete": false,
32+
"maxSelect": 1,
33+
"minSelect": 0
34+
}));
35+
36+
// add payment status field
37+
collection.fields.addAt(collection.fields.length, new Field({
38+
"id": "stripe_payment_status",
39+
"name": "payment_status",
40+
"type": "select",
41+
"required": true,
42+
"presentable": false,
43+
"system": false,
44+
"hidden": false,
45+
"values": ["pending", "processing", "succeeded", "failed", "refunded"],
46+
"maxSelect": 1
47+
}));
48+
49+
return app.save(collection);
50+
}, (app) => {
51+
const collection = app.findCollectionByNameOrId("pbc_3527180448");
52+
53+
// remove fields
54+
collection.fields.removeById("stripe_payment_intent");
55+
collection.fields.removeById("stripe_payment_method");
56+
collection.fields.removeById("stripe_payment_status");
57+
58+
return app.save(collection);
59+
})
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/// <reference path="../pb_data/types.d.ts" />
2+
migrate((app) => {
3+
const collection = new Collection({
4+
"createRule": "@request.auth.id != ''",
5+
"deleteRule": "@request.auth.id = user.id",
6+
"fields": [
7+
{
8+
"id": "user_relation",
9+
"name": "user",
10+
"type": "relation",
11+
"required": true,
12+
"presentable": false,
13+
"system": false,
14+
"cascadeDelete": true,
15+
"collectionId": "_pb_users_auth_",
16+
"maxSelect": 1,
17+
"minSelect": 1
18+
},
19+
{
20+
"id": "stripe_customer",
21+
"name": "stripe_customer_id",
22+
"type": "text",
23+
"required": true,
24+
"presentable": false,
25+
"system": false,
26+
"hidden": false
27+
},
28+
{
29+
"id": "created",
30+
"name": "created",
31+
"type": "autodate",
32+
"required": false,
33+
"presentable": false,
34+
"system": false,
35+
"hidden": false,
36+
"onCreate": true,
37+
"onUpdate": false
38+
},
39+
{
40+
"id": "updated",
41+
"name": "updated",
42+
"type": "autodate",
43+
"required": false,
44+
"presentable": false,
45+
"system": false,
46+
"hidden": false,
47+
"onCreate": true,
48+
"onUpdate": true
49+
}
50+
],
51+
"id": "stripe_customers",
52+
"indexes": ["CREATE UNIQUE INDEX idx_unique_customer ON stripe_customers (user, stripe_customer_id)"],
53+
"listRule": "@request.auth.id = user.id",
54+
"name": "stripe_customers",
55+
"system": false,
56+
"type": "base",
57+
"updateRule": "@request.auth.id = user.id",
58+
"viewRule": "@request.auth.id = user.id"
59+
});
60+
61+
return app.save(collection);
62+
}, (app) => {
63+
const collection = app.findCollectionByNameOrId("stripe_customers");
64+
return app.delete(collection);
65+
})

frontend/package-lock.json

Lines changed: 25 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
"dependencies": {
1212
"@headlessui/react": "^2.2.0",
1313
"@heroicons/react": "^2.2.0",
14+
"@stripe/react-stripe-js": "^3.1.1",
15+
"@stripe/stripe-js": "^5.6.0",
1416
"next": "15.1.5",
1517
"pocketbase": "^0.25.1",
1618
"react": "^19.0.0",

0 commit comments

Comments
 (0)