false, 'message' => 'PlayX angpow_import not configured', ]; } $baseUrl = rtrim(strval($conf['base_url'] ?? ''), '/'); $path = strval($conf['path'] ?? ''); $merchantCode = strval($conf['merchant_code'] ?? ''); $authKey = strval($conf['auth_key'] ?? ''); if ($baseUrl === '' || $path === '' || $merchantCode === '' || $authKey === '') { return [ 'ok' => false, 'message' => 'PlayX Angpow Import API not configured', ]; } $url = $baseUrl . $path; $asset = MallUserAsset::where('playx_user_id', $order->user_id)->find(); if (!$asset || !is_string($asset->playx_user_id ?? null) || strval($asset->playx_user_id) === '') { return [ 'ok' => false, 'message' => 'User asset not found', ]; } $item = MallItem::where('id', $order->mall_item_id)->find(); if (!$item) { return [ 'ok' => false, 'message' => 'Item not found', ]; } $reportDate = strval(time()); $signatureInput = 'merchant_code=' . $merchantCode . '&report_date=' . $reportDate; $signature = self::buildSignature($signatureInput, $authKey); if ($signature === null) { return [ 'ok' => false, 'message' => 'Build signature failed', ]; } $start = gmdate('Y-m-d\TH:i:s\Z', strtotime(strval($order->start_time))); $end = gmdate('Y-m-d\TH:i:s\Z', strtotime(strval($order->end_time))); $multiplier = intval($order->multiplier ?? 0); if ($multiplier <= 0) { $multiplier = 1; } $payload = [ 'merchant_code' => $merchantCode, 'report_date' => $reportDate, 'angpow' => [ [ 'member_login' => strval($asset->playx_user_id), 'start_time' => $start, 'end_time' => $end, 'amount' => $order->amount, 'reward_name' => strval($item->title ?? ''), 'description' => strval($item->description ?? ''), 'member_inbox_message' => 'Congratulations! You received an angpow.', 'category' => strval($item->category ?? ''), 'category_title' => strval($item->category_title ?? ''), 'one_time_turnover' => 'yes', 'multiplier' => $multiplier, ], ], 'currency_visual' => [ [ 'currency' => strval($conf['currency'] ?? 'MYR'), 'visual_name' => strval($conf['visual_name'] ?? 'Angpow'), ], ], ]; $client = new Client([ 'timeout' => 20, 'http_errors' => false, ]); try { $res = $client->post($url, [ 'headers' => [ 'Content-Type' => 'application/json', 'X-Request-Signature' => $signature, ], 'json' => $payload, ]); $data = json_decode(strval($res->getBody()), true) ?? []; if (($data['code'] ?? null) === '0' || ($data['code'] ?? null) === 0) { return [ 'ok' => true, 'message' => '', ]; } return [ 'ok' => false, 'message' => strval($data['message'] ?? 'PlayX angpow import not accepted'), ]; } catch (\Throwable $e) { return [ 'ok' => false, 'message' => $e->getMessage(), ]; } } private static function buildSignature(string $input, string $authKey): ?string { $keyBytes = null; $maybeBase64 = base64_decode($authKey, true); if ($maybeBase64 !== false && $maybeBase64 !== '') { $keyBytes = $maybeBase64; } if ($keyBytes === null) { $isHex = ctype_xdigit($authKey) && (strlen($authKey) % 2 === 0); if ($isHex) { $hex = hex2bin($authKey); if ($hex !== false && $hex !== '') { $keyBytes = $hex; } } } if ($keyBytes === null) { $keyBytes = $authKey; } $raw = hash_hmac('sha1', $input, $keyBytes, true); if (!is_string($raw) || $raw === '') { return null; } return base64_encode($raw); } }