Skip to content

Commit 2179f9f

Browse files
authored
feat: sync single entity (#74)
1 parent 9143db7 commit 2179f9f

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ body: {
129129
}
130130
```
131131

132+
### Syncing single entity
133+
134+
To backfill/update a single entity, you can use
135+
136+
```
137+
POST /sync/single/cus_12345
138+
```
139+
140+
The entity type is recognized automatically, based on the prefix.
141+
132142
## Future ideas
133143

134144
- Expose an "initialize" endpoint that will fetch data from Stripe and do an initial load (or perhaps `POST` a CSV to an endpoint).

src/lib/sync.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,34 @@ type SyncObject =
5454
| 'payment_intent'
5555
| 'plan'
5656

57+
export async function syncSingleEntity(stripeId: string) {
58+
if (stripeId.startsWith('cus_')) {
59+
return stripe.customers.retrieve(stripeId).then((it) => {
60+
if (!it || it.deleted) return
61+
62+
return upsertCustomers([it])
63+
})
64+
} else if (stripeId.startsWith('in_')) {
65+
return stripe.invoices.retrieve(stripeId).then((it) => upsertInvoices([it]))
66+
} else if (stripeId.startsWith('price_')) {
67+
return stripe.prices.retrieve(stripeId).then((it) => upsertPrices([it]))
68+
} else if (stripeId.startsWith('prod_')) {
69+
return stripe.products.retrieve(stripeId).then((it) => upsertProducts([it]))
70+
} else if (stripeId.startsWith('sub_')) {
71+
return stripe.subscriptions.retrieve(stripeId).then((it) => upsertSubscriptions([it]))
72+
} else if (stripeId.startsWith('seti_')) {
73+
return stripe.setupIntents.retrieve(stripeId).then((it) => upsertSetupIntents([it]))
74+
} else if (stripeId.startsWith('pm_')) {
75+
return stripe.paymentMethods.retrieve(stripeId).then((it) => upsertPaymentMethods([it]))
76+
} else if (stripeId.startsWith('dp_') || stripeId.startsWith('du_')) {
77+
return stripe.disputes.retrieve(stripeId).then((it) => upsertDisputes([it]))
78+
} else if (stripeId.startsWith('ch_')) {
79+
return stripe.charges.retrieve(stripeId).then((it) => upsertCharges([it]))
80+
} else if (stripeId.startsWith('pi_')) {
81+
return stripe.paymentIntents.retrieve(stripeId).then((it) => upsertPaymentIntents([it]))
82+
}
83+
}
84+
5785
export async function syncBackfill(params?: SyncBackfillParams): Promise<SyncBackfill> {
5886
const { created, object } = params ?? {}
5987
let products,

src/routes/sync.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { FastifyInstance } from 'fastify'
2-
import { syncBackfill, SyncBackfillParams } from '../lib/sync'
2+
import { syncBackfill, SyncBackfillParams, syncSingleEntity } from '../lib/sync'
33
import { verifyApiKey } from '../utils/verifyApiKey'
44

55
import Stripe from 'stripe'
@@ -23,4 +23,31 @@ export default async function routes(fastify: FastifyInstance) {
2323
})
2424
},
2525
})
26+
27+
fastify.post<{
28+
Params: {
29+
stripeId: string
30+
}
31+
}>('/sync/single/:stripeId', {
32+
preHandler: [verifyApiKey],
33+
schema: {
34+
params: {
35+
type: 'object',
36+
properties: {
37+
stripeId: { type: 'string' },
38+
},
39+
},
40+
},
41+
handler: async (request, reply) => {
42+
const { stripeId } = request.params
43+
44+
const result = await syncSingleEntity(stripeId)
45+
46+
return reply.send({
47+
statusCode: 200,
48+
ts: Date.now(),
49+
data: result,
50+
})
51+
},
52+
})
2653
}

src/routes/sync/daily.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ export default async function routes(fastify: FastifyInstance) {
1515
object: object ?? 'all',
1616
} as SyncBackfillParams
1717

18-
const result = await syncBackfill(params)
18+
await syncBackfill(params)
19+
1920
return reply.send({
2021
statusCode: 200,
2122
ts: Date.now(),
22-
...result,
2323
})
2424
},
2525
})

0 commit comments

Comments
 (0)