Files
2026-06-03 14:15:55 +08:00

88 lines
2.3 KiB
JavaScript

const fetch = require('node-fetch')
const APPID = process.env.WECHAT_APPID
const SECRET = process.env.WECHAT_SECRET
let accessToken = null
let tokenExpiresAt = 0
async function getAccessToken() {
if (!APPID || !SECRET) {
throw new Error('WECHAT_APPID and WECHAT_SECRET must be configured in .env')
}
if (accessToken && Date.now() < tokenExpiresAt) {
return accessToken
}
const res = await fetch(
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${SECRET}`
)
const data = await res.json()
if (data.errcode) {
throw new Error(`微信API错误: ${data.errmsg}`)
}
accessToken = data.access_token
tokenExpiresAt = Date.now() + (data.expires_in - 300) * 1000
return accessToken
}
async function sendSubscribeMessage(openid, templateId, data, page = '') {
const token = await getAccessToken()
const body = {
touser: openid,
template_id: templateId,
page,
data,
miniprogram_state: 'formal'
}
const res = await fetch(
`https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=${token}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
}
)
const result = await res.json()
if (result.errcode && result.errcode !== 0) {
console.error('发送订阅消息失败:', result)
return { success: false, error: result.errmsg }
}
return { success: true }
}
async function sendOrderStatusNotification(openid, orderId, status, totalPrice) {
const statusText = {
paid: '已付款',
completed: '已完成',
cancelled: '已取消'
}
const templateId = process.env.WECHAT_ORDER_TEMPLATE_ID
if (!templateId) {
console.warn('WECHAT_ORDER_TEMPLATE_ID not configured, skipping notification')
return { success: false, error: 'template not configured' }
}
return sendSubscribeMessage(openid, templateId, {
thing1: { value: `订单 ${orderId}` },
phrase2: { value: statusText[status] || status },
amount3: { value: `¥${totalPrice}` },
date4: { value: new Date().toLocaleString('zh-CN') },
thing5: { value: '点击查看订单详情' }
}, `/pages/customer-extra/order-detail/order-detail?id=${orderId}`)
}
module.exports = {
getAccessToken,
sendSubscribeMessage,
sendOrderStatusNotification
}