@unchainedshop/plugins
Version:
Official plugin collection for the Unchained Engine with payment, delivery, and pricing adapters
70 lines (69 loc) • 2.64 kB
JavaScript
const API_BASE_URL = 'https://checkout.postfinance.ch/api';
export class PostFinanceApiClient {
config;
constructor(config) {
this.config = config;
}
async generateMacHeaders(method, path) {
const version = '1';
const timestamp = Math.floor(Date.now() / 1000).toString();
const userId = this.config.userId.toString();
const resourcePath = path;
const dataToSign = [version, userId, timestamp, method, resourcePath].join('|');
const secretBytes = Uint8Array.from(atob(this.config.apiSecret), (c) => c.charCodeAt(0));
const key = await crypto.subtle.importKey('raw', secretBytes, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign']);
const signature = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(dataToSign));
const macValue = btoa(String.fromCharCode(...new Uint8Array(signature)));
return {
'x-mac-version': version,
'x-mac-userid': userId,
'x-mac-timestamp': timestamp,
'x-mac-value': macValue,
};
}
async request(method, endpoint, body) {
const url = `${API_BASE_URL}${endpoint}`;
const urlObj = new URL(url);
const pathWithQuery = urlObj.pathname + urlObj.search;
const macHeaders = await this.generateMacHeaders(method, pathWithQuery);
const headers = {
...macHeaders,
'Content-Type': 'application/json',
Accept: 'application/json',
};
const options = {
method,
headers,
};
if (body && method !== 'GET') {
options.body = JSON.stringify(body);
}
const response = await fetch(url, options);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(`PostFinance API error: ${response.status} ${response.statusText} ${JSON.stringify(errorData)}`);
}
const responseText = await response.text();
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
try {
return JSON.parse(responseText);
}
catch {
return responseText;
}
}
else {
return responseText;
}
}
get(endpoint) {
return this.request('GET', endpoint);
}
post(endpoint, body) {
return this.request('POST', endpoint, body);
}
patch(endpoint, body) {
return this.request('PATCH', endpoint, body);
}
}