Skip to content

Commit 2b7eebf

Browse files
authored
Merge pull request #2787 from mmccullom-sf/adyenApplePayPDP
@W-19014904 – Adyen Apple Pay PDP
2 parents 85b2a56 + 8c4e8d4 commit 2b7eebf

File tree

11 files changed

+1069
-61
lines changed

11 files changed

+1069
-61
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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+
import {useState, useEffect} from 'react'
8+
import {AdyenPaymentMethodsService} from '@salesforce/retail-react-app/app/components/apple-pay-express/utils/payment-methods'
9+
10+
/**
11+
* Hook for fetching payment methods without basket dependency (for "Buy Now" flows)
12+
* @param {string} authToken - Authentication token
13+
* @param {object} site - Site configuration
14+
* @param {object} locale - Locale configuration
15+
* @param {boolean} enabled - Whether the hook should make API calls (default: true)
16+
* @returns {object} Payment methods data, loading state, and error
17+
*/
18+
export const useStandalonePaymentMethods = (authToken, site, locale, enabled = true) => {
19+
const [paymentMethods, setPaymentMethods] = useState(null)
20+
const [loading, setLoading] = useState(false)
21+
const [error, setError] = useState(null)
22+
23+
useEffect(() => {
24+
// Only make API call if enabled and required parameters are available
25+
if (!enabled || !authToken || !site) {
26+
return
27+
}
28+
29+
const fetchPaymentMethods = async () => {
30+
try {
31+
setLoading(true)
32+
setError(null)
33+
34+
const service = new AdyenPaymentMethodsService(authToken, site)
35+
const data = await service.getPaymentMethods()
36+
37+
setPaymentMethods(data)
38+
} catch (err) {
39+
console.error('Error fetching standalone payment methods:', err)
40+
setError(err)
41+
} finally {
42+
setLoading(false)
43+
}
44+
}
45+
46+
fetchPaymentMethods()
47+
}, [authToken, site, locale, enabled])
48+
49+
return {
50+
paymentMethods,
51+
loading,
52+
error
53+
}
54+
}

0 commit comments

Comments
 (0)