211 lines
7.1 KiB
TypeScript
211 lines
7.1 KiB
TypeScript
import cloud from '@lafjs/cloud';
|
||
import * as JungleConfigModule from "@/jungleConfig";
|
||
const JungleConfig: any = JungleConfigModule as any;
|
||
const db = cloud.database();
|
||
const ThinkingData = require('thinkingdata-node');
|
||
export default async function (ctx: FunctionContext) {
|
||
let data: any;
|
||
try {
|
||
data = JSON.parse(ctx.body?.MiniGame?.Payload || "");
|
||
} catch {
|
||
console.error("微信发货回调 Payload 解析失败");
|
||
return { "ErrCode": -1, "ErrMsg": "Invalid Payload" };
|
||
}
|
||
|
||
const outTradeNo = String(data.OutTradeNo || "");
|
||
const orderResult = await db.collection("order").where({ outTradeNo }).getOne();
|
||
const order = orderResult.data;
|
||
if (!order) {
|
||
console.error("微信发货回调未找到订单:" + outTradeNo);
|
||
return { "ErrCode": -1, "ErrMsg": "Order Not Found" };
|
||
}
|
||
|
||
const jungleTier = JungleConfig.getJunglePaidTierByProductId(order.itemid);
|
||
if (jungleTier) {
|
||
const callbackProductId = String(data.GoodsInfo?.ProductId || "");
|
||
const callbackQuantity = Number(data.GoodsInfo?.Quantity);
|
||
const callbackOriginalPrice = Number(data.GoodsInfo?.OrigPrice);
|
||
if ((data.OpenId && data.OpenId !== order.openid)
|
||
|| (callbackProductId && callbackProductId !== order.itemid)
|
||
|| (Number.isFinite(callbackQuantity) && callbackQuantity !== Number(order.itemCount))
|
||
|| (Number.isFinite(callbackOriginalPrice) && callbackOriginalPrice !== Number(order.goodsPrice))) {
|
||
console.error("Jungle 支付回调与订单信息不一致:" + outTradeNo);
|
||
return { "ErrCode": -1, "ErrMsg": "Order Mismatch" };
|
||
}
|
||
}
|
||
|
||
const userResult = await db.collection("users").where({ openid: order.openid }).getOne();
|
||
const user = userResult.data;
|
||
if (!user) {
|
||
console.error("微信发货回调未找到玩家:" + order.openid);
|
||
return { "ErrCode": -1, "ErrMsg": "User Not Found" };
|
||
}
|
||
|
||
const firstPaidCallback = order.state === 0;
|
||
if (order.state !== 2) {
|
||
await db.collection("order").where({ outTradeNo }).update({
|
||
state: 1,
|
||
chargeTime: new Date(Date.now() + 8 * 3600000),
|
||
});
|
||
}
|
||
|
||
const userUpdate: any = {};
|
||
let jungleUnlockedFromLocked = false;
|
||
if (jungleTier) {
|
||
const storedState = JungleConfig.normalizeStoredJungleState(user.jungleTreasureState);
|
||
const wasLocked = Number(storedState?.tierStates?.[jungleTier.id - 1]) === 0;
|
||
const unlockResult = JungleConfig.unlockJungleTierByProductId(
|
||
user.jungleTreasureState,
|
||
order.itemid,
|
||
outTradeNo,
|
||
);
|
||
if (unlockResult.ok && unlockResult.changed && unlockResult.state) {
|
||
userUpdate.jungleTreasureState = JungleConfig.serializeJungleState(unlockResult.state);
|
||
jungleUnlockedFromLocked = wasLocked
|
||
&& Number(unlockResult.state.tierStates?.[jungleTier.id - 1]) === 1;
|
||
}
|
||
}
|
||
|
||
if (order.itemid === "starter_pack") {
|
||
userUpdate.starter_packState = 1;
|
||
}
|
||
if (!user.pay_user) {
|
||
userUpdate.pay_user = true;
|
||
}
|
||
if (Object.keys(userUpdate).length > 0) {
|
||
await db.collection("users").where({ _id: user._id }).update(userUpdate);
|
||
}
|
||
if (firstPaidCallback) {
|
||
await sead(order, user, getClientIp(ctx));
|
||
}
|
||
if (jungleTier && jungleUnlockedFromLocked) {
|
||
await db.collection("order").where({ outTradeNo }).update({
|
||
state: 2,
|
||
getTime: new Date(Date.now() + 8 * 3600000),
|
||
});
|
||
}
|
||
|
||
// let query={
|
||
// signature: '1c1b5c1c72058436e2f1214e6aeafd258e50acd4',
|
||
// timestamp: '1751291889',
|
||
// nonce: '3122546041'
|
||
// }
|
||
/**
|
||
* ToUserName: 'gh_1092576a6ce7',
|
||
FromUserName: 'orm8I7IA-pMesygmTc5HPufGZHvA',
|
||
CreateTime: 1751292233,
|
||
MsgType: 'event',
|
||
MiniGame: {
|
||
Payload: '{"OpenId":"orm8I7BRTjhdQ3Mz9V9cg1jzTUcQ","OutTradeNo":"wcx_92778691620421751292218408","WeChatPayInfo":{"MchOrderNo":"20250630714915544","TransactionId":"4200002678202506307565098431"},"Env":0,"GoodsInfo":{"ProductId":"10011","Quantity":1,"ZoneId":"1","OrigPrice":100,"ActualPrice":100,"Attach":"购买道具","OrderSource":1},"PayChannel":0}',
|
||
PayEventSig: 'ecdaf472c239894706e28ab941d2aebf727b5bed45fe4073c645e922b6eefc1a',
|
||
IsMock: false
|
||
},
|
||
Event: 'minigame_game_pay_goods_deliver_notify'
|
||
*/
|
||
//return ctx.query.echostr;
|
||
return { "ErrCode": 0, "ErrMsg": "Success" };
|
||
|
||
}
|
||
|
||
async function sead1(outTradeNo) {
|
||
let res = await db.collection("order").where({ outTradeNo: outTradeNo }).getOne();
|
||
if (res.data.state == 1) {
|
||
return {
|
||
code: 1, data: {
|
||
pay_state: 2
|
||
}, msg: "成功"
|
||
};
|
||
} else if (res.data.state == 2) {
|
||
let userInfo = await db.collection("users").where({ openid: res.data.openid }).getOne();
|
||
await sead(outTradeNo, userInfo.data, "")
|
||
console.log("1");
|
||
return {
|
||
code: 1, data: {
|
||
pay_state: 1,
|
||
}, msg: "已领取奖励"
|
||
}
|
||
} else {
|
||
return {
|
||
code: 1, data: {
|
||
pay_state: 1,
|
||
}, msg: "充值未成功"
|
||
}
|
||
};
|
||
}
|
||
|
||
const getClientIp = (req) => {
|
||
return (
|
||
req.headers['x-forwarded-for']?.split(',')[0]?.trim() || // 代理链中的第一个 IP
|
||
req.headers['x-real-ip'] || // Nginx 配置的 real-ip
|
||
req.socket.remoteAddress // 原始 IP(可能是代理)
|
||
);
|
||
};
|
||
|
||
|
||
async function sead(order, userInfo, ip) {
|
||
db.collection("susu").add({
|
||
order: order,
|
||
time: Date.now()
|
||
});
|
||
if (!userInfo.distinctId) {
|
||
console.log("未找到distinctId无法上传数数")
|
||
return;
|
||
}
|
||
let id = '95993f9ab6f1402a87abe5147827e5e0';
|
||
if (userInfo.isDebug != "true") {
|
||
id = '40e3d5c5f2af49a4a074205564ce5dbb';
|
||
}
|
||
let teSDK = ThinkingData.initWithBatchMode(id, 'https://data.nika4fun.com/sync_data', {
|
||
dryRun: false, // report data to TE or not
|
||
deviceId: "123456789",//设备唯一标识
|
||
});
|
||
let trackEvent = {
|
||
accountId: order.openid,
|
||
distinctId: userInfo.distinctId,//访客id
|
||
event: 'payment',
|
||
time: new Date(Date.now() + 8 * 3600000),
|
||
ip: ip,
|
||
properties: {
|
||
order_id: order.outTradeNo,
|
||
pay_amount: order.goodsPrice,
|
||
payment_name: order.itemid,
|
||
payment_num: order.itemCount,
|
||
payment_type: order.type == "ios" ? "ios" : "Android",
|
||
is_on_table: Number(userInfo.addLevel) >= 5,
|
||
current_level: userInfo.levelAmount, //当前关卡等级 number
|
||
current_health: userInfo.healthAmount, //当前体力值
|
||
tmp_coin: userInfo.coinAmount,//当前金币
|
||
version: "1.6",
|
||
user_id: userInfo._id, //用户id
|
||
pay_user: userInfo.pay_user,
|
||
register_time: userInfo.register_time,
|
||
abTest_layer_one: getABTestGroupValue(userInfo.abTests, "layer_1"),
|
||
abTest_layer_two: getABTestGroupValue(userInfo.abTests, "layer_2"),
|
||
abTest_layer_three: getABTestGroupValue(userInfo.abTests, "layer_3")
|
||
},
|
||
callback(e) {
|
||
if (e) {
|
||
}
|
||
}
|
||
};
|
||
teSDK.track(trackEvent);
|
||
teSDK.close();
|
||
return;
|
||
}
|
||
|
||
function getABTestGroupValue(abTests: any, layerKey: string) {
|
||
if (!abTests) {
|
||
return 0;
|
||
}
|
||
if (typeof abTests === "string") {
|
||
try {
|
||
abTests = JSON.parse(abTests);
|
||
} catch {
|
||
return 0;
|
||
}
|
||
}
|
||
const groupMap = { A: 1, B: 2, C: 3, D: 4, E: 5 };
|
||
const group = String(abTests[layerKey]?.group || "").toUpperCase();
|
||
return groupMap[group] || 0;
|
||
}
|