MatchMaster/server/laf-cloud/functions/wx/KeFuInfo.ts
COMPUTER\EDY ae2a1feccb 已更新
2026-07-10 19:44:29 +08:00

235 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cloud from '@lafjs/cloud'
const token = "nika123";
const EncodingAESKey = "XcdOFaZOQjmyBqYHxWAITtrmq11YaZQ63DeEZAAgYJt";
const mchid = "1719895437";//商户id
const serialNo = "2A97ED6ED441E55600EBC8830B9EC889ED41496E";//证书序列号
const appid = "wx30f74367b3d3e7a6";
import crypto from 'crypto';
const db = cloud.database();
export default async function (ctx: FunctionContext) {
console.log(ctx.body);
//console.log(ctx.query);;
try {
let openid = ctx.body.FromUserName;
//console.log(openid);
const data = JSON.parse(ctx.body.SessionFrom);
//console.log(data);
console.log(data);
if (data.tpye == "ios") {
await PostMsg(openid, "点击下方页面进行充值");
await PostImg(openid, data.outTradeNo, data.propName, data.count, data.price);
}
} catch (e) {
console.error("ios客服充值参数错误" + ctx.body.SessionFrom);
console.log(ctx.body);
}
//return ctx.query.echostr;
return { data: "scuess" };
}
/**获取订单*/
async function getOrder(openid, toatal, outTradeNo, timestamp, nonceStr) {
const url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
// 生成随机字符串和时间戳
const body = {
"appid": appid,
"mchid": mchid,
"description": "消消王者道具购买",
"out_trade_no": outTradeNo,
"notify_url": "https://q6rvwvtnga.sealoshzh.site/wx/iosPayCall",
"amount": { "total": Number(toatal), "currency": "CNY" },
"payer": { "openid": openid }
}
let ret = await sign(nonceStr, timestamp, body);
const res = await fetch(url, {
method: 'POST',
headers: {
'Authorization': ret,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(body)
})
if (res.ok) {
const data = await res.json().catch(async () => {
//如果不是JSON尝试读取文本
return await res.text().catch(() => 'Empty response');
});
return data.prepay_id;
}
return null;
}
async function sign(nonceStr, timestamp, body) {
const data = `POST\n/v3/pay/transactions/jsapi\n${timestamp}\n${nonceStr}\n${JSON.stringify(body)}\n`;
// 创建签名对象
const sign = crypto.createSign('RSA-SHA256');
// 更新签名内容
sign.update(data);
// 获取存储桶
const bucket = cloud.storage.bucket('j3k323ol-colorblock-oss');
// 获取文件列表
const res = await bucket.readFile('apiclient_key.pem');
const privateKeyPem = await res.Body.transformToString();
// 使用私钥签名PKCS1 填充)
const signature = sign.sign({
key: privateKeyPem,
padding: crypto.constants.RSA_PKCS1_PADDING
}, 'base64');
// 构建Authorization头
const authorization = `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",nonce_str="${nonceStr}",signature="${signature}",timestamp="${timestamp}",serial_no="${serialNo}"`;
return authorization;
}
/**前端签名*/
async function frontsign(data) {
// 创建签名对象
const sign = crypto.createSign('RSA-SHA256');
// 更新签名内容
sign.update(data);
// 获取存储桶
const bucket = cloud.storage.bucket('j3k323ol-colorblock-oss');
// 获取文件列表
const res = await bucket.readFile('apiclient_key.pem');
const privateKeyPem = await res.Body.transformToString();
//console.error(privateKeyPem);
// 使用私钥签名PKCS1 填充)
const signature = sign.sign({
key: privateKeyPem,
padding: crypto.constants.RSA_PKCS1_PADDING
}, 'base64');
// 构建Authorization头
return signature
}
const propName = {
gold_1: "金币包1",
gold_2: "金币包2",
gold_3: "金币包3",
gold_4: "金币包4",
gold_5: "金币包5",
gold_6: "金币包6",
unlimited_health_bundle_1: "无限体力组合包1",
unlimited_health_bundle_2: "无限体力组合包2",
unlimited_health_bundle_3: "无限体力组合包3",
freeze_in_game: "局内购买冻结",
hammer_in_game: "局内购买锤子",
wand_in_gamerefill: "局内购买魔棒",
health: "补满体力"
};
async function PostMsg(OpenId, msg) {
let token = cloud.shared.get('wxaccess_token');
if (!token) {
return { code: 0, data: null, msg: "token获取失败" };
}
const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`;
const data = {
"touser": OpenId,
"msgtype": "text",
"text":
{
"content": msg
}
}
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(data)
})
return "ok"
}
async function PostImg(OpenId, outTradeNo, name, count, price) {
let token = cloud.shared.get('wxaccess_token');
if (!token) {
return { code: 0, data: null, msg: "token获取失败" };
}
const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`;
const nonceStr = crypto.randomBytes(16).toString('hex');
const timestamp = Math.floor(Date.now() / 1000).toString();
const total = count * price;
let prepay_id = await getOrder(OpenId, total, outTradeNo, timestamp, nonceStr);
let frontBody = {
"appId": appid, //公众号ID由商户传入
"timeStamp": timestamp, //时间戳自1970年以来的秒数
"nonceStr": nonceStr, //随机串
"package": "prepay_id=" + prepay_id
}
const data1 = `${frontBody.appId}\n${frontBody.timeStamp}\n${frontBody.nonceStr}\n${frontBody.package}\n`;
let paySign = await frontsign(data1);
let user = await db.collection("users").where({ openid: OpenId }).update({ iosTime: frontBody.timeStamp });
let param = {
name: propName[name],
openid: OpenId,
outTradeNo: outTradeNo,
time: timestamp,
quantity: count,
price: price,
body: {
"appId": frontBody.appId, //公众号ID由商户传入
"timeStamp": frontBody.timeStamp, //时间戳自1970年以来的秒数
"nonceStr": frontBody.nonceStr, //随机串
"package": frontBody.package,
"signType": "RSA", //微信签名方式:
"paySign": paySign //微信签名
}
}
await db.collection("iosOrder").add({
openid: OpenId,
outTradeNo: outTradeNo,
itemid: name,
itemCount: count,
goodsPrice: Number(price),
time: Date.now(),
orderTime: new Date(Date.now() + 8 * 3600000),
chargeTime: 0,
getTime: 0,
type: "ios",
state: 0,
});
const data = {
"touser": OpenId,
"msgtype": "link",
"link": {
"title": "点我支付",
"description": "金额:" + (total / 100).toFixed(2) + "元",
"url": `https://pay.nika4games.com/order3.html#data=${encodeURIComponent(JSON.stringify(param))}`,
"thumb_url": "https://static-host-j3k323ol-colorblock-oss.sealoshzh.site/icon.jpg"
}
}
//console.log(data);
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(data)
})
const data11 = await res.json();
console.log(data11);
if (data11.errcode == 40001) {
console.error("未获取到正确token,重新发送请求");
let res = await getWxToken();
await PostMsg(OpenId, "点击下方页面进行充值");
await PostImg(OpenId, outTradeNo, name, count, price);
}
return "ok"
}
/**获取微信Token*/
async function getWxToken() {
const api_url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${appsecret}`;
const ret = await cloud.fetch({
url: api_url,
method: "get",
});
if (ret?.data?.access_token) {
cloud.shared.set('wxaccess_token', ret.data.access_token);
return ret.data.access_token;
} else {
//access_token = nul l;
return null;
}
}