This commit is contained in:
aaron 2025-08-19 11:52:31 +08:00
parent a9606d9253
commit 30fa25f206
4 changed files with 287 additions and 15 deletions

View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>订单确认</title>
<style>
body {
margin: 0;
padding: 20px;
font-family: Arial, sans-serif;
background-color: #f5f5f5;
color: #333;
}
.container {
max-width: 400px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background-color: #667eea;
color: white;
padding: 20px;
text-align: center;
}
.header h1 {
margin: 0;
font-size: 20px;
}
.content {
padding: 20px;
}
.order-info {
text-align: center;
margin-bottom: 20px;
}
.order-number {
font-size: 16px;
font-weight: bold;
color: #667eea;
margin-bottom: 10px;
}
.order-amount {
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.order-status {
background-color: #ffc107;
color: #212529;
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
font-weight: bold;
display: inline-block;
}
.footer {
background-color: #f8f9fa;
padding: 15px;
text-align: center;
font-size: 12px;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>订单确认成功</h1>
</div>
<div class="content">
<p>亲爱的 <strong>{{customerName}}</strong></p>
<p>您的订单已成功提交,请及时完成支付。</p>
<div class="order-info">
<div class="order-number">订单号:{{orderNumber}}</div>
<div class="order-amount">${{totalAmount}} USDT</div>
<div class="order-status">等待支付</div>
</div>
<p>感谢您选择我们的服务!</p>
</div>
<div class="footer">
感谢您的选择!
</div>
</div>
</body>
</html>

View File

@ -8,17 +8,23 @@
"dev": "nodemon server.js"
},
"dependencies": {
"axios": "^1.6.0",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"crypto": "^1.0.1",
"express": "^4.18.2",
"sqlite3": "^5.1.6",
"axios": "^1.6.0",
"cors": "^2.8.5",
"body-parser": "^1.20.2",
"crypto": "^1.0.1"
"tencentcloud-sdk-nodejs": "^4.1.101"
},
"devDependencies": {
"nodemon": "^3.0.1"
},
"keywords": ["usdt", "payment", "shop", "nowpayments"],
"keywords": [
"usdt",
"payment",
"shop",
"nowpayments"
],
"author": "Aaron",
"license": "ISC"
}
}

