diff options
| author | Joe Carstairs <65492573+Sycamost@users.noreply.github.com> | 2023-12-21 21:22:47 +0000 |
|---|---|---|
| committer | Joe Carstairs <jcarstairs@scottlogic.com> | 2024-01-29 10:46:46 +0000 |
| commit | 2d0634cdc3d00b3e55cf773ff03c7dc841112d36 (patch) | |
| tree | 424f0b9ce2907e3d58336a2b25233bf0f9bead9d /api/_paypal.ts | |
| parent | f44b2a82b74337c6424c576fdbf4c1376166e553 (diff) | |
33 / Users can sign up and log in with WebAuthn (#39)
* Installs @vercel/postgres
* Installs @simplewebauthn/server
* Installs @simplewebauthn/browser
* Git-ignores all files starting with .env
* Reorganises folders in API
* Defines User type
* Defines Subscription type
* Defines Authenticator type
* Sets up table definition file
* Can get user from database
* Can add user to database
* Can get user's current challenge
* Can set user's current challenge
* Can get user's authenticators from database
* Can get authenticator by ID from database
* Can add user authenticator to database
* Can update authenticator in database
* Defines Relying Party information
* Can generate registration options
* Can verify registration response
* Defines registration API endpoint
* Defines user API endpoint
* Reorganises API functions on frontend
* Can access authentication API functions on frontend
* Can generate authentication options
* Can verify authentication response
* Documents the registration flow
* Fix dev_csso
* Form styling
* WIP adds sign up page
Diffstat (limited to 'api/_paypal.ts')
| -rw-r--r-- | api/_paypal.ts | 115 |
1 files changed, 0 insertions, 115 deletions
diff --git a/api/_paypal.ts b/api/_paypal.ts deleted file mode 100644 index 5abb198..0000000 --- a/api/_paypal.ts +++ /dev/null @@ -1,115 +0,0 @@ -import type Order from './_Order'; -import env from './_env'; - -export async function paypalCreateOrder(order: Order) { - const accessToken = await getLazyAccessToken(); - const url = `${PAYPAL_URL}/v2/checkout/orders`; - const response = await fetch(url, { - method: 'POST', - headers: paypalCreateOrderRequestHeaders(accessToken), - body: paypalCreateOrderRequestBody(order), - }); - return await handle(response); -} - -export async function paypalCaptureOrder(orderId: string) { - const accessToken = await getLazyAccessToken(); - const url = `${PAYPAL_URL}/v2/checkout/orders/${orderId}/capture`; - const response = await fetch(url, { - method: 'POST', - headers: paypalCaptureOrderRequestHeaders(accessToken), - }); - return await handle(response); -} - -async function handle(response: Response) { - if (response.ok) { - return await response.json(); - } - throw new Error('Failed to communicate with PayPal. ' + await response.text()); -} - -function paypalCreateOrderRequestBody(order: Order) { - const body = JSON.stringify({ - intent: 'CAPTURE', - purchase_units: [ - { - description: order.productDescription, - soft_descriptor: order.shortDescription, - amount: { - currency_code: 'GBP', - value: order.totalPrice, - }, - }, - ], - }); - return body; -} - -function paypalCreateOrderRequestHeaders(accessToken: string) { - return { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }; -} - -function paypalCaptureOrderRequestHeaders(accessToken: string) { - return { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }; -} - -const getLazyAccessToken = (() => { - let accessToken: string; - let timeRequested: number; - let timeExpires: number; - return async function (): Promise<string> { - const isNearlyExpired = timeExpires - Date.now() < 10_000; - if (!accessToken || isNearlyExpired) { - timeRequested = Date.now(); - let secondsUntilExpires: number; - ({ accessToken, secondsUntilExpires } = await generateAccessToken()); - const msUntilExpires = secondsUntilExpires * 1000; - timeExpires = timeRequested + msUntilExpires; - } - return accessToken; - }; -})(); - -async function generateAccessToken(): Promise<AccessTokenResponse> { - const auth = Buffer.from(PAYPAL_CLIENT_ID + ':' + PAYPAL_SECRET).toString('base64'); - const response = await fetch(`${PAYPAL_URL}/v1/oauth2/token`, { - method: 'POST', - body: 'grant_type=client_credentials', - headers: { - Authorization: `Basic ${auth}`, - }, - }); - const { access_token, expires_in } = await response.json(); - if (access_token && expires_in) { - return { - accessToken: access_token, - secondsUntilExpires: expires_in, - }; - } - throw new Error('Could not fetch access token from PayPal.'); -} - -type AccessTokenResponse = { - accessToken: string; - secondsUntilExpires: number; -}; - -const PAYPAL_CLIENT_ID = - env.ENVIRONMENT === 'prod' - ? env.PAYPAL_LIVE_CLIENT_ID - : env.PAYPAL_SANDBOX_CLIENT_ID; -const PAYPAL_SECRET = - env.ENVIRONMENT === 'prod' - ? env.PAYPAL_LIVE_SECRET - : env.PAYPAL_SANDBOX_SECRET; -const PAYPAL_URL = - env.ENVIRONMENT === 'prod' - ? 'https://api-m.paypal.com' - : 'https://api-m.sandbox.paypal.com'
\ No newline at end of file |
