Skip to content

Instantly share code, notes, and snippets.

@chientrm
Last active February 2, 2024 03:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chientrm/adcad96715adb69aff08fd5587f640ed to your computer and use it in GitHub Desktop.
Save chientrm/adcad96715adb69aff08fd5587f640ed to your computer and use it in GitHub Desktop.
SvelteKit PayPal webhook
import { CLIENT_SECRET, PAYPAL, WEBHOOK_ID } from '$env/static/private';
import { PUBLIC_CLIENT_ID } from '$env/static/public';
import { Events } from '$lib/schema';
import { forceOk } from '$lib/util.server';
import { Buffer } from 'node:buffer';
const authenticate = () =>
fetch(`${PAYPAL}/v1/oauth2/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${Buffer.from(PUBLIC_CLIENT_ID + ':' + CLIENT_SECRET).toString(
'base64'
)}`
},
body: new URLSearchParams({ grant_type: 'client_credentials' })
})
.then((res) => res.json<{ access_token: string }>())
.then((data) => data.access_token);
export const POST = async ({ request, locals }) => {
const auth_algo = request.headers.get('PAYPAL-AUTH-ALGO');
const cert_url = request.headers.get('PAYPAL-CERT-URL');
const transmission_id = request.headers.get('PAYPAL-TRANSMISSION-ID');
const transmission_sig = request.headers.get('PAYPAL-TRANSMISSION-SIG');
const transmission_time = request.headers.get('PAYPAL-TRANSMISSION-TIME');
const webhook_id = WEBHOOK_ID;
const webhook_event = await request.json<{
id: string;
resource: {
start_time: string;
create_time: string;
custom_id: string;
id: string;
plan_id: string;
status: string;
};
}>();
const access_token = await authenticate();
await fetch(`${PAYPAL}/v1/notifications/verify-webhook-signature`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${access_token}`
},
body: JSON.stringify({
auth_algo,
cert_url,
transmission_id,
transmission_sig,
transmission_time,
webhook_id,
webhook_event
})
}).then(forceOk);
const { id, resource } = webhook_event;
const { id: resource_id, start_time, create_time, custom_id: email, plan_id, status } = resource;
await locals.db
.insert(Events)
.values({ id, email, start_time, create_time, resource_id, plan_id, status });
console.log({ id });
return new Response(null, { status: 200 });
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment