-
Notifications
You must be signed in to change notification settings - Fork 0
/
payments.js
121 lines (104 loc) · 3.77 KB
/
payments.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import {sparqlEscapeUri, sparqlEscapeString} from 'mu';
import {querySudo as query, updateSudo as update} from '@lblod/mu-auth-sudo';
import createMollieClient from "@mollie/api-client";
import http from "http";
export async function getPaymentInformationFromPaymentId(paymentId) {
const queryQuery = `
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
PREFIX schema: <http://schema.org/>
SELECT ?buyerPod ?sellerPod ?order ?seller
FROM <http://mu.semte.ch/application>
WHERE {
?order a schema:Order;
schema:paymentMethodId ${sparqlEscapeString(paymentId)};
ext:sellerPod ?sellerPod;
ext:buyerPod ?buyerPod;
schema:seller ?seller.
}`;
return query(queryQuery);
}
export async function checkPayment(paymentId, apiKey) {
const mollieClient = createMollieClient({apiKey: apiKey});
const payment = await mollieClient.payments.get(paymentId);
return (payment?.status === 'paid');
}
export async function savePaymentId(orderId, paymentId) {
const storeQuery = `
PREFIX schema: <http://schema.org/>
INSERT DATA { GRAPH <http://mu.semte.ch/application> {
${sparqlEscapeUri(orderId)} schema:paymentMethodId ${sparqlEscapeString(paymentId)}.
} }`;
return update(storeQuery);
}
export async function getOrderDetails(orderId) {
const queryQuery = `
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
PREFIX schema: <http://schema.org/>
SELECT ?orderStatus ?offerName ?offerPrice ?offerCurrency ?sellerWebId
FROM <http://mu.semte.ch/application>
WHERE {
${sparqlEscapeUri(orderId)} a schema:Order;
schema:orderStatus ?orderStatus;
schema:acceptedOffer ?offer.
?offer a schema:Offer;
schema:name ?offerName;
schema:seller ?sellerWebId;
schema:price ?offerPrice;
schema:priceCurrency ?offerCurrency.
}`;
return query(queryQuery);
}
export async function handlePayment(offeringName, price, mollieApiKey, mollieRedirectUrl, mollieBaseWebhookUrl) {
const mollieClient = createMollieClient({apiKey: mollieApiKey});
return await mollieClient.payments.create({
amount: {
value: Number(price).toFixed(2),
currency: 'EUR'
},
description: `Payment for ${offeringName} via The Solid Shop.`,
redirectUrl: mollieRedirectUrl,
webhookUrl: mollieBaseWebhookUrl
});
}
export async function confirmPayment(buyerPod, sellerPod, orderUUID) {
const deleteQuery = `
PREFIX schema: <http://schema.org/>
DELETE DATA { GRAPH <http://mu.semte.ch/application> {
${sparqlEscapeUri(orderUUID)} schema:orderStatus <http://schema.org/OrderPaymentDue>.
} }`;
const insertQuery = `
PREFIX schema: <http://schema.org/>
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
INSERT DATA { GRAPH <http://mu.semte.ch/application> {
${sparqlEscapeUri(orderUUID)} schema:orderStatus <http://schema.org/OrderDelivered>.
} }`;
try {
await update(deleteQuery);
await update(insertQuery);
} catch (e) {
console.error(e);
return false;
}
return true;
}
export function sendBackendCallback(backendCallbackHostname, backendCallbackPort, backendCallbackPath, paymentId) {
const data = JSON.stringify({
paymentId: paymentId
});
const options = {
method: 'POST',
port: backendCallbackPort,
hostname: backendCallbackHostname,
path: backendCallbackPath,
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
},
}
const req = http.request(options, () => {});
req.on('error', error => {
console.error(error);
});
req.write(data);
req.end();
}