From 30fa25f206d49f6d559b1966fb0550fc828babd8 Mon Sep 17 00:00:00 2001
From: aaron <>
Date: Tue, 19 Aug 2025 11:52:31 +0800
Subject: [PATCH] update
---
order-success-email-template.html | 94 ++++++++++++++++++++++++++++
package.json | 18 ++++--
payment-success-email-template.html | 94 ++++++++++++++++++++++++++++
server.js | 96 ++++++++++++++++++++++++++---
4 files changed, 287 insertions(+), 15 deletions(-)
create mode 100644 order-success-email-template.html
create mode 100644 payment-success-email-template.html
diff --git a/order-success-email-template.html b/order-success-email-template.html
new file mode 100644
index 0000000..77da9ee
--- /dev/null
+++ b/order-success-email-template.html
@@ -0,0 +1,94 @@
+
+
+
+
+
+ 订单确认
+
+
+
+
+
+
+
+
亲爱的 {{customerName}},
+
您的订单已成功提交,请及时完成支付。
+
+
+
订单号:{{orderNumber}}
+
${{totalAmount}} USDT
+
等待支付
+
+
+
感谢您选择我们的服务!
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index dda5dd5..32f4477 100644
--- a/package.json
+++ b/package.json
@@ -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"
-}
\ No newline at end of file
+}
diff --git a/payment-success-email-template.html b/payment-success-email-template.html
new file mode 100644
index 0000000..655367b
--- /dev/null
+++ b/payment-success-email-template.html
@@ -0,0 +1,94 @@
+
+
+
+
+
+ 支付成功
+
+
+
+
+
+
+
+
亲爱的 {{customerName}},
+
您的支付已成功确认,订单正在准备发货中。
+
+
+
订单号:{{orderNumber}}
+
${{totalAmount}} USDT
+
等待发货
+
+
+
我们会尽快为您安排发货,感谢您的耐心等待!
+
+
+
+
+
+
\ No newline at end of file
diff --git a/server.js b/server.js
index 76cd01c..293e246 100644
--- a/server.js
+++ b/server.js
@@ -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');
}
);