Last active
February 2, 2024 03:58
-
-
Save chientrm/adcad96715adb69aff08fd5587f640ed to your computer and use it in GitHub Desktop.
SvelteKit PayPal webhook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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