feat: add per-run reborn gift price tiers
This commit is contained in:
@@ -2648,7 +2648,7 @@ export default class JiaZai extends cc.Component {
|
||||
if (order.itemid == "gold_1" || order.itemid == "gold_2" || order.itemid == "gold_3"
|
||||
|| order.itemid == "gold_4" || order.itemid == "gold_5" || order.itemid == "gold_6"
|
||||
|| order.itemid == "unlimited_health_bundle_10" || order.itemid == "unlimited_health_bundle_20"
|
||||
|| order.itemid == "unlimited_health_bundle_30" || order.itemid == "month_Card" || order.itemid == "reborn_Gift"
|
||||
|| order.itemid == "unlimited_health_bundle_30" || order.itemid == "month_Card" || /^reborn_Gift(?:_[2-5])?$/.test(order.itemid)
|
||||
|| order.itemid == "starter_pack" || order.itemid == "battlepass"
|
||||
) {
|
||||
if (canUpdateHome()) this.openLoad();
|
||||
@@ -2678,7 +2678,7 @@ export default class JiaZai extends cc.Component {
|
||||
if (canUpdateHome()) this.openLoad();
|
||||
this.buyMonthCard(productId, order.outTradeNo);
|
||||
}
|
||||
else if (order.itemid == "reborn_Gift") {
|
||||
else if (/^reborn_Gift(?:_[2-5])?$/.test(order.itemid)) {
|
||||
coinTemp = 1000;
|
||||
}
|
||||
else if (order.itemid == "starter_pack") {
|
||||
@@ -2695,7 +2695,7 @@ export default class JiaZai extends cc.Component {
|
||||
let title = "充值补发奖励金币:" + coinTemp;
|
||||
// MiniGameSdk.API.showToast(title);
|
||||
if (order.itemid != "month_Card")
|
||||
cc.fx.GameTool.shopBuy(productId, true, productId === "starter_pack" ? { outTradeNo: order.outTradeNo } : null);
|
||||
cc.fx.GameTool.shopBuy(productId, true, productId === "starter_pack" || /^reborn_Gift(?:_[2-5])?$/.test(productId) ? { outTradeNo: order.outTradeNo } : null);
|
||||
// console.log("充值成功获得金币");
|
||||
let price = parseInt(order.goodsPrice) || 0;
|
||||
// const dataSuccess = {
|
||||
|
||||
@@ -283,6 +283,21 @@ export default class MapConroler extends cc.Component {
|
||||
// 6. 获取场景管理器引用
|
||||
// 7. 获取城市排行榜数据
|
||||
// ============================================
|
||||
// 本局成功购买的礼包次数,与金币复活次数 review 独立;重建关卡时归零。
|
||||
rebornGiftCount: number = 0;
|
||||
private rebornGiftOrders: Set<string> = new Set();
|
||||
|
||||
recordRebornGiftPurchase(order: string) {
|
||||
if (!order || this.rebornGiftOrders.has(order)) return;
|
||||
this.rebornGiftOrders.add(order);
|
||||
this.rebornGiftCount++;
|
||||
}
|
||||
|
||||
getRebornGiftProduct() {
|
||||
const tier = Math.min(this.rebornGiftCount, 4);
|
||||
return { id: tier === 0 ? "reborn_Gift" : "reborn_Gift_" + (tier + 1), price: [600, 800, 1000, 1200, 1500][tier] };
|
||||
}
|
||||
|
||||
onLoad() {
|
||||
// 测试开关开启时,每次进关都从十连胜开始。
|
||||
if (cc.fx.GameConfig.forceRainbowWinStreakB) {
|
||||
|
||||
+87
-41
@@ -25,6 +25,9 @@ export default class Revive extends cc.Component {
|
||||
private iosPrice: number = 0;
|
||||
private iosProductId: string = "";
|
||||
private iosCount: number = 1;
|
||||
private iosMap: MapConroler = null;
|
||||
private iosUid: string = "";
|
||||
private checkingIosOrder: boolean = false;
|
||||
public home: number = 0;
|
||||
|
||||
onLoad() {
|
||||
@@ -36,12 +39,18 @@ export default class Revive extends cc.Component {
|
||||
if (cc.sys.platform === cc.sys.WECHAT_GAME || cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
|
||||
console.log("从后台进入前台订单号:", cc.fx.GameConfig.GM_INFO.iosReviveOrder);
|
||||
if (cc.fx.GameConfig.GM_INFO.iosReviveOrder != null && cc.fx.GameConfig.GM_INFO.iosReviveOrder != "") {
|
||||
if (this.checkingIosOrder) return;
|
||||
this.checkingIosOrder = true;
|
||||
console.log("有苹果订单号,开始轮训");
|
||||
const iosReviveOrder = cc.fx.GameConfig.GM_INFO.iosReviveOrder;
|
||||
this.openLoad();
|
||||
this.btn_Touch = true;
|
||||
this.btn_Touch = false;
|
||||
const purchaseMap = this.iosMap;
|
||||
const purchaseUid = this.iosUid || cc.fx.GameConfig.GM_INFO.uid;
|
||||
Utils.getIosPayInfo(iosReviveOrder,
|
||||
(data) => {
|
||||
this.checkingIosOrder = false;
|
||||
if (purchaseUid !== cc.fx.GameConfig.GM_INFO.uid) return;
|
||||
console.log("获得轮训结果:", data);
|
||||
const iosID = data.data?.payment_name || this.iosProductId;
|
||||
let iosAmount = data.data?.goodsPrice || this.iosPrice;
|
||||
@@ -55,12 +64,10 @@ export default class Revive extends cc.Component {
|
||||
this.btn_Touch = true;
|
||||
console.log("_________正式发货");
|
||||
MiniGameSdk.API.showToast("充值成功");
|
||||
cc.fx.GameTool.shopBuy(iosID, false);
|
||||
this.revivew()
|
||||
if (iosID == "reborn_Gift") {
|
||||
this.buyGift();
|
||||
}
|
||||
cc.fx.GameConfig.GM_INFO.iosReviveOrder = null;
|
||||
this.completePurchase(iosID, iosReviveOrder, purchaseMap, purchaseUid);
|
||||
Utils.setPayInfo(() => {}, iosReviveOrder);
|
||||
if (cc.fx.GameConfig.GM_INFO.iosReviveOrder === iosReviveOrder)
|
||||
cc.fx.GameConfig.GM_INFO.iosReviveOrder = null;
|
||||
//console.log("充值成功获得金币");
|
||||
this.updateGameCoin();
|
||||
|
||||
@@ -81,7 +88,8 @@ export default class Revive extends cc.Component {
|
||||
if (iosID != undefined && iosID != "" && iosID != null) {
|
||||
cc.fx.GameTool.shushu_Track("payment_fail", dataFail);
|
||||
}
|
||||
cc.fx.GameConfig.GM_INFO.iosReviveOrder = null;
|
||||
if (cc.fx.GameConfig.GM_INFO.iosReviveOrder === iosReviveOrder)
|
||||
cc.fx.GameConfig.GM_INFO.iosReviveOrder = null;
|
||||
}
|
||||
else if (data.code == 2) {
|
||||
this.closeLoad();
|
||||
@@ -112,10 +120,34 @@ export default class Revive extends cc.Component {
|
||||
return;
|
||||
}
|
||||
this.node.active = true;
|
||||
this.updatePrice();
|
||||
this.addListener();
|
||||
this.btn_Touch = true;
|
||||
}
|
||||
|
||||
private updatePrice() {
|
||||
const map = MapConroler._instance;
|
||||
const price = this.node.getChildByName("price");
|
||||
const label = price && price.getComponent(cc.Label);
|
||||
if (!map || !label) return;
|
||||
// 固定数字右边缘,让两位数向左展开,保留旁边独立的“元”节点。
|
||||
price.x += price.width * (1 - price.anchorX);
|
||||
price.anchorX = 1;
|
||||
label.string = String(map.getRebornGiftProduct().price / 100);
|
||||
}
|
||||
|
||||
private completePurchase(productId: string, order: string, purchaseMap: MapConroler, uid: string) {
|
||||
if (uid !== cc.fx.GameConfig.GM_INFO.uid || !order || !/^reborn_Gift(?:_[2-5])?$/.test(productId)) return;
|
||||
const currentRun = purchaseMap && cc.isValid(purchaseMap, true) && MapConroler._instance === purchaseMap;
|
||||
if (currentRun) purchaseMap.recordRebornGiftPurchase(order);
|
||||
if (cc.fx.GameTool.shopBuy(productId, false, { outTradeNo: order }) === false) return;
|
||||
this.buyGift();
|
||||
// 旧局订单仍发奖励,但不能复活新局或提高新局的礼包价格。
|
||||
if (currentRun) {
|
||||
this.revivew(purchaseMap);
|
||||
}
|
||||
}
|
||||
|
||||
addListener() {
|
||||
if (cc.sys.platform === cc.sys.WECHAT_GAME || cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
|
||||
if (this.onShowListener) {
|
||||
@@ -141,9 +173,8 @@ export default class Revive extends cc.Component {
|
||||
// update (dt) {}
|
||||
}
|
||||
//发奖励
|
||||
revivew() {
|
||||
revivew(map: MapConroler) {
|
||||
cc.fx.GameConfig.GM_INFO.revive = 0;
|
||||
const map = MapConroler && MapConroler._instance;
|
||||
if (map) map.setPropNum();
|
||||
const jiazaiNode = cc.find("Canvas"); // 假设 JiaZai 挂在 Canvas 节点
|
||||
const jiazaiComp = jiazaiNode && jiazaiNode.getComponent(JiaZai);
|
||||
@@ -166,7 +197,7 @@ export default class Revive extends cc.Component {
|
||||
this.node.active = false;
|
||||
}
|
||||
}, 200);
|
||||
if (map && cc.isValid(map)) map.runRewiveCopy(false);
|
||||
if (map && cc.isValid(map)) map.runRewiveCopy();
|
||||
}
|
||||
buyProduct(customData) {
|
||||
// cc.fx.GameTool.shopBuy("revive", false);
|
||||
@@ -174,17 +205,19 @@ export default class Revive extends cc.Component {
|
||||
if (!this.btn_Touch) {
|
||||
return;
|
||||
}
|
||||
this.btn_Touch = false;
|
||||
const productId = "reborn_Gift";
|
||||
let id = "10011";
|
||||
let price = 100;
|
||||
let count = 1;
|
||||
id = productId;
|
||||
switch (productId) {
|
||||
case "reborn_Gift":
|
||||
price = 600;
|
||||
break;
|
||||
if (cc.fx.GameConfig.GM_INFO.iosReviveOrder) {
|
||||
this.onShow();
|
||||
return;
|
||||
}
|
||||
const purchaseMap = MapConroler._instance;
|
||||
if (!purchaseMap || !cc.isValid(purchaseMap, true)) return;
|
||||
const purchaseUid = cc.fx.GameConfig.GM_INFO.uid;
|
||||
this.btn_Touch = false;
|
||||
const product = purchaseMap.getRebornGiftProduct();
|
||||
const productId = product.id;
|
||||
const id = productId;
|
||||
const price = product.price;
|
||||
const count = 1;
|
||||
console.log("获得商品id:", id, count, price);
|
||||
// 判断设备系统
|
||||
let systemType = "Android";
|
||||
@@ -203,8 +236,7 @@ export default class Revive extends cc.Component {
|
||||
// MiniGameSdk.API.showToast("IOS系统暂不支持支付");
|
||||
// this.btn_Touch = true;
|
||||
this.openLoad();
|
||||
this.btn_Touch = true;
|
||||
this.iosOldPay(price, productId);
|
||||
this.iosOldPay(price, productId, purchaseMap, purchaseUid);
|
||||
}
|
||||
else {
|
||||
// MiniGameSdk.API.showToast("充值成功");
|
||||
@@ -220,9 +252,9 @@ export default class Revive extends cc.Component {
|
||||
// }, 500);
|
||||
|
||||
this.openLoad();
|
||||
this.btn_Touch = true;
|
||||
console.log("7.14_____________________", "调用充值接口");
|
||||
Utils.buyProp(id, count, price, systemType, productId, (res) => {
|
||||
if (purchaseUid !== cc.fx.GameConfig.GM_INFO.uid) return;
|
||||
console.log("获得充值结果", res);
|
||||
if (res == null) {
|
||||
MiniGameSdk.API.showToast("充值失败");
|
||||
@@ -243,7 +275,7 @@ export default class Revive extends cc.Component {
|
||||
console.log("错误原因:", res.errMsg);
|
||||
if (res.errCode == 16) {
|
||||
// console.log("走ios旧支付");
|
||||
this.iosOldPay(price, productId);
|
||||
this.iosOldPay(price, productId, purchaseMap, purchaseUid);
|
||||
return;
|
||||
}
|
||||
MiniGameSdk.API.showToast("充值失败");
|
||||
@@ -266,7 +298,15 @@ export default class Revive extends cc.Component {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
const orderNumber = res.outTradeNo;
|
||||
if (!orderNumber) {
|
||||
this.btn_Touch = true;
|
||||
this.closeLoad();
|
||||
MiniGameSdk.API.showToast("未获取到充值订单,请稍后重试");
|
||||
return;
|
||||
}
|
||||
Utils.getPayInfo((data) => {
|
||||
if (purchaseUid !== cc.fx.GameConfig.GM_INFO.uid) return;
|
||||
console.log("7.14_______________充值成功,准备轮训");
|
||||
console.log("获得轮训结果:", data);
|
||||
this.closeLoad();
|
||||
@@ -274,7 +314,7 @@ export default class Revive extends cc.Component {
|
||||
this.btn_Touch = true;
|
||||
MiniGameSdk.API.showToast("取消充值");
|
||||
const dataFail2 = {
|
||||
outTradeNo: Utils.outTradeNo,
|
||||
outTradeNo: orderNumber,
|
||||
pay_amount: price,
|
||||
payment_name: productId,
|
||||
payment_num: 1,
|
||||
@@ -284,7 +324,8 @@ export default class Revive extends cc.Component {
|
||||
cc.fx.GameTool.shushu_Track("payment_fail", dataFail2);
|
||||
}
|
||||
else if (data.data.pay_state == 2) {
|
||||
this.btn_Touch = true;
|
||||
if (cc.isValid(purchaseMap, true) && MapConroler._instance === purchaseMap)
|
||||
purchaseMap.recordRebornGiftPurchase(orderNumber);
|
||||
// const dataSuccess = {
|
||||
// outTradeNo: Utils.outTradeNo,
|
||||
// pay_amount: price,
|
||||
@@ -294,41 +335,40 @@ export default class Revive extends cc.Component {
|
||||
// }
|
||||
// cc.fx.GameTool.shushu_Track("payment", dataSuccess);
|
||||
let name = "购买金币道具:" + productId;
|
||||
console.log("引力付费透传", price, Utils.outTradeNo, name);
|
||||
MiniGameSdk.API.yinli_Pay(price, Utils.outTradeNo, name)
|
||||
console.log("引力付费透传", price, orderNumber, name);
|
||||
MiniGameSdk.API.yinli_Pay(price, orderNumber, name)
|
||||
console.log("7.14_______________充值成功,轮训成功,准备发货");
|
||||
this.completePurchase(productId, orderNumber, purchaseMap, purchaseUid);
|
||||
Utils.setPayInfo(
|
||||
(res) => {
|
||||
if (purchaseUid !== cc.fx.GameConfig.GM_INFO.uid) return;
|
||||
this.btn_Touch = true;
|
||||
console.log("设置轮训结果:", res);
|
||||
if (res.code === 1) {
|
||||
console.log("7.14_________正式发货");
|
||||
MiniGameSdk.API.showToast("充值成功");
|
||||
cc.fx.GameTool.shopBuy(productId, false);
|
||||
this.revivew();
|
||||
if (productId == "reborn_Gift") {
|
||||
this.buyGift();
|
||||
}
|
||||
//console.log("充值成功获得金币");
|
||||
}
|
||||
else {
|
||||
MiniGameSdk.API.showToast("网络异常,充值奖励将在登录后再次发放");
|
||||
MiniGameSdk.API.showToast("充值已到账,订单确认将在登录后重试");
|
||||
const dataFail4 = {
|
||||
outTradeNo: Utils.outTradeNo,
|
||||
outTradeNo: orderNumber,
|
||||
pay_amount: price,
|
||||
payment_name: productId,
|
||||
payment_num: 1,
|
||||
type: systemType,
|
||||
fail_reason: "成功付款,但是发货时请求服务器失败,充值成功未发货",
|
||||
fail_reason: "充值已到账,确认发货请求失败",
|
||||
}
|
||||
cc.fx.GameTool.shushu_Track("payment_fail", dataFail4);
|
||||
}
|
||||
this.updateGameCoin();
|
||||
}, Utils.outTradeNo)
|
||||
if (cc.isValid(this, true)) this.updatePrice();
|
||||
}, orderNumber)
|
||||
}
|
||||
else {
|
||||
|
||||
const dataFail3 = {
|
||||
outTradeNo: Utils.outTradeNo,
|
||||
outTradeNo: orderNumber,
|
||||
pay_amount: price,
|
||||
payment_name: productId,
|
||||
payment_num: 1,
|
||||
@@ -339,18 +379,20 @@ export default class Revive extends cc.Component {
|
||||
this.btn_Touch = true;
|
||||
this.updateGameCoin();
|
||||
}
|
||||
})
|
||||
}, orderNumber)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
openLoad() {
|
||||
if (!cc.isValid(this, true)) return;
|
||||
const canvas = cc.find("Canvas");
|
||||
const loading = canvas && canvas.getChildByName("Loading");
|
||||
if (loading) LoadingCatAnimation.play(loading);
|
||||
}
|
||||
|
||||
closeLoad() {
|
||||
if (!cc.isValid(this, true)) return;
|
||||
const canvas = cc.find("Canvas");
|
||||
const loading = canvas && canvas.getChildByName("Loading");
|
||||
if (loading) LoadingCatAnimation.stop(loading);
|
||||
@@ -407,7 +449,7 @@ export default class Revive extends cc.Component {
|
||||
this.onShow();
|
||||
}
|
||||
|
||||
iosOldPay(price, productId) {
|
||||
iosOldPay(price, productId, purchaseMap: MapConroler, uid: string) {
|
||||
// 旧版本ios支付
|
||||
let iosPayInfo = {
|
||||
price: price,
|
||||
@@ -417,6 +459,8 @@ export default class Revive extends cc.Component {
|
||||
this.iosPrice = price;
|
||||
this.iosProductId = productId;
|
||||
this.iosCount = 1;
|
||||
this.iosMap = purchaseMap;
|
||||
this.iosUid = uid;
|
||||
console.log("准备跳客服回话:");
|
||||
console.log(this.iosProductId);
|
||||
Utils.GoKEFu(iosPayInfo, (res) => {
|
||||
@@ -425,6 +469,8 @@ export default class Revive extends cc.Component {
|
||||
}
|
||||
else {
|
||||
console.log("客服回话失败");
|
||||
this.btn_Touch = true;
|
||||
cc.fx.GameConfig.GM_INFO.iosReviveOrder = null;
|
||||
this.closeLoad();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -253,7 +253,7 @@ export default class Utils {
|
||||
cc.fx.GameConfig.GM_INFO.iosMonthOrder = null;
|
||||
cc.fx.GameConfig.GM_INFO.iosMonthOrder = order;
|
||||
}
|
||||
else if (iosPayInfo.payment_name == "reborn_Gift") {
|
||||
else if (/^reborn_Gift(?:_[2-5])?$/.test(iosPayInfo.payment_name)) {
|
||||
cc.fx.GameConfig.GM_INFO.iosReviveOrder = null;
|
||||
cc.fx.GameConfig.GM_INFO.iosReviveOrder = order;
|
||||
}
|
||||
@@ -336,7 +336,7 @@ export default class Utils {
|
||||
const orderNow = order;
|
||||
console.log("请求uid:" + Utils.uid);
|
||||
console.log("outTradeNo:" + orderNow);
|
||||
Utils.POST("wx/iosgetPayInfo", { outTradeNo: orderNow, uid: cc.fx.GameConfig.GM_INFO.uid }, res => {
|
||||
Utils.POST("wx/iosgetPayInfo", { outTradeNo: orderNow, uid: cc.fx.GameConfig.GM_INFO.uid, rebornGiftVersion: 1 }, res => {
|
||||
console.log("查询字符结果IOS");
|
||||
console.log(res);
|
||||
// 清除超时定时器
|
||||
|
||||
@@ -999,6 +999,9 @@ var GameTool = {
|
||||
|
||||
//商城购买
|
||||
shopBuy(productId, compensate, orderContext: any = null) {
|
||||
const rebornOrderKey = /^reborn_Gift(?:_[2-5])?$/.test(productId) && orderContext?.outTradeNo
|
||||
? "RebornGiftGranted_" + cc.fx.GameConfig.GM_INFO.uid + "_" + orderContext.outTradeNo : "";
|
||||
if (rebornOrderKey && cc.fx.StorageMessage.getStorage(rebornOrderKey)) return false;
|
||||
const starterOrderKey = productId === "starter_pack" && orderContext?.outTradeNo
|
||||
? "StarterPackGranted_" + cc.fx.GameConfig.GM_INFO.uid + "_" + orderContext.outTradeNo : "";
|
||||
if (starterOrderKey && cc.fx.StorageMessage.getStorage(starterOrderKey)) return;
|
||||
@@ -1234,9 +1237,13 @@ var GameTool = {
|
||||
]
|
||||
break;
|
||||
case "reborn_Gift":
|
||||
case "reborn_Gift_2":
|
||||
case "reborn_Gift_3":
|
||||
case "reborn_Gift_4":
|
||||
case "reborn_Gift_5":
|
||||
cc.fx.GameTool.changeCoin(1000);
|
||||
coin = 1000;
|
||||
price = 600;
|
||||
price = { reborn_Gift: 600, reborn_Gift_2: 800, reborn_Gift_3: 1000, reborn_Gift_4: 1200, reborn_Gift_5: 1500 }[productId];
|
||||
rewardData = [
|
||||
{ type: "coin", count: coin },
|
||||
{ type: "freeze", count: 1 },
|
||||
@@ -1250,6 +1257,7 @@ var GameTool = {
|
||||
"price": price
|
||||
}
|
||||
this.getShopProp(propData3, compensate);
|
||||
if (rebornOrderKey) cc.fx.StorageMessage.setStorage(rebornOrderKey, true);
|
||||
break;
|
||||
case "starter_pack": {
|
||||
const reward = starterPackReward();
|
||||
|
||||
@@ -393,7 +393,7 @@ export default class NewClass extends cc.Component {
|
||||
const iosID = data.data?.payment_name || this.iosProductId;
|
||||
let iosAmount = data.data?.goodsPrice || this.iosPrice;
|
||||
iosAmount = parseInt(iosAmount);
|
||||
if (iosID == "reborn_Gift" || iosID == "month_Card" || iosID == "starter_pack") {
|
||||
if (/^reborn_Gift(?:_[2-5])?$/.test(iosID) || iosID == "month_Card" || iosID == "starter_pack") {
|
||||
console.log("商城检测到是月卡返回");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -476,6 +476,10 @@ async function getIosOrder(openid, ctx) {
|
||||
await db.collection("users").where({ _id: res1.data._id }).update({ pay_user: true });
|
||||
break;
|
||||
case "reborn_Gift":
|
||||
case "reborn_Gift_2":
|
||||
case "reborn_Gift_3":
|
||||
case "reborn_Gift_4":
|
||||
case "reborn_Gift_5":
|
||||
db.collection("users").where({ _id: res1.data._id }).update({ rebornGiftTime: Date.now(), rebornGiftCount: 0, pay_user: true });
|
||||
break;
|
||||
case "starter_pack":
|
||||
@@ -486,7 +490,8 @@ async function getIosOrder(openid, ctx) {
|
||||
break;
|
||||
}
|
||||
// 月卡补单确认成功后进入待客户端补发状态。
|
||||
if (res.data[i].itemid === "month_Card" || jungleTier || /^battlepass(?:_30|_12)?$/.test(res.data[i].itemid)) {
|
||||
if (res.data[i].itemid === "month_Card" || jungleTier || /^battlepass(?:_30|_12)?$/.test(res.data[i].itemid)
|
||||
|| /^reborn_Gift(?:_[2-5])?$/.test(res.data[i].itemid)) {
|
||||
await db.collection("order").where({ outTradeNo: res.data[i].outTradeNo }).update({ state: 1 });
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -102,6 +102,8 @@ async function frontsign(data) {
|
||||
return signature
|
||||
}
|
||||
const propName = {
|
||||
reborn_Gift: "复活礼包6元", reborn_Gift_2: "复活礼包8元", reborn_Gift_3: "复活礼包10元",
|
||||
reborn_Gift_4: "复活礼包12元", reborn_Gift_5: "复活礼包15元",
|
||||
battlepass: '基础战令', battlepass_30: '高级战令', battlepass_12: '战令升级',
|
||||
gold_1: "金币包1",
|
||||
gold_2: "金币包2",
|
||||
@@ -151,6 +153,11 @@ async function PostMsg(OpenId, msg) {
|
||||
return "ok"
|
||||
}
|
||||
async function PostImg(OpenId, outTradeNo, name, count, price, passInput: any = {}) {
|
||||
const rebornPrice = { reborn_Gift: 600, reborn_Gift_2: 800, reborn_Gift_3: 1000, reborn_Gift_4: 1200, reborn_Gift_5: 1500 };
|
||||
if (/^reborn_Gift(?:_[2-5])?$/.test(name)) {
|
||||
count = 1;
|
||||
price = rebornPrice[name];
|
||||
}
|
||||
let passFields: any = {};
|
||||
if (Object.prototype.hasOwnProperty.call(PASS_PRICES, name)) {
|
||||
const owner = await db.collection('users').where({ openid: OpenId }).getOne();
|
||||
|
||||
@@ -10,6 +10,15 @@ export default async function (ctx: FunctionContext) {
|
||||
if (!order.data) {
|
||||
return { code: 0, data: null, msg: "未获取到充值订单" };
|
||||
}
|
||||
if (/^reborn_Gift(?:_[2-5])?$/.test(order.data.itemid)) {
|
||||
const user = await db.collection("users").where({ _id: ctx.body.uid }).getOne();
|
||||
if (!user.data || user.data.openid !== order.data.openid) {
|
||||
return { code: 0, data: null, msg: "充值订单不属于当前玩家" };
|
||||
}
|
||||
if (order.data.state !== 1 && order.data.state !== 2) {
|
||||
return { code: 0, data: null, msg: "充值尚未成功" };
|
||||
}
|
||||
}
|
||||
// 月卡由 monthlyCard 在成功加时后完成订单,避免两次请求之间断线导致无法补发。
|
||||
if (isUpgradeOrder(order.data)) return { code: 0, msg: '请在新版战令中完成发放' };
|
||||
if (order.data.itemid !== "month_Card") {
|
||||
|
||||
@@ -24,6 +24,9 @@ export default async function (ctx: FunctionContext) {
|
||||
return { code: 0, data: null, msg: "未获取到充值信息" };
|
||||
}
|
||||
let payment_name = ret.data?.itemid;
|
||||
const rebornGift = /^reborn_Gift(?:_[2-5])?$/.test(payment_name);
|
||||
const rebornPending = rebornGift && Number(ctx.body.rebornGiftVersion) === 1;
|
||||
if (rebornGift && !uid) return { code: 0, data: null, msg: "未获取到玩家数据" };
|
||||
if (isUpgradeOrder(ret.data) && ret.data.state === 2) return { code: 1, data: { payment_name, goodsPrice: ret.data.goodsPrice } };
|
||||
if (res && payment_name === "starter_pack") {
|
||||
try {
|
||||
@@ -45,6 +48,9 @@ export default async function (ctx: FunctionContext) {
|
||||
if (!res1.data) {
|
||||
return { code: 0, data: null, msg: "未获取到玩家数据" };
|
||||
}
|
||||
if (rebornGift && ret.data.openid !== res1.data.openid) {
|
||||
return { code: 0, data: null, msg: "充值订单不属于当前玩家" };
|
||||
}
|
||||
paidUser = res1.data;
|
||||
if (!iosOrder) {
|
||||
iosOrder = {};
|
||||
@@ -65,6 +71,10 @@ export default async function (ctx: FunctionContext) {
|
||||
await db.collection("users").where({ _id: uid }).update({ pay_user: true });
|
||||
break;
|
||||
case "reborn_Gift":
|
||||
case "reborn_Gift_2":
|
||||
case "reborn_Gift_3":
|
||||
case "reborn_Gift_4":
|
||||
case "reborn_Gift_5":
|
||||
db.collection("users").where({ _id: uid }).update({ rebornGiftTime: Date.now(), rebornGiftCount: 0, pay_user: true });
|
||||
break;
|
||||
case "starter_pack":
|
||||
@@ -75,11 +85,11 @@ export default async function (ctx: FunctionContext) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 月卡等待 monthlyCard 完成加时后再进入 state=2,其他商品保持原逻辑。
|
||||
// 新版复活礼包等待客户端去重发奖后确认;旧客户端保持直接完成订单。
|
||||
await db.collection("order").where({ outTradeNo: outTradeNo, ...(isUpgradeOrder(ret.data) ? { state: ret.data.state } : {}) }).update({
|
||||
state: payment_name === "month_Card" || isUpgradeOrder(ret.data) ? 1 : 2,
|
||||
state: payment_name === "month_Card" || isUpgradeOrder(ret.data) || rebornPending ? 1 : 2,
|
||||
chargeTime: new Date(Date.now() + 8 * 3600000),
|
||||
...(payment_name === "month_Card" || isUpgradeOrder(ret.data) ? {} : { getTime: new Date(Date.now() + 8 * 3600000) }),
|
||||
...(payment_name === "month_Card" || isUpgradeOrder(ret.data) || rebornPending ? {} : { getTime: new Date(Date.now() + 8 * 3600000) }),
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ export default async function (ctx: FunctionContext) {
|
||||
let itemid = ctx.body.itemid;
|
||||
let itemCount = ctx.body.itemCount;
|
||||
let itemPrice = ctx.body.itemPrice;
|
||||
const rebornPrice = { reborn_Gift: 600, reborn_Gift_2: 800, reborn_Gift_3: 1000, reborn_Gift_4: 1200, reborn_Gift_5: 1500 };
|
||||
if (/^reborn_Gift(?:_[2-5])?$/.test(itemid)) {
|
||||
itemCount = 1;
|
||||
itemPrice = rebornPrice[itemid];
|
||||
}
|
||||
let user = await db.collection("users").where({ _id: uid }).getOne();
|
||||
if (user.data == null) {
|
||||
return { code: 0, data: null, msg: "未获取到玩家数据" };
|
||||
|
||||
@@ -17,6 +17,11 @@ export default async function (ctx: FunctionContext) {
|
||||
let itemid = ctx.body.itemid;
|
||||
let itemCount = ctx.body.itemCount;
|
||||
let itemPrice = ctx.body.itemPrice;
|
||||
const rebornPrice = { reborn_Gift: 600, reborn_Gift_2: 800, reborn_Gift_3: 1000, reborn_Gift_4: 1200, reborn_Gift_5: 1500 };
|
||||
if (/^reborn_Gift(?:_[2-5])?$/.test(itemid)) {
|
||||
itemCount = 1;
|
||||
itemPrice = rebornPrice[itemid];
|
||||
}
|
||||
let user = await db.collection("users").where({ _id: uid }).getOne();
|
||||
if (user.data == null) {
|
||||
return { code: 0, data: null, msg: "未获取到玩家数据" };
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# 当局复活礼包阶梯
|
||||
|
||||
| 本局成功购买次数(购买前) | 商品 ID | 价格(分) |
|
||||
| --- | --- | --- |
|
||||
| 0 | reborn_Gift | 600 |
|
||||
| 1 | reborn_Gift_2 | 800 |
|
||||
| 2 | reborn_Gift_3 | 1000 |
|
||||
| 3 | reborn_Gift_4 | 1200 |
|
||||
| 4 及以上 | reborn_Gift_5 | 1500 |
|
||||
|
||||
每档维持 1000 金币、冰冻/锤子/魔棒各 1,以及当前局复活加 30 秒。主线、助力和无尽模式共用规则。
|
||||
|
||||
## 计数与补单
|
||||
|
||||
- `Map.rebornGiftCount` 只记录本局已确认支付的订单,以订单号去重;新建关卡的 Map 时归零。切后台不重建 Map,因此保留次数。
|
||||
- 金币复活继续使用独立的 `GM_INFO.review`;礼包购买不读写它。
|
||||
- 回调捕获下单时的 Map。若已换局,仍发金币/道具,但不复活新局、不递增新局次数。
|
||||
- `GameTool.shopBuy` 沿用现有发奖方式,为复活礼包增加按用户及订单号保存的去重标记,登录补单也使用同一标记。
|
||||
- 新版旧 iOS 客服支付查询携带 `rebornGiftVersion: 1`,服务器先标记待领取,客户端发奖后再确认;旧客户端保持原有完成方式。
|
||||
- 不新增对局登记接口。云端旧 `rebornGiftCount` 仍返回 0、保持不限购;当局阶梯由 Map 管理,服务器按商品 ID 强制对应价格和数量 1,不独立校验当局购买序号。
|
||||
|
||||
## 发布范围
|
||||
|
||||
先发布云函数:`wx/orderPaySig`、`wx/iosorderPaySig`、`wx/KeFuInfo`、`wx/iosgetPayInfo`、`wx/getOrderReward`、`login`,再发布客户端。支付平台须存在上述五个商品,仓库无法验证平台配置。
|
||||
|
||||
客户端直接更新 `Lose/Revive/price` 的数字文本,保留现有字体及独立的“元”节点;数字固定右边缘,两位数向左展开。
|
||||
|
||||
验证命令:`node --test tools/test-reborn-gift.cjs`(仓库根目录)。测试使用模拟订单,不会发起真实支付。
|
||||
@@ -0,0 +1,215 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const crypto = require('node:crypto');
|
||||
const { loadMembers, loadModule } = require('./new-player-ab-test-support.cjs');
|
||||
|
||||
const products = ['reborn_Gift', 'reborn_Gift_2', 'reborn_Gift_3', 'reborn_Gift_4', 'reborn_Gift_5'];
|
||||
const prices = [600, 800, 1000, 1200, 1500];
|
||||
const MapController = loadMembers('assets/Script/Map.ts', [
|
||||
'rebornGiftCount', 'rebornGiftOrders', 'recordRebornGiftPurchase', 'getRebornGiftProduct',
|
||||
]);
|
||||
|
||||
function fixture() {
|
||||
const storage = new Map(), calls = { rewards: [], revived: [], acknowledgements: [], products: [], props: [] };
|
||||
const info = { uid: 'u', coin: 100, review: 3, iosCanPay: true };
|
||||
const map = new MapController();
|
||||
const cc = {
|
||||
fx: { GameConfig: { GM_INFO: info }, StorageMessage: {
|
||||
getStorage: key => storage.get(key), setStorage: (key, value) => storage.set(key, value),
|
||||
} },
|
||||
sys: { platform: 1, WECHAT_GAME: 1, BYTEDANCE_GAME: 2 },
|
||||
isValid: value => !!value && !value.destroyed, find: () => null,
|
||||
};
|
||||
MapController._instance = map;
|
||||
map.SceneManager = { openRewardWindow: rewards => calls.rewards.push(rewards) };
|
||||
const MiniGameSdk = { API: { showToast() {}, yinli_Pay() {}, shushu_SetSuperProperties() {} } };
|
||||
const Tool = loadMembers('assets/Script/module/Tool/GameTool.ts', ['shopBuy'], { cc, MapConroler: MapController, MiniGameSdk });
|
||||
cc.fx.GameTool = Object.assign(new Tool(), {
|
||||
changeCoin: amount => { info.coin += amount; },
|
||||
getShopProp: props => calls.props.push(props), shushu_Track() {},
|
||||
});
|
||||
const Utils = {
|
||||
outTradeNo: 'unrelated-order',
|
||||
buyProp: (id, count, price, platform, product, callback) => { calls.products.push({ id, count, price }); calls.pay = callback; },
|
||||
getPayInfo: (callback, order) => { calls.poll = callback; calls.polledOrder = order; },
|
||||
getIosPayInfo: (order, callback) => { calls.iosPoll = callback; calls.polledOrder = order; },
|
||||
setPayInfo: (callback, order) => { calls.acknowledgements.push(order); calls.ack = callback; },
|
||||
GoKEFu: (data, callback) => { calls.iosRequest = data; info.iosReviveOrder = 'ios-order'; callback('success'); },
|
||||
};
|
||||
const Revive = loadMembers('assets/Script/Revive.ts', [
|
||||
'iosMap', 'iosUid', 'checkingIosOrder', 'iosPrice', 'iosProductId', 'iosCount',
|
||||
'buyProduct', 'onShow', 'iosOldPay', 'completePurchase',
|
||||
], { cc, MapConroler: MapController, MiniGameSdk, Utils, wx: { getSystemInfoSync: () => ({ platform: 'android' }) }, console: { log() {}, error() {} } });
|
||||
const revive = Object.assign(new Revive(), {
|
||||
btn_Touch: true, openLoad() {}, closeLoad() {}, buyGift() {}, updateGameCoin() {}, updatePrice() {}, openConfirmBox() {},
|
||||
revivew: source => calls.revived.push(source),
|
||||
});
|
||||
return { map, revive, info, calls, cc, Utils, newMap: () => {
|
||||
const next = new MapController(); next.SceneManager = map.SceneManager; MapController._instance = next; return next;
|
||||
} };
|
||||
}
|
||||
|
||||
test('one run advances through five prices, caps at 15 yuan and leaves coin revival untouched', () => {
|
||||
const f = fixture();
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const tier = Math.min(i, 4), offer = f.map.getRebornGiftProduct();
|
||||
assert.equal(offer.id, products[tier]); assert.equal(offer.price, prices[tier]);
|
||||
f.revive.completePurchase(offer.id, `order-${i}`, f.map, 'u');
|
||||
assert.equal(f.map.rebornGiftCount, i + 1);
|
||||
assert.equal(f.calls.props[i].price, prices[tier]);
|
||||
assert.equal(f.calls.props[i].freeze, 1); assert.equal(f.calls.props[i].hammer, 1); assert.equal(f.calls.props[i].magic_wand, 1);
|
||||
}
|
||||
assert.equal(f.info.coin, 8100); assert.equal(f.info.review, 3);
|
||||
assert.equal(f.calls.revived.length, 8);
|
||||
assert.equal(f.newMap().getRebornGiftProduct().price, 600);
|
||||
});
|
||||
|
||||
test('duplicate callbacks and login compensation grant each order only once', () => {
|
||||
const f = fixture();
|
||||
f.revive.completePurchase('reborn_Gift', 'same', f.map, 'u');
|
||||
f.revive.completePurchase('reborn_Gift', 'same', f.map, 'u');
|
||||
f.cc.fx.GameTool.shopBuy('reborn_Gift', true, { outTradeNo: 'same' });
|
||||
assert.equal(f.info.coin, 1100); assert.equal(f.map.rebornGiftCount, 1); assert.equal(f.calls.revived.length, 1);
|
||||
for (const product of products) f.cc.fx.GameTool.shopBuy(product, true, { outTradeNo: product });
|
||||
assert.equal(f.info.coin, 6100); assert.equal(f.map.rebornGiftCount, 1);
|
||||
});
|
||||
|
||||
test('old-run payment grants rewards without reviving or advancing a new run; changed account is ignored', () => {
|
||||
const f = fixture(); const next = f.newMap();
|
||||
f.revive.completePurchase('reborn_Gift_3', 'late', f.map, 'u');
|
||||
assert.equal(f.info.coin, 1100); assert.equal(next.rebornGiftCount, 0); assert.equal(f.calls.revived.length, 0);
|
||||
f.info.uid = 'other'; f.revive.completePurchase('reborn_Gift_4', 'other-account', f.map, 'u');
|
||||
assert.equal(f.info.coin, 1100);
|
||||
});
|
||||
|
||||
test('ordinary payment captures its order and run, blocks repeated clicks and counts verified success once', () => {
|
||||
const f = fixture();
|
||||
f.revive.buyProduct(null); f.revive.buyProduct(null);
|
||||
assert.equal(f.calls.products.length, 1); assert.equal(f.map.rebornGiftCount, 0);
|
||||
f.calls.pay({ outTradeNo: 'paid-order' }); assert.equal(f.calls.polledOrder, 'paid-order');
|
||||
f.calls.poll({ code: 1, data: { pay_state: 2 } });
|
||||
assert.equal(f.map.rebornGiftCount, 1); assert.equal(f.info.coin, 1100);
|
||||
assert.deepEqual(f.calls.acknowledgements, ['paid-order']);
|
||||
f.calls.ack({ code: 1 }); assert.equal(f.map.rebornGiftCount, 1);
|
||||
});
|
||||
|
||||
test('cancelled, failed and unconfirmed payments keep the six-yuan tier', () => {
|
||||
for (const response of [null, { err: true, errCode: -2 }, { err: true, errCode: -1 }]) {
|
||||
const f = fixture(); f.revive.buyProduct(null); f.calls.pay(response);
|
||||
assert.equal(f.map.rebornGiftCount, 0); assert.equal(f.revive.btn_Touch, true);
|
||||
}
|
||||
const f = fixture(); f.revive.buyProduct(null); f.calls.pay({ outTradeNo: 'unknown' });
|
||||
f.calls.poll({ code: 0, data: { pay_state: -1 } });
|
||||
assert.equal(f.map.rebornGiftCount, 0); assert.equal(f.info.coin, 100);
|
||||
const missing = fixture(); missing.revive.buyProduct(null); missing.calls.pay({});
|
||||
assert.equal(missing.calls.polledOrder, undefined); assert.equal(missing.revive.btn_Touch, true);
|
||||
});
|
||||
|
||||
test('iOS background return keeps the run; overlapping polls and late callbacks do not double grant', () => {
|
||||
const f = fixture(); f.map.recordRebornGiftPurchase('earlier');
|
||||
f.revive.iosOldPay(800, 'reborn_Gift_2', f.map, 'u');
|
||||
assert.equal(f.calls.iosRequest.price, 800);
|
||||
f.revive.onShow(); const poll = f.calls.iosPoll; f.revive.onShow(); assert.equal(f.calls.iosPoll, poll);
|
||||
poll({ code: 1, data: { payment_name: 'reborn_Gift_2', goodsPrice: 800 } });
|
||||
assert.equal(f.map.rebornGiftCount, 2); assert.equal(f.info.coin, 1100);
|
||||
assert.deepEqual(f.calls.acknowledgements, ['ios-order']);
|
||||
f.info.iosReviveOrder = 'late-ios'; const next = f.newMap(); f.revive.onShow();
|
||||
f.calls.iosPoll({ code: 1, data: { payment_name: 'reborn_Gift_3', goodsPrice: 1000 } });
|
||||
assert.equal(next.rebornGiftCount, 0); assert.equal(f.info.coin, 2100); assert.equal(f.calls.revived.length, 1);
|
||||
});
|
||||
|
||||
test('price node updates the amount on every opening, including 10/12/15 yuan', () => {
|
||||
const data = JSON.parse(require('node:fs').readFileSync('assets/lose/prefab/Lose.prefab', 'utf8'));
|
||||
const node = data.find(n => n.__type__ === 'cc.Node' && n._name === 'price');
|
||||
assert.ok(node._components.some(ref => data[ref.__id__].__type__ === 'cc.Label'));
|
||||
assert.ok(data[data.findIndex(n => n === node)]._parent);
|
||||
assert.ok(data[node._parent.__id__]._children.some(ref => data[ref.__id__]._name === 'yuan'));
|
||||
const label = {}, price = { x: node._trs.array[0], width: node._contentSize.width, anchorX: node._anchorPoint.x, getComponent: () => label };
|
||||
const right = price.x + price.width * (1 - price.anchorX);
|
||||
const map = new MapController(); MapController._instance = map;
|
||||
const cc = { Label: {} };
|
||||
const Panel = loadMembers('assets/Script/Revive.ts', ['updatePrice'], { cc, MapConroler: MapController });
|
||||
const panel = new Panel(); panel.node = { getChildByName: name => name === 'price' ? price : null };
|
||||
for (let i = 0; i < 7; i++) {
|
||||
map.rebornGiftCount = i; panel.updatePrice();
|
||||
assert.equal(label.string, String(prices[Math.min(i, 4)] / 100));
|
||||
assert.equal(price.x, right); assert.equal(price.anchorX, 1);
|
||||
price.width = label.string.length * 44;
|
||||
}
|
||||
});
|
||||
|
||||
function serverFixture() {
|
||||
const state = { orders: [], user: { _id: 'u', openid: 'o', session_key: 'session' }, requests: [] };
|
||||
const matches = (row, query) => Object.entries(query).every(([key, value]) => row[key] === value);
|
||||
const db = { collection: name => ({
|
||||
add: async row => { state.orders.push({ ...row, collection: name }); return {}; },
|
||||
where: query => ({
|
||||
getOne: async () => ({ data: (name === 'users' ? [state.user] : state.orders).find(row => matches(row, query)) }),
|
||||
update: async values => { (name === 'users' ? [state.user] : state.orders).filter(row => matches(row, query)).forEach(row => Object.assign(row, values)); return {}; },
|
||||
}),
|
||||
}) };
|
||||
const cloud = { database: () => db, shared: { get: key => key === 'wxaccess_token' ? 'token' : {}, set() {} }, storage: { bucket: () => ({ readFile: async () => ({ Body: { transformToString: async () => 'key' } }) }) } };
|
||||
const deps = {
|
||||
'@lafjs/cloud': { default: cloud }, '@/limitedTimeEvent': { starterPackOrderSnapshot: () => ({}), reportRookieGift: async () => {} },
|
||||
'@/passCheckUpgrade': { passOrderFields: () => ({}), PASS_PRICES: {}, isUpgradeOrder: () => false },
|
||||
'@/jungleConfig': { getJunglePaidTierByProductId: () => null },
|
||||
'thinkingdata-node': {},
|
||||
crypto: { ...crypto, default: { ...crypto, createSign: () => ({ update() {}, sign: () => 'signature' }) } },
|
||||
};
|
||||
const globals = { process: { env: { PAYMENT_APP_ENV: 'production', WX_MIDAS_PAY_SIGN_KEY: 'test-key' } }, console: { log() {}, error() {} },
|
||||
fetch: async (url, options) => { state.requests.push({ url, body: options?.body && JSON.parse(options.body) }); return { ok: true, json: async () => ({ prepay_id: 'prepay', errcode: 0, trade_state: 'SUCCESS' }) }; },
|
||||
};
|
||||
return { state, load: file => loadModule(file, deps, globals).default };
|
||||
}
|
||||
|
||||
test('Android and iOS signing enforce all five server prices and quantity one', async () => {
|
||||
for (const file of ['orderPaySig', 'iosorderPaySig']) {
|
||||
const f = serverFixture(), create = f.load(`server/laf-cloud/functions/wx/${file}.ts`);
|
||||
for (let i = 0; i < products.length; i++) {
|
||||
const result = await create({ body: { uid: 'u', itemid: products[i], itemPrice: 1, itemCount: 99 } });
|
||||
assert.equal(result.code, 1);
|
||||
const signed = JSON.parse(result.data.signData);
|
||||
assert.equal(signed.goodsPrice, prices[i]); assert.equal(signed.buyQuantity, 1);
|
||||
assert.equal(f.state.orders[i].goodsPrice, prices[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('legacy iOS customer service enforces the same prices and names', async () => {
|
||||
const f = serverFixture(), create = f.load('server/laf-cloud/functions/wx/KeFuInfo.ts');
|
||||
for (let i = 0; i < products.length; i++) {
|
||||
await create({ body: { FromUserName: 'o', SessionFrom: JSON.stringify({ tpye: 'ios', propName: products[i], price: 1, count: 99, outTradeNo: `ios-${i}` }) } });
|
||||
assert.equal(f.state.orders[i].goodsPrice, prices[i]); assert.equal(f.state.orders[i].itemCount, 1);
|
||||
const payment = f.state.requests.filter(r => r.url.includes('/v3/pay/transactions/jsapi'))[i];
|
||||
assert.equal(payment.body.amount.total, prices[i]);
|
||||
}
|
||||
});
|
||||
|
||||
test('reborn acknowledgement rejects unpaid or foreign orders and tolerates retries', async () => {
|
||||
const f = serverFixture(), acknowledge = f.load('server/laf-cloud/functions/wx/getOrderReward.ts');
|
||||
const order = { outTradeNo: 'paid', itemid: 'reborn_Gift_5', openid: 'o', state: 0 }; f.state.orders.push(order);
|
||||
const request = () => acknowledge({ body: { outTradeNo: 'paid', uid: 'u' } });
|
||||
assert.equal((await request()).code, 0); assert.equal(order.state, 0);
|
||||
order.state = 1; order.openid = 'other'; assert.equal((await request()).code, 0);
|
||||
order.openid = 'o'; assert.equal((await request()).code, 1); assert.equal(order.state, 2);
|
||||
assert.equal((await request()).code, 1);
|
||||
});
|
||||
|
||||
test('legacy iOS confirms all tiers but leaves new-client rewards pending until acknowledgement', async () => {
|
||||
for (const version of [undefined, 1]) for (let i = 0; i < products.length; i++) {
|
||||
const f = serverFixture(), poll = f.load('server/laf-cloud/functions/wx/iosgetPayInfo.ts');
|
||||
const order = { outTradeNo: 'ios', itemid: products[i], goodsPrice: prices[i], openid: 'o', state: 0 };
|
||||
f.state.orders.push(order);
|
||||
const result = await poll({ body: { uid: 'u', outTradeNo: 'ios', rebornGiftVersion: version }, headers: {}, socket: {} });
|
||||
assert.equal(result.code, 1); assert.equal(result.data.goodsPrice, prices[i]);
|
||||
assert.equal(order.state, version === 1 ? 1 : 2);
|
||||
assert.equal(f.state.user.rebornGiftCount, 0, 'legacy global limit stays disabled');
|
||||
if (version === 1) {
|
||||
const again = await poll({ body: { uid: 'u', outTradeNo: 'ios', rebornGiftVersion: 1 }, headers: {}, socket: {} });
|
||||
assert.equal(again.code, 1); assert.equal(order.state, 1);
|
||||
const acknowledge = f.load('server/laf-cloud/functions/wx/getOrderReward.ts');
|
||||
assert.equal((await acknowledge({ body: { uid: 'u', outTradeNo: 'ios' } })).code, 1);
|
||||
assert.equal(order.state, 2);
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user