Complete example of processing payments using FinFlow.
This example demonstrates how to:
- Create a payment using Stripe
- Handle payment success/failure
- Create accounting entries
- Query payment status
- FinFlow services running
- Valid JWT token
- Stripe API keys configured
const axios = require("axios");
// Login to get JWT token
const login = async () => {
const response = await axios.post("http://localhost:3001/api/auth/login", {
email: "user@example.com",
password: "password123",
});
return response.data.token;
};
const token = await login();const createPayment = async (token) => {
const paymentData = {
amount: 10000, // $100.00 in cents
currency: "usd",
processorType: "stripe",
source: "tok_visa", // Test token
description: "Order #12345",
metadata: {
orderId: "12345",
customerId: "cust_abc123",
},
};
try {
const response = await axios.post(
"http://localhost:3002/api/payments",
paymentData,
{
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
},
);
console.log("Payment created:", response.data);
return response.data;
} catch (error) {
console.error("Payment failed:", error.response.data);
throw error;
}
};const handlePayment = async (payment) => {
if (payment.status === "succeeded") {
console.log("✓ Payment successful");
console.log("Transaction ID:", payment.processorTransactionId);
// Create accounting entry
await createAccountingEntry(payment);
} else if (payment.status === "failed") {
console.error("✗ Payment failed");
console.error("Error:", payment.error);
}
};const createAccountingEntry = async (payment) => {
const journalEntry = {
date: new Date().toISOString().split("T")[0],
description: `Payment received for ${payment.description}`,
entries: [
{
accountCode: "1000",
accountName: "Cash",
debit: payment.amount / 100,
credit: 0,
},
{
accountCode: "1100",
accountName: "Accounts Receivable",
debit: 0,
credit: payment.amount / 100,
},
],
};
const response = await axios.post(
"http://localhost:3003/api/journal-entries",
journalEntry,
{
headers: {
Authorization: `Bearer ${token}`,
},
},
);
console.log("Accounting entry created:", response.data);
};const getPaymentStatus = async (paymentId) => {
const response = await axios.get(
`http://localhost:3002/api/payments/${paymentId}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
},
);
return response.data;
};
// Usage
const status = await getPaymentStatus(payment.id);
console.log("Current status:", status.status);const processPayment = async () => {
try {
// 1. Login
const token = await login();
// 2. Create payment
const payment = await createPayment(token);
// 3. Handle result
await handlePayment(payment);
// 4. Check status
const status = await getPaymentStatus(payment.id);
console.log("Final status:", status);
} catch (error) {
console.error("Error processing payment:", error.message);
}
};
processPayment();Payment created: {
id: 'payment-uuid-123',
amount: 10000,
currency: 'usd',
status: 'succeeded',
processorType: 'stripe',
processorTransactionId: 'ch_3abc123...',
createdAt: '2025-01-20T15:30:00Z'
}
✓ Payment successful
Transaction ID: ch_3abc123...
Accounting entry created: {
id: 'journal-entry-uuid',
date: '2025-01-20',
status: 'posted'
}
Current status: succeeded
try {
const payment = await createPayment(token);
} catch (error) {
if (error.response) {
// Server responded with error
console.error("Status:", error.response.status);
console.error("Error:", error.response.data.error);
if (error.response.status === 401) {
console.log("Token expired, refreshing...");
// Refresh token and retry
} else if (error.response.status === 400) {
console.log("Invalid payment data");
}
} else if (error.request) {
// No response received
console.error("Network error:", error.message);
}
}