UNPKG

@unchainedshop/plugins

Version:

Official plugin collection for the Unchained Engine with payment, delivery, and pricing adapters

70 lines (69 loc) 2.64 kB
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); } }