Skip to content

Commit 2ee6c0b

Browse files
committed
implemented webhook handling for customer_cash_balance_transaction.created event
1 parent a68b9a8 commit 2ee6c0b

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/api/routes/stripe.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
ScanCommand,
44
TransactWriteItemsCommand,
55
UpdateItemCommand,
6+
PutItemCommand,
67
} from "@aws-sdk/client-dynamodb";
78
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";
89
import { withRoles, withTags } from "api/components/index.js";
@@ -332,6 +333,7 @@ const stripeRoutes: FastifyPluginAsync = async (fastify, _options) => {
332333
sig,
333334
secretApiConfig.stripe_links_endpoint_secret as string,
334335
);
336+
// event = JSON.parse(request.rawBody.toString()); <-- this is for testing without a stripe account via Curl
335337
} catch (err: unknown) {
336338
if (err instanceof BaseError) {
337339
throw err;
@@ -715,7 +717,57 @@ Please contact Officer Board with any questions.`,
715717
return reply
716718
.code(200)
717719
.send({ handled: false, requestId: request.id });
720+
case "customer_cash_balance_transaction.created": {
721+
const txn = event.data.object as any;
718722

723+
if (txn.funding_method === "bank_transfer") {
724+
const customerId = txn.customer?.toString() ?? "UNKNOWN";
725+
const amount = txn.net_amount;
726+
const currency = txn.currency;
727+
const status = txn.status;
728+
const eventId = event.id;
729+
730+
request.log.info(
731+
`Received ACH push ${status} txn ${txn.id} for ${customerId} (${amount} ${currency})`,
732+
);
733+
734+
await fastify.dynamoClient.send(
735+
new PutItemCommand({
736+
TableName: genericConfig.StripePaymentsDynamoTableName,
737+
Item: marshall({
738+
primaryKey: `CUSTOMER#${customerId}`,
739+
sortKey: `PAY#${txn.id}`,
740+
amount,
741+
currency,
742+
status,
743+
createdAt: Date.now(),
744+
eventId,
745+
}),
746+
}),
747+
);
748+
749+
// if (status === "succeeded") {
750+
// await fastify.dynamoClient.send(
751+
// new UpdateItemCommand({
752+
// TableName: genericConfig.StripePaymentsDynamoTableName,
753+
// Key: marshall({
754+
// primaryKey: `CUSTOMER#${customerId}`,
755+
// sortKey: "SUMMARY",
756+
// }),
757+
// UpdateExpression: "ADD totalPaid :amount SET lastUpdated = :ts",
758+
// ExpressionAttributeValues: marshall({
759+
// ":amount": amount,
760+
// ":ts": Date.now(),
761+
// }),
762+
// })
763+
// );
764+
// }
765+
}
766+
767+
return reply
768+
.status(200)
769+
.send({ handled: true, requestId: request.id });
770+
}
719771
default:
720772
request.log.warn(`Unhandled event type: ${event.type}`);
721773
}

src/common/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export type GenericConfigType = {
4040
CacheDynamoTableName: string;
4141
LinkryDynamoTableName: string;
4242
StripeLinksDynamoTableName: string;
43+
StripePaymentsDynamoTableName: string;
4344
EntraSecretName: string;
4445
UpcomingEventThresholdSeconds: number;
4546
AwsRegion: string;
@@ -83,6 +84,7 @@ export const commChairsGroupId = "105e7d32-7289-435e-a67a-552c7f215507";
8384
const genericConfig: GenericConfigType = {
8485
EventsDynamoTableName: "infra-core-api-events",
8586
StripeLinksDynamoTableName: "infra-core-api-stripe-links",
87+
StripePaymentsDynamoTableName: "infra-core-api-stripe-payments",
8688
CacheDynamoTableName: "infra-core-api-cache",
8789
LinkryDynamoTableName: "infra-core-api-linkry",
8890
EntraSecretName: "infra-core-api-entra",

0 commit comments

Comments
 (0)