$ErrorActionPreference = "Continue" $base = $env:OPENAPI_BASE_URL $appKey = $env:OPENAPI_APPKEY $appSecret = $env:OPENAPI_APPSECRET $iccid = $env:OPENAPI_ICCID $chanKey = $env:OPENAPI_CHANKEY if (-not $base -or -not $appKey -or -not $appSecret -or -not $iccid -or -not $chanKey) { throw "Set OPENAPI_BASE_URL, OPENAPI_APPKEY, OPENAPI_APPSECRET, OPENAPI_ICCID and OPENAPI_CHANKEY first" } $tmp = Join-Path $PSScriptRoot ".apitest-output" if (-not (Test-Path $tmp)) { New-Item -ItemType Directory -Path $tmp | Out-Null } # Try a quick connectivity check try { $ping = Invoke-WebRequest -Uri "$base/" -Method GET -TimeoutSec 8 -UseBasicParsing -ErrorAction Stop Write-Host "[ping] status=$($ping.StatusCode)" } catch { Write-Host "[ping] FAIL: $($_.Exception.Message)" } $ts = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds().ToString() function Call-Api { param( [string]$Label, [string]$Url, [string]$Method = "POST", [hashtable]$Headers = @{}, [string]$BodyJson = $null, [int]$TimeoutSec = 15 ) Write-Host "" Write-Host "==== $Label ====" Write-Host "$Method $Url" if ($Headers.Count -gt 0) { Write-Host ("Headers: " + (($Headers.GetEnumerator() | ForEach-Object { "$($_.Key): " }) -join "; ")) } if ($null -ne $BodyJson) { $logBody = $BodyJson | ConvertFrom-Json if ($logBody.verify) { $logBody.verify.password = "" $logBody.verify.sign = "" } Write-Host ("Body: " + ($logBody | ConvertTo-Json -Depth 10 -Compress)) } try { $params = @{ Uri = $Url Method = $Method TimeoutSec = $TimeoutSec UseBasicParsing = $true } if ($Headers.Count -gt 0) { $params.Headers = $Headers } if ($null -ne $BodyJson) { $params.ContentType = "application/json; charset=utf-8" $params.Body = $BodyJson } $resp = Invoke-WebRequest @params -ErrorAction Stop $code = $resp.StatusCode $text = $resp.Content Write-Host "HTTP $code" if ($text.Length -gt 4000) { Write-Host $text.Substring(0, 4000) $fn = Join-Path $tmp ("$Label".Replace('\','_').Replace('/','_') + ".txt") Set-Content -LiteralPath $fn -Value $text -Encoding utf8NoBOM Write-Host "(truncated, full saved to $fn)" } else { Write-Host $text } } catch { $msg = $_.Exception.Message Write-Host "ERROR: $msg" if ($_.Exception.Response) { $sr = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream()) $body = $sr.ReadToEnd() Write-Host "BODY: $body" } } } # ===== V3 ===== # 3.2 token (obtain once, reuse for the rest of V3) $tokenJson = $null try { $tokenBody = @{ appKey=$appKey; appSecret=$appSecret } | ConvertTo-Json -Compress $resp = Invoke-WebRequest -Uri "$base/openapi/v3/query/token" -Method POST -ContentType "application/json; charset=utf-8" -Body $tokenBody -TimeoutSec 12 -UseBasicParsing -ErrorAction Stop $tokenJson = $resp.Content Write-Host "==== V3-token ====" Write-Host "POST $base/openapi/v3/query/token" Write-Host 'Body: ' Write-Host "HTTP $($resp.StatusCode)" Write-Host 'Token response received (token redacted)' } catch { Write-Host "==== V3-token ====" Write-Host "POST $base/openapi/v3/query/token" Write-Host "token fetch FAIL: $($_.Exception.Message)" if ($_.Exception.Response) { $sr = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream()) Write-Host "token err body: $($sr.ReadToEnd())" } } $accessToken = $null $appId = $null if ($tokenJson) { try { $obj = $tokenJson | ConvertFrom-Json $accessToken = $obj.data.accessToken $appId = $obj.data.appId Write-Host "Got accessToken (len=$($accessToken.Length)), appId=" } catch { Write-Host "token parse error: $($_.Exception.Message)" } } if ($accessToken) { $authHeader = @{ "X-Access-Token" = $accessToken } # 3.3 access-token (carrier) $b = @{ appId=$appId; chanKey=$chanKey } | ConvertTo-Json -Compress Call-Api -Label "V3-access-token" -Url "$base/openapi/v3/query/access-token" -Headers $authHeader -BodyJson $b # 3.4 sim-info $b = @{ appId=$appId; iccid=$iccid } | ConvertTo-Json -Compress Call-Api -Label "V3-sim-info" -Url "$base/openapi/v3/query/sim-info" -Headers $authHeader -BodyJson $b # 3.5 sim-limit $b = @{ appId=$appId; iccid=$iccid } | ConvertTo-Json -Compress Call-Api -Label "V3-sim-limit" -Url "$base/openapi/v3/query/sim-limit" -Headers $authHeader -BodyJson $b # 3.6 sim-imei $b = @{ appId=$appId; iccid=$iccid } | ConvertTo-Json -Compress Call-Api -Label "V3-sim-imei" -Url "$base/openapi/v3/query/sim-imei" -Headers $authHeader -BodyJson $b # 3.7 sim-usage $b = @{ appId=$appId; iccid=$iccid } | ConvertTo-Json -Compress Call-Api -Label "V3-sim-usage" -Url "$base/openapi/v3/query/sim-usage" -Headers $authHeader -BodyJson $b } else { Write-Host "[skip] no accessToken; skipping V3 authenticated endpoints" } # ===== V1+V2 ===== $verify = @{ timeStamp = $ts password = $appSecret appId = $appKey sign = "" } # 3.1 cardInfo $b = @{ Param = @{ type="iccid"; cardno=$iccid }; verify = $verify } | ConvertTo-Json -Depth 6 -Compress Call-Api -Label "V1V2-cardInfo" -Url "$base/route/open/cardInfo" -BodyJson $b # 3.2 simDataUsage $b = @{ Param = @{ iccid=$iccid }; verify = $verify } | ConvertTo-Json -Depth 6 -Compress Call-Api -Label "V1V2-simDataUsage" -Url "$base/route/open/simDataUsage" -BodyJson $b # 3.3 simDataUsageMonthly $b = @{ Param = @{ iccid=$iccid; dateTime="2025-09-14" }; verify = $verify } | ConvertTo-Json -Depth 6 -Compress Call-Api -Label "V1V2-simDataUsageMonthly" -Url "$base/route/open/simDataUsageMonthly" -BodyJson $b # 3.4 simStatus $b = @{ Param = @{ iccid=$iccid }; verify = $verify } | ConvertTo-Json -Depth 6 -Compress Call-Api -Label "V1V2-simStatus" -Url "$base/route/open/simStatus" -BodyJson $b # 3.5 simSession $b = @{ Param = @{ iccid=$iccid }; verify = $verify } | ConvertTo-Json -Depth 6 -Compress Call-Api -Label "V1V2-simSession" -Url "$base/route/open/simSession" -BodyJson $b # 3.6 queryCardInfoList $b = @{ Param = @{ iccid = @($iccid) }; verify = $verify } | ConvertTo-Json -Depth 6 -Compress Call-Api -Label "V1V2-queryCardInfoList" -Url "$base/route/open/queryCardInfoList" -BodyJson $b Write-Host "" Write-Host "==== DONE ===="