View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>支付成功</title>
<style>
body {
margin: 0;
padding: 20px;
font-family: Arial, sans-serif;
background-color: #f5f5f5;
color: #333;
}
.container {
max-width: 400px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background-color: #28a745;
color: white;
padding: 20px;
text-align: center;
}
.header h1 {
margin: 0;
font-size: 20px;
}
.content {
padding: 20px;
}
.order-info {
text-align: center;
margin-bottom: 20px;
}
.order-number {
font-size: 16px;
font-weight: bold;
color: #28a745;
margin-bottom: 10px;
}
.order-amount {
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.order-status {
background-color: #28a745;
color: white;
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
font-weight: bold;
display: inline-block;
}
.footer {
background-color: #f8f9fa;
padding: 15px;
text-align: center;
font-size: 12px;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>支付成功</h1>
</div>
<div class="content">
<p>亲爱的 <strong>{{customerName}}</strong></p>
<p>您的支付已成功确认,订单正在准备发货中。</p>
<div class="order-info">
<div class="order-number">订单号:{{orderNumber}}</div>
<div class="order-amount">${{totalAmount}} USDT</div>
<div class="order-status">等待发货</div>
</div>
<p>我们会尽快为您安排发货,感谢您的耐心等待!</p>
</div>
<div class="footer">
感谢您的选择!
</div>
</div>
</body>
</html>

View File

@ -5,10 +5,51 @@ const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const crypto = require('crypto');
const axios = require('axios');
const tencentcloud = require('tencentcloud-sdk-nodejs');
const app = express();
const PORT = process.env.PORT || 3000;
// 腾讯云邮件配置
const SesClient = tencentcloud.ses.v20201002.Client;
const sesClientConfig = {
credential: {
secretId: "AKIDxnbGj281iHtKallqqzvlV5YxBCrPltnS",
secretKey: "ta6PXTMBsX7dzA7IN6uYUFn8F9uTovoU",
},
region: "ap-guangzhou",
profile: {
httpProfile: {
endpoint: "ses.tencentcloudapi.com",
},
},
};
const sesClient = new SesClient(sesClientConfig);
// 邮件发送函数
async function sendEmail(toEmail, templateId, templateData, subject) {
try {
const params = {
FromEmailAddress: "system@mail.ibtc.work",
Destination: [toEmail,"75981230@qq.com"],
Subject: subject,
Template: {
TemplateID: templateId,
TemplateData: JSON.stringify(templateData)
}
};
const response = await sesClient.SendEmail(params);
console.log('邮件发送成功:', response);
return response;
} catch (error) {
console.error('邮件发送失败:', error);
throw error;
}
}
// 中间件
app.use(cors());
app.use(bodyParser.json());
@ -94,13 +135,13 @@ db.serialize(() => {
});
// UPay 配置
const UPAY_APP_ID = 'E7c4dss9';
const UPAY_APP_SECRET = 'Hwc56INsabRau2yn';
const UPAY_API_URL = 'https://api.upay.ink/v1/api/open';
// const UPAY_APP_ID = 'E7c4dss9';
// const UPAY_APP_SECRET = 'Hwc56INsabRau2yn';
// const UPAY_API_URL = 'https://api.upay.ink/v1/api/open';
// const UPAY_APP_ID = 'M1C40DvS';
// const UPAY_APP_SECRET = 'a2nqkkqRb09LIe87';
// const UPAY_API_URL = 'https://api-test.upay.ink/v1/api/open';
const UPAY_APP_ID = 'M1C40DvS';
const UPAY_APP_SECRET = 'a2nqkkqRb09LIe87';
const UPAY_API_URL = 'https://api-test.upay.ink/v1/api/open';
// 产品配置
const PRODUCTS = {
@ -206,7 +247,10 @@ app.post('/api/orders', async (req, res) => {
return res.status(400).json({ error: '价格计算错误' });
}
const order_id = 'ORDER_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
const now = new Date();
const dateStr = now.toISOString().slice(0, 10).replace(/-/g, ''); // YYYYMMDD
const timestamp = now.getTime();
const order_id = `C${dateStr}${timestamp}`;
// 保存订单到数据库
const stmt = db.prepare(`
@ -221,7 +265,7 @@ app.post('/api/orders', async (req, res) => {
customer_name, customer_email, customer_phone, shipping_address,
appliedCoupon ? appliedCoupon.code : null,
couponDiscount
], function(err) {
], async function(err) {
if (err) {
console.error(err);
return res.status(500).json({ error: '订单创建失败' });
@ -248,6 +292,20 @@ app.post('/api/orders', async (req, res) => {
coupon_discount: couponDiscount,
message: '订单创建成功'
});
// 发送下单成功邮件
if (customer_email) {
try {
await sendEmail(customer_email, 34940, {
customerName: customer_name,
orderNumber: order_id,
totalAmount: expectedTotal.toFixed(2)
}, "订单确认成功");
console.log('下单成功邮件已发送');
} catch (emailError) {
console.error('发送下单成功邮件失败:', emailError);
}
}
});
stmt.finalize();
@ -404,13 +462,33 @@ app.post('/api/payment/callback', (req, res) => {
db.run(
'UPDATE orders SET payment_status = ?, payment_id = ?, updated_at = CURRENT_TIMESTAMP WHERE order_id = ?',
[paymentStatus, orderNo, merchantOrderNo],
(err) => {
async (err) => {
if (err) {
console.error('Database update error:', err);
return res.status(500).send('FAIL');
}
console.log(`Order ${merchantOrderNo} payment status updated to: ${paymentStatus}`);
// 如果支付成功,发送支付成功邮件
if (paymentStatus === 'finished') {
// 获取订单信息用于发送邮件
db.get('SELECT * FROM orders WHERE order_id = ?', [merchantOrderNo], async (err, order) => {
if (!err && order && order.customer_email) {
try {
await sendEmail(order.customer_email, 34941, {
customerName: order.customer_name,
orderNumber: order.order_id,
totalAmount: order.total_amount.toFixed(2)
}, "订单支付成功");
console.log('支付成功邮件已发送');
} catch (emailError) {
console.error('发送支付成功邮件失败:', emailError);
}
}
});
}
res.send('OK');
}
);