From 89ad059938952c8e8a242e685a938271b1e55ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olav=20Sundf=C3=B8r?= Date: Mon, 26 May 2025 14:32:32 +0200 Subject: [PATCH] Revert "FIX: Existing agreement exists, but is out of sync (#41)" This reverts commit 43477f07987ace6ae7c5b1dc7f115395e51d66b1. --- .gitignore | 1 - lib/vipps/vipps.ts | 85 ++++++++++++---------------- routes/api/trigger-donation/vipps.ts | 21 +------ 3 files changed, 37 insertions(+), 70 deletions(-) diff --git a/.gitignore b/.gitignore index 9c1cbf1..a49d6cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -test-script.ts tmp # Created by https://www.toptal.com/developers/gitignore/api/node,deno,macos,emacs diff --git a/lib/vipps/vipps.ts b/lib/vipps/vipps.ts index 79f03da..33cdeb3 100644 --- a/lib/vipps/vipps.ts +++ b/lib/vipps/vipps.ts @@ -7,12 +7,8 @@ import { STATUS_CODE } from "$fresh/server.ts"; const config = { clientId: Deno.env.get("VIPPS_CLIENT_ID"), clientSecret: Deno.env.get("VIPPS_CLIENT_SECRET"), - ocpApimSubscriptionKeyPrimary: Deno.env.get( - "VIPPS_OCP_APIM_SUBSCRIPTION_KEY_PRIMARY", - ), - ocpApimSubscriptionKeySecondary: Deno.env.get( - "VIPPS_OCM_APIM_SUBSCRIPTION_KEY_SECONDARY", - ), + ocpApimSubscriptionKeyPrimary: Deno.env.get("VIPPS_OCP_APIM_SUBSCRIPTION_KEY_PRIMARY"), + ocpApimSubscriptionKeySecondary: Deno.env.get("VIPPS_OCM_APIM_SUBSCRIPTION_KEY_SECONDARY"), msn: Deno.env.get("VIPPS_MSN"), baseUrl: Deno.env.get("VIPPS_API_BASE_URL"), }; @@ -37,8 +33,8 @@ const getAccessToken = async function () { method: "POST", // @ts-ignore headers: { - client_id: config.clientId, - client_secret: config.clientSecret, + "client_id": config.clientId, + "client_secret": config.clientSecret, ...standardVippsHeaders, }, }); @@ -60,23 +56,23 @@ export const createAgreement = async function (email: string) { ...standardVippsHeaders, }, body: JSON.stringify({ - interval: { - unit: "MONTH", - count: 1, + "interval": { + "unit": "MONTH", + "count": 1, }, - initialCharge: { - amount: amount, - description: "Initial charge", - transactionType: "DIRECT_CAPTURE", + "initialCharge": { + "amount": amount, + "description": "Initial charge", + "transactionType": "DIRECT_CAPTURE", }, - pricing: { - amount: amount, - currency: "NOK", + "pricing": { + "amount": amount, + "currency": "NOK", }, // email is used to identify the user in the success page - merchantRedirectUrl: `${getHostUrl()}/donations-success?email=${email}`, - merchantAgreementUrl: `${getHostUrl()}`, - productName: "Månedlig støtte til NRSS", + "merchantRedirectUrl": `${getHostUrl()}/donations-success?email=${email}`, + "merchantAgreementUrl": `${getHostUrl()}`, + "productName": "Månedlig støtte til NRSS", }), }); @@ -93,23 +89,15 @@ export const createAgreement = async function (email: string) { } }; -export const getAgreement = async function (agreementId: string): Promise< - | { - status: "PENDING" | "ACTIVE" | "STOPPED" | "EXPIRED"; - } - | Error -> { +export const getAgreement = async function (agreementId: string) { const token = await getAccessToken(); - const response = await fetch( - `${config.baseUrl}/recurring/v3/agreements/${agreementId}`, - { - // @ts-ignore - headers: { - authorization: `Bearer ${token}`, - ...standardVippsHeaders, - }, + const response = await fetch(`${config.baseUrl}/recurring/v3/agreements/${agreementId}`, { + // @ts-ignore + headers: { + authorization: `Bearer ${token}`, + ...standardVippsHeaders, }, - ); + }); if (response.status === STATUS_CODE.OK) { return response.json(); @@ -122,21 +110,18 @@ export const getAgreement = async function (agreementId: string): Promise< export const cancelAgreement = async function (agreementId: string) { const token = await getAccessToken(); - const response = await fetch( - `${config.baseUrl}/recurring/v3/agreements/${agreementId}`, - { - method: "PATCH", - // @ts-ignore - headers: { - authorization: `Bearer ${token}`, - "Idempotency-Key": `${agreementId}-${Date.now()}`, - ...standardVippsHeaders, - }, - body: JSON.stringify({ - status: "STOPPED", - }), + const response = await fetch(`${config.baseUrl}/recurring/v3/agreements/${agreementId}`, { + method: "PATCH", + // @ts-ignore + headers: { + authorization: `Bearer ${token}`, + "Idempotency-Key": `${agreementId}-${Date.now()}`, + ...standardVippsHeaders, }, - ); + body: JSON.stringify({ + "status": "STOPPED", + }), + }); if (response.status === STATUS_CODE.NoContent) { return true; diff --git a/routes/api/trigger-donation/vipps.ts b/routes/api/trigger-donation/vipps.ts index 236c8cc..7d20900 100644 --- a/routes/api/trigger-donation/vipps.ts +++ b/routes/api/trigger-donation/vipps.ts @@ -1,7 +1,6 @@ import { getHostUrl, validateEmail } from "../../../lib/utils.ts"; import { storage } from "../../../lib/storage.ts"; import { createAgreement } from "../../../lib/vipps/vipps.ts"; -import { getAgreement } from "../../../lib/vipps/vipps.ts"; export const handler = async function (req: Request): Promise { const email = new URLSearchParams(req.url.split("?")[1] || "").get("email"); @@ -22,27 +21,11 @@ export const handler = async function (req: Request): Promise { const hasActiveAgreement = existingAgreement && existingAgreement.validAt !== null && existingAgreement.revokedAt === null; - - const agreementInVipps = existingAgreement && (await getAgreement(existingAgreement.agreementId)); - if ( - agreementInVipps && - !(agreementInVipps instanceof Error) && - agreementInVipps.status !== "ACTIVE" && hasActiveAgreement ) { - // Somehow the Vipps agreement is not active in our system anymore. - // We should reflect the new status in our system. - await storage.writeVippsAgreement({ - ...existingAgreement, - revokedAt: new Date(), - }); - } else { - // i.e. the agreement in our system was in sync with Vipps. - if (hasActiveAgreement) { - console.error("Agreement already exists", email); - return Response.redirect(errorPage); - } + console.error("Agreement already exists", email); + return Response.redirect(errorPage); } const agreement = await createAgreement(email);