Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signup form with Vipps payment #16

Merged
merged 55 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
1e2541d
add header
sverrejb Jul 31, 2023
0307d49
started on form
sverrejb Aug 1, 2023
6ec6349
form actions, buttons etc
sverrejb Aug 1, 2023
b810323
add icon
sverrejb Aug 1, 2023
47ddd9d
return values on actions
sverrejb Aug 1, 2023
3804324
css and stuff
sverrejb Aug 1, 2023
e530bc7
icon on card button
sverrejb Aug 1, 2023
3ec14f0
slight refactor
sverrejb Aug 1, 2023
7d8f519
h2
sverrejb Aug 1, 2023
dca7cb6
add tnc component
sverrejb Aug 1, 2023
925ff42
fix derp on success
sverrejb Aug 1, 2023
e2714c3
remove unused selector
sverrejb Aug 2, 2023
840aff9
kinda works with google
sverrejb Aug 2, 2023
45bedfa
refactoring?
sverrejb Aug 3, 2023
95cfe3f
blahblah
sverrejb Aug 3, 2023
9760bdb
started on return endpoint
sverrejb Aug 3, 2023
abab5fb
add missing file
sverrejb Aug 3, 2023
9b2e143
started on crypto
sverrejb Aug 30, 2023
f8f2cc7
started on crypto
sverrejb Aug 30, 2023
ea182b5
encryption from env variables
sverrejb Aug 30, 2023
fa2909e
minor crypto refactor
sverrejb Aug 30, 2023
e6a6ec9
google sheet idempotency
sverrejb Aug 31, 2023
e6b7dc1
fix ts shit
sverrejb Aug 31, 2023
0c367af
small error log change
sverrejb Aug 31, 2023
d4117a2
some error handling and graphics
sverrejb Aug 31, 2023
cde377d
some refactor
sverrejb Sep 1, 2023
361ded6
no idea what i am doing
sverrejb Sep 12, 2023
cc8dd9a
updating stuff works
sverrejb Sep 20, 2023
3430e0f
rebase and fix
sverrejb Jan 30, 2024
035363a
delete a paragraph of placeholder
sverrejb Jan 31, 2024
67a54ec
disable prerendering nonstatic page
sverrejb Jan 31, 2024
3ea7adf
update error message
sverrejb Jan 31, 2024
b404fae
cleanup after rebase
sverrejb Feb 21, 2024
cff0ae7
update tnc
sverrejb Feb 21, 2024
acca0c8
more tnc
sverrejb Feb 22, 2024
45522a5
try current node
sverrejb Feb 22, 2024
303c97a
try old node
sverrejb Feb 22, 2024
3ab5480
18.0.0
sverrejb Feb 22, 2024
7b7aa06
18.13.0
sverrejb Feb 22, 2024
0030c85
fuck web development
sverrejb Feb 22, 2024
9b7d3c2
remove placeholder text
sverrejb Feb 22, 2024
7d44648
further vipps integration
sverrejb Mar 17, 2024
68cc978
vipps happy path ish working
sverrejb Mar 18, 2024
a1219cb
capture sort of works
sverrejb Mar 18, 2024
cdc8137
nok for i dag
sverrejb Mar 18, 2024
8c1979e
some cleanup
sverrejb Mar 18, 2024
491ad04
clean more
sverrejb Mar 18, 2024
b72179c
add name to welcome page
sverrejb Mar 19, 2024
642fa39
only capture uncaptured payments
sverrejb Mar 20, 2024
6593f1d
read membership data from config file
sverrejb Mar 20, 2024
ad8ca4d
read membership from config data in vipps module
sverrejb Mar 20, 2024
a900eb5
some cleanup and refactoring
sverrejb Mar 20, 2024
e9c6cd0
comments and timeout
sverrejb Mar 20, 2024
72791fc
delete weird timestamp files
sverrejb Mar 20, 2024
46c4d20
remove unneeded dep
sverrejb Mar 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
capture sort of works
  • Loading branch information
