Learn how to integrate a secure payment gateway with Lovable. Follow our step-by-step guide to create seamless payment solutions for your website.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Setting Up Payment Gateway API Credentials
const PAYMENT_API_KEY = "your-api-key-here";
const PAYMENT_API_SECRET = "your-api-secret-here";
export { PAYMENT_API_KEY, PAYMENT_API_SECRET };
Adding a Dependency for HTTP Requests
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
Creating the Payment Integration Logic File
import { PAYMENT_API_KEY, PAYMENT_API_SECRET } from "./config.js";
// Function to initialize a payment request
function createPayment(amount, currency) {
// Construct the payload with required parameters
const payload = {
apiKey: PAYMENT_API_KEY,
apiSecret: PAYMENT_API_SECRET,
amount: amount,
currency: currency,
// Additional parameters as required by the payment provider
};
// Make an HTTP POST request to the payment gateway API
axios.post("https://api.paymentgatewayprovider.com/createPayment", payload)
.then(function(response) {
handlePaymentResponse(response.data);
})
.catch(function(error) {
console.error("Payment creation error:", error);
alert("An error occurred while processing the payment. Please try again.");
});
}
// Function to handle the payment gateway's response
function handlePaymentResponse(data) {
if (data.status === "success") {
alert("Payment Successful!");
} else {
alert("Payment Failed. Please check your details and try again.");
}
}
// Expose the createPayment function for use elsewhere
export { createPayment };
Integrating the Payment Button into Your Lovable App Interface
<button id="payButton">Pay Now</button>
<script type="module" src="./paymentIntegration.js"></script>
Adding an Event Listener to Trigger the Payment Process
import { createPayment } from "./paymentIntegration.js";
document.getElementById("payButton").addEventListener("click", function() {
// Set the payment amount and currency (these could also be dynamically retrieved)
createPayment(100, "USD");
});
Testing Your Payment Gateway Integration
const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');
const app = express();
app.use(bodyParser.json());
app.post('/lovable/payment', async (req, res) => {
try {
const { amount, currency, userId, paymentMethod } = req.body;
if (!amount || !currency || !userId || !paymentMethod) {
return res.status(400).json({ error: 'Missing required payment fields' });
}
const payload = {
merchantId: 'YOUR_LOVABLE_MERCHANT\_ID',
order: {
userId,
details: {
amount,
currency,
paymentMethod
}
}
};
const response = await axios.post('https://api.lovablepay.com/v1/payments', payload, {
headers: {
'Authorization': 'Bearer YOUR_LOVABLE_API\_KEY',
'Content-Type': 'application/json'
}
});
if (response.data.success) {
res.status(200).json({ message: 'Payment processed successfully', transactionId: response.data.transactionId });
} else {
res.status(500).json({ error: 'Failed to process payment on Lovable', details: response.data });
}
} catch (error) {
console.error('Payment error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();
app.use(bodyParser.json());
const LOVABLE_WEBHOOK_SECRET = process.env.LOVABLE_WEBHOOK_SECRET || 'YOUR\_SECRET';
function verifySignature(payload, signature) {
const hash = crypto
.createHmac('sha256', LOVABLE_WEBHOOK_SECRET)
.update(JSON.stringify(payload))
.digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signature));
} catch (e) {
return false;
}
}
app.post('/lovable/webhook', (req, res) => {
const signature = req.headers['lovable-signature'];
if (!signature || !verifySignature(req.body, signature)) {
return res.status(401).json({ error: 'Invalid or missing signature' });
}
const { event, data } = req.body;
if (!event || !data) {
return res.status(400).json({ error: 'Malformed webhook payload' });
}
if (event === 'payment.success') {
// Process a successful payment event
// e.g., update transaction status in database
console.log(`Payment success for user ${data.userId}, transaction ${data.transactionId}`);
} else if (event === 'payment.failed') {
// Process a failed payment event
console.log(`Payment failed for user ${data.userId}, error: ${data.errorMessage}`);
} else {
console.log(`Unhandled event type: ${event}`);
}
res.status(200).end();
});
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`Webhook listener running on port ${PORT}`);
});
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
let cachedToken = null;
let tokenExpiresAt = 0;
async function fetchLovableToken() {
const now = Date.now();
if (cachedToken && now < tokenExpiresAt) {
return cachedToken;
}
const response = await axios.post('https://api.lovablepay.com/v1/token', {
apiKey: process.env.LOVABLE_API_KEY,
apiSecret: process.env.LOVABLE_API_SECRET
});
cachedToken = response.data.token;
tokenExpiresAt = now + (response.data.expiresIn \* 1000) - 30000;
return cachedToken;
}
app.post('/lovable/refund', async (req, res) => {
try {
const { transactionId, amount, reason } = req.body;
if (!transactionId || !amount || !reason) {
return res.status(400).json({ error: 'Missing transactionId, amount or reason' });
}
const token = await fetchLovableToken();
const refundRequest = await axios.post('https://api.lovablepay.com/v1/refunds', {
transactionId,
amount,
reason
}, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
let { refundId, status } = refundRequest.data;
if (status === 'pending') {
let attempts = 0;
while (attempts < 5 && status === 'pending') {
await new Promise(resolve => setTimeout(resolve, 2000));
const statusResponse = await axios.get(`https://api.lovablepay.com/v1/refunds/${refundId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
status = statusResponse.data.status;
attempts++;
}
}
res.status(200).json({ refundId, finalStatus: status });
} catch (error) {
console.error('Refund Error:', error.response ? error.response.data : error.message);
res.status(500).json({ error: 'Refund processing failed' });
}
});
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(`Refund service is running on port ${PORT}`));
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Understanding Payment Gateway Integration
Setting Up the Environment
# Assuming you have Python installed, you can create a virtual environment:
python -m venv payment-env
source payment-env/bin/activate # For Mac/Linux
payment-env\Scripts\activate # For Windows
Install the necessary libraries
pip install requests
Integrating with Payment Gateway APIs
import requests
def process_payment(payment_details):
# The endpoint URL provided by the payment gateway
endpoint = "https://api.paymentgateway.com/process"
# Include your API key in the request headers
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
# Send a POST request with payment data in JSON format
response = requests.post(endpoint, json=payment\_details, headers=headers)
return response.json()
Example payment details
payment_data = {
"amount": 100,
"currency": "USD",
"card_number": "4111111111111111",
"expiry_month": "12",
"expiry_year": "2025",
"cvv": "123"
}
result = process_payment(payment_data)
print(result)
Incorporating AI Code Generators
import os
def get_api_key():
# Retrieve API key from environment variables to keep it secure
return os.getenv("PAYMENT_GATEWAY_API_KEY")
api_key = get_api_key()
Implementing Security Best Practices
Testing and Error Handling
def process_payment(payment_details):
try:
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.