Skip to content

Instantly share code, notes, and snippets.

@farzd
Last active February 2, 2025 08:15
Show Gist options
  • Save farzd/b666573935970eb93d88710c61762508 to your computer and use it in GitHub Desktop.
Save farzd/b666573935970eb93d88710c61762508 to your computer and use it in GitHub Desktop.
Revenue Cat supabase hook
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { createClient } from "jsr:@supabase/supabase-js@2";
import { create, verify } from "https://deno.land/x/[email protected]/mod.ts";
const supabase = createClient(
Deno.env.get("SUPABASE_URL")!,
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!
);
const REVENUECAT_SECRET = Deno.env.get("RC_SECRET")!;
Deno.serve(async (req) => {
try {
if (req.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const authHeader = req.headers.get("Authorization");
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return new Response("Unauthorized", { status: 401 });
}
const jwt = authHeader.replace("Bearer ", "");
const importedKeyJWT = {
kty: "oct",
k: REVENUECAT_SECRET,
alg: "HS512",
key_ops: ["sign", "verify"],
ext: true
};
const importedKey = await crypto.subtle.importKey(
"jwt",
importedKeyJWT,
{ name: "HMAC", hash: "SHA-512" },
true,
["sign", "verify"]
);
const payload = await verify(jwt, importedKey);
if (payload['whateverObjectSetInJWT']) {
const { event } = await req.json();
switch (event.type) {
case "INITIAL_PURCHASE":
case "RENEWAL":
await updateUserCredits(event.app_user_id, event.product_id, event.id);
break;
}
return new Response("OK", { status: 200 });
} else {
return new Response("Invalid token", { status: 401 });
}
} catch (error) {
console.error("Error processing request:", error);
return new Response(`Internal Server Error: ${error.message}`, { status: 500 });
}
});
async function updateUserCredits(supabaseUserId, productId, eventId) {
// Perform upsert operation
const { error } = await supabase
.from("subscriptions")
.upsert(
{
user_id: supabaseUserId,
rc_product_id: productId,
},
{
onConflict: 'user_id'
}
);
console.log('updating', { supabaseUserId, productId, eventId, newScans });
if (error) {
console.error("Error updating user credits:", error);
throw error;
} else {
console.log("User credits updated successfully");
}
}
@farzd
Copy link
Author

farzd commented Oct 23, 2024

Create your key with

const key = await crypto.subtle.generateKey(
  { name: "HMAC", hash: "SHA-512" },
  true,
  ["sign", "verify"]
);

const exportedKeyJWK = await crypto.subtle.exportKey("jwt", key);
const keyToStore = exportedKeyJWK.k;  //this is your Deno.env.get("RC_SECRET"), store as SECRET for your Supabase Edge Fn

const jwt = await create({ alg: "HS512", typ: "JWT" }, { whateverObjectSetInJWT: true }, key); //Beart jwt is what you set in Revenue Cat webhook in the [Authorization header value field]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment