1import{serve}from"https://deno.land/std@0.224.0/http/server.ts";
2import{createHmac}from"node:crypto";
3
4constWEBHOOK_SECRET=Deno.env.get("STRIPE_WEBHOOK_SECRET")!;
5
6interfaceStripeEvent{
7type:string;
8data:{object:Record<string,unknown>};
9}
10
11functionverifySignature(
12raw:string,
13signature:string,
14secret:string
15):boolean{
16constparts=signature.split(",");
17consttimePart=parts.find((p)=>p.startsWith("t="))!;
18constsigPart=parts.find((p)=>p.startsWith("v1="))!;
19consttimestamp=timePart.slice(2);
20constexpected=createHmac("sha256",secret)
21.update(`${timestamp}.${raw}`)
22.digest("hex");
23returnexpected===sigPart.slice(3);
24}
25
26asyncfunctionhandleWebhook(req:Request):Promise<Response>{
27constraw=awaitreq.text();
28constsig=req.headers.get("stripe-signature")??"";
29
30if(!verifySignature(raw,sig,WEBHOOK_SECRET)){
31returnnewResponse("Invalid signature",{status:401});
32}
33
34constevent:StripeEvent=JSON.parse(raw);
35
36switch(event.type){
37case"invoice.paid":
38// handle paid invoice
39break;
40case"customer.subscription.deleted":
41// handle cancellation
42break;
43}
44
45returnnewResponse(JSON.stringify({received:true}),{
46headers:{"content-type":"application/json"},
47});
48}
49
50serve(handleWebhook,{port:8080});