diff --git a/server/src/Hokm.Server/Payments/IabService.cs b/server/src/Hokm.Server/Payments/IabService.cs index 43ac2ff..36d8771 100644 --- a/server/src/Hokm.Server/Payments/IabService.cs +++ b/server/src/Hokm.Server/Payments/IabService.cs @@ -110,19 +110,26 @@ public sealed class IabService } /// - /// Myket: validate via the developer API (mirrors Google Play). The access - /// token comes from the Myket developer panel. + /// Myket: validate via the developer API. POST the purchase token in the body + /// (`{ "tokenId": ... }`) to the partners/verify endpoint with an X-Access-Token + /// header. The access token comes from the Myket developer panel → in-app + /// products. See https://myket.ir/kb/pages/server-to-server-payment-validation-api/ /// private async Task VerifyMyket(string productId, string token) { if (string.IsNullOrWhiteSpace(_opts.MyketAccessToken)) return _opts.AllowUnverified; - var url = $"https://developer.myket.ir/api/applications/{_opts.PackageName}/purchases/products/{Uri.EscapeDataString(productId)}/tokens/{Uri.EscapeDataString(token)}"; - using var req = new HttpRequestMessage(HttpMethod.Get, url); + var url = $"https://developer.myket.ir/api/partners/applications/{_opts.PackageName}/purchases/products/{Uri.EscapeDataString(productId)}/verify"; + using var req = new HttpRequestMessage(HttpMethod.Post, url); req.Headers.Add("X-Access-Token", _opts.MyketAccessToken); + req.Content = new StringContent( + JsonSerializer.Serialize(new { tokenId = token }), + System.Text.Encoding.UTF8, + "application/json"); var resp = await Http.SendAsync(req); if (!resp.IsSuccessStatusCode) return false; using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync()); + // purchaseState: 0 = successful purchase, 1 = failed. if (doc.RootElement.TryGetProperty("purchaseState", out var ps) && ps.ValueKind == JsonValueKind.Number) return ps.GetInt32() == 0; return true;