Skip to content

Commit 34f05bb

Browse files
committed
- feat: add invoices API with pagination
- feat: add payment API (create invoice and pay)
1 parent 3a3f1b6 commit 34f05bb

File tree

1 file changed

+101
-6
lines changed

1 file changed

+101
-6
lines changed

routes/stripe.js

+101-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
const express = require('express');
22
const Stripe = require('stripe');
3-
const cors = require('cors'); // Import the CORS middleware
3+
const cors = require('cors');
44

55
const router = express.Router();
66

77
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
8-
apiVersion: '2020-08-27',
8+
apiVersion: '2022-11-15'
99
});
1010

11-
const HARD_CODED_CUSTOMER_ID = 'cus_RPmbpSyKY0cF1N'; // Hard-coded customer ID for testing purposes
11+
const HARD_CODED_CUSTOMER_ID = 'cus_RPmbpSyKY0cF1N';
1212

1313
// Enable CORS for all routes in this router
1414
router.use(cors()); // Allow cross-origin requests for all routes in this router
@@ -38,15 +38,15 @@ router.get('/payment-method', async (req, res) => {
3838

3939
// Route to remove a payment method
4040
router.delete('/payment-method/:id', async (req, res) => {
41-
const { id } = req.params;
41+
const {id} = req.params;
4242

4343
try {
4444
await stripe.paymentMethods.detach(id);
4545

4646
res.status(200).json({
4747
status: 'success',
4848
message: 'Payment method removed successfully.',
49-
data: { id },
49+
data: {id},
5050
});
5151
} catch (error) {
5252
console.error('Error removing payment method:', error.message);
@@ -60,7 +60,7 @@ router.delete('/payment-method/:id', async (req, res) => {
6060

6161
// Route to attach a payment method to a customer
6262
router.put('/payment-method', async (req, res) => {
63-
const { paymentMethodId } = req.body;
63+
const {paymentMethodId} = req.body;
6464

6565
if (!paymentMethodId) {
6666
return res.status(400).json({
@@ -90,4 +90,99 @@ router.put('/payment-method', async (req, res) => {
9090
}
9191
});
9292

93+
94+
router.post('/payment-intent', async (req, res) => {
95+
try {
96+
const {amount, currency, paymentMethod} = req.body
97+
const paymentIntent = await stripe.paymentIntents.create({
98+
amount,
99+
currency,
100+
customer: HARD_CODED_CUSTOMER_ID,
101+
payment_method: paymentMethod,
102+
confirm: true,
103+
})
104+
res.json(paymentIntent)
105+
} catch (error) {
106+
res.status(500).json({error: error.message})
107+
}
108+
})
109+
110+
router.post('/payment', async (req, res) => {
111+
const {
112+
customerId = HARD_CODED_CUSTOMER_ID,
113+
paymentMethod,
114+
amount,
115+
currency = 'usd',
116+
description = 'Invoice for custom payment'
117+
} = req.body;
118+
119+
try {
120+
// 1. Create and finalize the invoice
121+
const invoice = await stripe.invoices.create({
122+
customer: customerId,
123+
auto_advance: false, // Automatically finalize and charge this invoice
124+
});
125+
126+
// 2. Create an invoice item
127+
await stripe.invoiceItems.create({
128+
customer: customerId,
129+
amount,
130+
currency,
131+
description,
132+
invoice: invoice.id,
133+
});
134+
135+
// 3. Pay the invoice using the specified payment method
136+
const paidInvoice = await stripe.invoices.pay(invoice.id, {
137+
payment_method: paymentMethod,
138+
});
139+
140+
141+
// Respond with the invoice details
142+
res.status(200).json({
143+
status: 'success',
144+
message: 'Payment and invoice processed successfully.',
145+
data: {invoice: paidInvoice},
146+
});
147+
} catch (error) {
148+
console.error('Error processing payment and invoice:', error.message);
149+
res.status(500).json({
150+
status: 'error',
151+
message: 'Failed to process payment and invoice.',
152+
data: null,
153+
});
154+
}
155+
});
156+
157+
158+
// Route to fetch invoices with pagination (10 per page)
159+
router.get('/invoices', async (req, res) => {
160+
try {
161+
const {starting_after} = req.query; // Get the starting_after parameter from query params
162+
163+
// Use Stripe's invoices.list API to retrieve the invoices
164+
const invoices = await stripe.invoices.list({
165+
customer: HARD_CODED_CUSTOMER_ID,
166+
limit: 10, // Get only 10 invoices per request
167+
starting_after: starting_after || undefined, // If starting_after is provided, use it
168+
});
169+
170+
res.status(200).json({
171+
status: 'success',
172+
message: 'Invoices retrieved successfully.',
173+
data: {
174+
invoices: invoices.data,
175+
has_more: invoices.has_more, // Check if there are more invoices to paginate
176+
},
177+
});
178+
} catch (error) {
179+
console.error('Error fetching invoices:', error.message);
180+
res.status(500).json({
181+
status: 'error',
182+
message: 'Failed to fetch invoices.',
183+
data: null,
184+
});
185+
}
186+
});
187+
93188
module.exports = router;

0 commit comments

Comments
 (0)