|
| 1 | +/* |
| 2 | + * Copyright (c) 2025, Salesforce, Inc. |
| 3 | + * All rights reserved. |
| 4 | + * SPDX-License-Identifier: BSD-3-Clause |
| 5 | + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause |
| 6 | + */ |
| 7 | + |
| 8 | +/** |
| 9 | + * Custom payment methods controller that doesn't require a basket |
| 10 | + * This is specifically for "Buy Now" flows where we need to show Apple Pay |
| 11 | + * before creating a basket |
| 12 | + */ |
| 13 | + |
| 14 | +// Helper function to get the Adyen PWA library version dynamically |
| 15 | +function getAdyenPwaVersion() { |
| 16 | + try { |
| 17 | + // Try to read the version from the installed package |
| 18 | + const packageJson = require('@adyen/adyen-salesforce-pwa/package.json') |
| 19 | + return packageJson.version |
| 20 | + } catch (error) { |
| 21 | + console.error('Unable to determine Adyen PWA version', error) |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +export default async function handler(req, res) { |
| 26 | + if (req.method !== 'GET') { |
| 27 | + return res.status(405).json({error: 'Method not allowed'}) |
| 28 | + } |
| 29 | + |
| 30 | + try { |
| 31 | + const {siteId, locale} = req.query |
| 32 | + |
| 33 | + if (!siteId) { |
| 34 | + return res.status(400).json({error: 'siteId is required'}) |
| 35 | + } |
| 36 | + |
| 37 | + // Get Adyen configuration from environment variables |
| 38 | + // Environment variables are prefixed with the site ID |
| 39 | + const apiKey = process.env[`${siteId}_ADYEN_API_KEY`] |
| 40 | + const merchantAccount = process.env[`${siteId}_ADYEN_MERCHANT_ACCOUNT`] |
| 41 | + const environment = process.env[`${siteId}_ADYEN_ENVIRONMENT`] || 'test' |
| 42 | + const clientKey = process.env[`${siteId}_ADYEN_CLIENT_KEY`] |
| 43 | + |
| 44 | + if (!apiKey || !merchantAccount || !clientKey) { |
| 45 | + return res.status(500).json({ |
| 46 | + error: 'Missing Adyen configuration', |
| 47 | + details: `Required environment variables: ${siteId}_ADYEN_API_KEY, ${siteId}_ADYEN_MERCHANT_ACCOUNT, ${siteId}_ADYEN_CLIENT_KEY` |
| 48 | + }) |
| 49 | + } |
| 50 | + |
| 51 | + // Construct Adyen API URL |
| 52 | + const adyenBaseUrl = |
| 53 | + environment === 'live' |
| 54 | + ? 'https://checkout-live.adyen.com/v70' |
| 55 | + : 'https://checkout-test.adyen.com/v70' |
| 56 | + |
| 57 | + // Call Adyen payment methods API without basket dependency |
| 58 | + const adyenResponse = await fetch(`${adyenBaseUrl}/paymentMethods`, { |
| 59 | + method: 'POST', |
| 60 | + headers: { |
| 61 | + 'Content-Type': 'application/json', |
| 62 | + 'X-API-Key': apiKey |
| 63 | + }, |
| 64 | + body: JSON.stringify({ |
| 65 | + merchantAccount, |
| 66 | + countryCode: locale?.split('-')[1] || 'US', |
| 67 | + channel: 'Web' |
| 68 | + }) |
| 69 | + }) |
| 70 | + |
| 71 | + if (!adyenResponse.ok) { |
| 72 | + const errorBody = await adyenResponse.text() |
| 73 | + console.error('Adyen API error:', errorBody) |
| 74 | + return res.status(adyenResponse.status).json({ |
| 75 | + error: 'Failed to fetch payment methods from Adyen' |
| 76 | + }) |
| 77 | + } |
| 78 | + |
| 79 | + const paymentMethods = await adyenResponse.json() |
| 80 | + |
| 81 | + // Return the payment methods with environment configuration and application info |
| 82 | + res.status(200).json({ |
| 83 | + ...paymentMethods, |
| 84 | + environment: { |
| 85 | + ADYEN_ENVIRONMENT: environment, |
| 86 | + ADYEN_CLIENT_KEY: clientKey |
| 87 | + }, |
| 88 | + applicationInfo: { |
| 89 | + adyenLibrary: { |
| 90 | + name: 'adyen-salesforce-pwa', |
| 91 | + version: getAdyenPwaVersion() |
| 92 | + } |
| 93 | + } |
| 94 | + }) |
| 95 | + } catch (error) { |
| 96 | + console.error('Payment methods API error:', error) |
| 97 | + res.status(500).json({ |
| 98 | + error: 'Internal server error', |
| 99 | + message: error.message |
| 100 | + }) |
| 101 | + } |
| 102 | +} |
0 commit comments