sverrejb committed Mar 18, 2024
commit a1219cb23aa541b3a6b25802760293ba27012eb7
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@
"node-fetch": "^3.3.2",
"vite-imagetools": "^6.2.9"
}
}
}
48 changes: 43 additions & 5 deletions src/lib/utils/vipps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { VIPPS_CLIENT_ID, VIPPS_CLIENT_SECRET, VIPPS_OCP_APIM_SUBSCRIPTION_KEY, VIPPS_MSN } from '$env/static/private';
import { VIPPS_CLIENT_ID, VIPPS_CLIENT_SECRET, VIPPS_OCP_APIM_SUBSCRIPTION_KEY, VIPPS_MSN, VIPPS_BASE_URL } from '$env/static/private';
//TODO: Read this from config
const prices: { [key: string]: number } = { "year": 330, "year-reduced": 220, "semester": 215, "semester-reduced": 150 };

Expand All @@ -9,7 +9,7 @@ export enum PaymentType {
}

export async function getVippsAccessToken() {
const url = 'https://apitest.vipps.no/accesstoken/get';
const url = `${VIPPS_BASE_URL}/accesstoken/get`;
const headers = {
"Content-Type": "application/json",
"client_id": VIPPS_CLIENT_ID,
Expand All @@ -32,7 +32,7 @@ export async function getVippsAccessToken() {
}

export async function initiateVippsPayment(accessToken: string, formData: FormData, returnUrl: string, paymentType: PaymentType) {
const url = 'https://apitest.vipps.no/epayment/v1/payments';
const url = `${VIPPS_BASE_URL}/epayment/v1/payments`;

const idempotencyKey = formData.get("id") as string;
const membershipType = formData.get("membershipType") as string;
Expand Down Expand Up @@ -89,8 +89,8 @@ export async function initiateVippsPayment(accessToken: string, formData: FormDa
return responseData;
}

async function getStatusOfPayment(paymentReference: string, accessToken: string) {
const url = `https://apitest.vipps.no/epayment/v1/payments/${paymentReference}`;
export async function getPaymentStatus(paymentReference: string, accessToken: string) {
const url = `${VIPPS_BASE_URL}/epayment/v1/payments/${paymentReference}`;

const headers = {
"Content-Type": "application/json",
Expand All @@ -110,4 +110,42 @@ async function getStatusOfPayment(paymentReference: string, accessToken: string)
}

return await response.json();
}

export async function capturePayment(paymentReference: string, amount: number, accessToken: string) {
const url = `${VIPPS_BASE_URL}/epayment/v1/payments/${paymentReference}/capture`;

const headers = {
"Content-Type": "application/json",
"Authorization": `Bearer ${accessToken}`,
"Ocp-Apim-Subscription-Key": VIPPS_OCP_APIM_SUBSCRIPTION_KEY,
"Merchant-Serial-Number": VIPPS_MSN,
"Idempotency-Key": paymentReference,
};

const body = {
"modificationAmount": {
"currency": "NOK",
"value": amount
}
};

const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
});

if (!response.ok) {
const responseData = await response.json();

console.log(responseData);

throw new Error(`HTTP error! status: ${response.status}`);
}
const responseData = await response.json();

console.log(responseData);

return responseData;
}
24 changes: 21 additions & 3 deletions src/routes/membership/registrationComplete/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
/** @type {import('./$types').PageLoad} */
import { ENCRYPTION_KEY, INITIALIZATION_VECTOR } from '$env/static/private';
import { addPaymentDetailsToRegistration } from '$lib/utils/googleSheets';
import { decryptFormData } from '$lib/utils/crypto.js';

import { redirect } from '@sveltejs/kit';
import { getVippsAccessToken, getPaymentStatus, capturePayment } from '$lib/utils/vipps';

export const prerender = false;

export async function load({ url }) {
const encryptedData: string = url.searchParams.get('data');
const encryptedData: string | null = url.searchParams.get('data');

if (!encryptedData) {
throw redirect(303, "/");
}

try {
const decryptedJson = await decryptFormData(encryptedData);
const { id, name, email, membershipType } = decryptedJson;

const vippsToken = await getVippsAccessToken();
const paymentStatus = await getPaymentStatus(id, vippsToken.access_token);
const pspReference = paymentStatus.pspReference;
const amount = paymentStatus.amount.value;

console.log(paymentStatus);
console.log(pspReference);

if (paymentStatus.state !== 'AUTHORIZED') {
return { error: true }
}

if (paymentStatus.state === 'AUTHORIZED') {
await capturePayment(id, amount, vippsToken.access_token);
}

await addPaymentDetailsToRegistration(id, name, email, membershipType);
}
catch (error) {
catch (error: any) {
console.error(error.message)
return { error: true }
}
Expand Down