Compare commits

...

6 Commits

Author SHA1 Message Date
0fdc1e2e88 优化每日推送接口 2026-04-08 13:57:38 +08:00
186af5a55f 更新推送订单接口新增start_time和end_time 2026-04-08 10:28:40 +08:00
6bec4e7758 修复签名生成bug 2026-04-07 10:46:32 +08:00
f9e4e61d93 修复签名生成bug 2026-04-07 10:45:07 +08:00
8b6727dac1 修复签名生成bug 2026-04-07 10:42:50 +08:00
b97d33a24f 优化统一订单页面翻译 2026-04-03 11:07:38 +08:00
7 changed files with 81 additions and 57 deletions

View File

@@ -148,7 +148,7 @@ class Playx extends Api
/** /**
* Daily Push API - PlayX 调用商城接收 T+1 数据 * Daily Push API - PlayX 调用商城接收 T+1 数据
* POST /api/v1/playx/daily-push * POST /api/v1/mall/dailyPush
*/ */
public function dailyPush(Request $request): Response public function dailyPush(Request $request): Response
{ {
@@ -173,7 +173,7 @@ class Playx extends Api
if ($sig === '' || $ts === '' || $rid === '') { if ($sig === '' || $ts === '' || $rid === '') {
return $this->error(__('Daily push signature missing or incomplete'), null, 0, ['statusCode' => 401]); return $this->error(__('Daily push signature missing or incomplete'), null, 0, ['statusCode' => 401]);
} }
$canonical = $ts . "\n" . $rid . "\nPOST\n/api/v1/playx/daily-push\n" . hash('sha256', json_encode($body)); $canonical = $ts . "\n" . $rid . "\nPOST\n/api/v1/mall/dailyPush\n" . hash('sha256', json_encode($body));
$expected = hash_hmac('sha256', $canonical, $secret); $expected = hash_hmac('sha256', $canonical, $secret);
if (!hash_equals($expected, $sig)) { if (!hash_equals($expected, $sig)) {
return $this->error(__('Daily push signature verification failed'), null, 0, ['statusCode' => 401]); return $this->error(__('Daily push signature verification failed'), null, 0, ['statusCode' => 401]);
@@ -942,6 +942,8 @@ class Playx extends Api
'grant_status' => MallOrder::GRANT_NOT_SENT, 'grant_status' => MallOrder::GRANT_NOT_SENT,
'create_time' => time(), 'create_time' => time(),
'update_time' => time(), 'update_time' => time(),
'start_time' => date('Y-m-d H:i:s', time()),
'end_time' => date('Y-m-d H:i:s', time()+86400*3),
]); ]);
Db::commit(); Db::commit();

View File

@@ -238,17 +238,17 @@ class AngpowImportJobs
return null; return null;
} }
$createTime = $order->create_time ?? null; // $createTime = $order->create_time ?? null;
if (!is_int($createTime)) { // if (!is_int($createTime)) {
if (is_numeric($createTime)) { // if (is_numeric($createTime)) {
$createTime = intval($createTime); // $createTime = intval($createTime);
} else { // } else {
$createTime = time(); // $createTime = time();
} // }
} // }
$start = gmdate('Y-m-d\TH:i:s\Z', $createTime); $start = gmdate('Y-m-d H:i:s', strtotime($order->start_time));
$end = gmdate('Y-m-d\TH:i:s\Z', $createTime + 86400); $end = gmdate('Y-m-d H:i:s', strtotime($order->end_time));
return [ return [
'member_login' => strval($asset->playx_user_id), 'member_login' => strval($asset->playx_user_id),

View File

@@ -13,7 +13,7 @@ return [
// Daily Push 签名校验PlayX 调用商城时使用) // Daily Push 签名校验PlayX 调用商城时使用)
'daily_push_secret' => strval(env('PLAYX_DAILY_PUSH_SECRET', '')), 'daily_push_secret' => strval(env('PLAYX_DAILY_PUSH_SECRET', '')),
/** /**
* 合作方 JWT 验签密钥HS256。非空时daily-push 等回调需带 Authorization: Bearer * 合作方 JWT 验签密钥HS256。非空时dailyPush 等回调需带 Authorization: Bearer
* 仅写入部署环境变量,勿提交仓库。 * 仅写入部署环境变量,勿提交仓库。
*/ */
'partner_jwt_secret' => strval(env('PLAYX_PARTNER_JWT_SECRET', '')), 'partner_jwt_secret' => strval(env('PLAYX_PARTNER_JWT_SECRET', '')),

View File

@@ -1,13 +1,14 @@
<?php <?php
//脚本执行指令 php tmp_sig.php
$secret = '5590a339502b133f4d0c545c3cdad159a4827dfccb3f51bb110c56f9b96568ca'; $secret = '5590a339502b133f4d0c545c3cdad159a4827dfccb3f51bb110c56f9b96568ca';
$ts = '1700000123'; $ts = '1775525663';
$rid = 'req_1700000000_234567'; $rid = 'req_1775525663_123';
$body = [ $body = [
'report_date' => '1700000123', 'report_date' => '1775525663',
'member' => [ 'member' => [
[ [
'member_id' => '234567', 'member_id' => '123',
'login' => 'zhenhui', 'login' => 'zhenhui',
'ltv_deposit' => 1500, 'ltv_deposit' => 1500,
'ltv_withdrawal' => 1800, 'ltv_withdrawal' => 1800,
@@ -18,7 +19,7 @@ $body = [
]; ];
$json = json_encode($body); $json = json_encode($body);
$canonical = $ts . "\n" . $rid . "\nPOST\n/api/v1/playx/daily-push\n" . hash('sha256', $json); $canonical = $ts . "\n" . $rid . "\nPOST\n/api/v1/mall/dailyPush\n" . hash('sha256', $json);
echo "json={$json}\n"; echo "json={$json}\n";
echo "sha256=" . hash('sha256', $json) . "\n"; echo "sha256=" . hash('sha256', $json) . "\n";

View File

@@ -2,41 +2,42 @@ export default {
approve: 'Review', approve: 'Review',
manual_retry: 'Retry grant', manual_retry: 'Retry grant',
retry_confirm: 'Queue this order for grant retry?', retry_confirm: 'Queue this order for grant retry?',
id: 'ID', id: 'Order ID',
user_id: 'user_id', user_id: 'User ID',
type: 'type', type: 'Type',
'type BONUS': 'Bonus(BONUS)', 'type BONUS': 'Bonus',
'type PHYSICAL': 'Physical(PHYSICAL)', 'type PHYSICAL': 'Physical',
'type WITHDRAW': 'Withdraw(WITHDRAW)', 'type WITHDRAW': 'Withdraw',
status: 'status', status: 'Status',
'status PENDING': 'Pending(PENDING)', 'status PENDING': 'Pending',
'status COMPLETED': 'Completed(COMPLETED)', 'status COMPLETED': 'Completed',
'status SHIPPED': 'Shipped(SHIPPED)', 'status SHIPPED': 'Shipped',
'status REJECTED': 'Rejected(REJECTED)', 'status REJECTED': 'Rejected',
mall_item_id: 'mall_item_id', mall_item_id: 'Product ID',
mallitem__title: 'title', mallitem__title: 'Product title',
points_cost: 'points_cost', points_cost: 'Points spent',
amount: 'amount', amount: 'Cash amount',
multiplier: 'multiplier', multiplier: 'Turnover multiplier',
external_transaction_id: 'external_transaction_id', external_transaction_id: 'Order number',
playx_transaction_id: 'playx_transaction_id', playx_transaction_id: 'PlayX transaction ID',
grant_status: 'grant_status', grant_status: 'Grant status',
'grant_status NOT_SENT': 'NOT_SENT', 'grant_status NOT_SENT': 'Not sent',
'grant_status SENT_PENDING': 'SENT_PENDING', 'grant_status SENT_PENDING': 'Sent (queued)',
'grant_status ACCEPTED': 'ACCEPTED', 'grant_status ACCEPTED': 'Accepted',
'grant_status FAILED_RETRYABLE': 'FAILED_RETRYABLE', 'grant_status FAILED_RETRYABLE': 'Failed (retryable)',
'grant_status FAILED_FINAL': 'FAILED_FINAL', 'grant_status FAILED_FINAL': 'Failed (final)',
'grant_status ---': '---', 'grant_status ---': '',
fail_reason: 'fail_reason', fail_reason: 'Failure reason',
reject_reason: 'reject_reason', reject_reason: 'Rejection reason',
shipping_company: 'shipping_company', shipping_company: 'Carrier',
shipping_no: 'shipping_no', shipping_no: 'Tracking number',
receiver_name: 'receiver_name', receiver_name: 'Recipient name',
receiver_phone: 'receiver_phone', receiver_phone: 'Recipient phone',
receiver_address: 'receiver_address', receiver_address: 'Shipping address',
mall_address_id: 'mall_address_id', mall_address_id: 'Address ID',
create_time: 'create_time', start_time: 'Redemption time',
update_time: 'update_time', end_time: 'Collection end time',
'quick Search Fields': 'ID', create_time: 'Created at',
update_time: 'Updated at',
'quick Search Fields': 'Order ID',
} }

View File

@@ -23,7 +23,7 @@ export default {
grant_status: '推送playx状态', grant_status: '推送playx状态',
'grant_status NOT_SENT': '未发送', 'grant_status NOT_SENT': '未发送',
'grant_status SENT_PENDING': '已发送排队', 'grant_status SENT_PENDING': '已发送排队',
'grant_status ACCEPTED': '已接收(accepted)', 'grant_status ACCEPTED': '已接收',
'grant_status FAILED_RETRYABLE': '失败可重试', 'grant_status FAILED_RETRYABLE': '失败可重试',
'grant_status FAILED_FINAL': '失败最终', 'grant_status FAILED_FINAL': '失败最终',
'grant_status ---': '---', 'grant_status ---': '---',
@@ -35,8 +35,9 @@ export default {
receiver_phone: '收货电话', receiver_phone: '收货电话',
receiver_address: '收货地址', receiver_address: '收货地址',
mall_address_id: '地址ID', mall_address_id: '地址ID',
start_time: '兑换时间',
end_time: '领取结束时间',
create_time: '创建时间', create_time: '创建时间',
update_time: '修改时间', update_time: '修改时间',
'quick Search Fields': 'ID', 'quick Search Fields': 'ID',
} }

View File

@@ -210,6 +210,24 @@ const baTable = new baTableClass(
operatorPlaceholder: t('Fuzzy query'), operatorPlaceholder: t('Fuzzy query'),
}, },
{ label: t('mall.order.mall_address_id'), prop: 'mall_address_id', align: 'center', width: 100, operator: 'eq', sortable: false }, { label: t('mall.order.mall_address_id'), prop: 'mall_address_id', align: 'center', width: 100, operator: 'eq', sortable: false },
{
label: t('mall.order.start_time'),
prop: 'start_time',
align: 'center',
operator: 'RANGE',
comSearchRender: 'datetime',
sortable: 'custom',
width: 160,
},
{
label: t('mall.order.end_time'),
prop: 'end_time',
align: 'center',
operator: 'RANGE',
comSearchRender: 'datetime',
sortable: 'custom',
width: 160,
},
{ {
label: t('mall.order.create_time'), label: t('mall.order.create_time'),
prop: 'create_time', prop: 'create_time',
@@ -225,6 +243,7 @@ const baTable = new baTableClass(
label: t('mall.order.update_time'), label: t('mall.order.update_time'),
prop: 'update_time', prop: 'update_time',
align: 'center', align: 'center',
show: false,
render: 'datetime', render: 'datetime',
operator: 'RANGE', operator: 'RANGE',
comSearchRender: 'datetime', comSearchRender: 'datetime',