Shopee.Affiliate
1.1.2
dotnet add package Shopee.Affiliate --version 1.1.2
NuGet\Install-Package Shopee.Affiliate -Version 1.1.2
<PackageReference Include="Shopee.Affiliate" Version="1.1.2" />
<PackageVersion Include="Shopee.Affiliate" Version="1.1.2" />
<PackageReference Include="Shopee.Affiliate" />
paket add Shopee.Affiliate --version 1.1.2
#r "nuget: Shopee.Affiliate, 1.1.2"
#:package Shopee.Affiliate@1.1.2
#addin nuget:?package=Shopee.Affiliate&version=1.1.2
#tool nuget:?package=Shopee.Affiliate&version=1.1.2
Shopee.Affiliate
A lightweight, strongly typed .NET SDK for Shopee Affiliate Open Platform APIs.
Small .NET SDK for Shopee Affiliate Open API workflows.
Maintained by Greco Labs.
Shopee.Affiliate helps affiliate bots, deal monitors, content automations, and back-office tools turn Shopee product URLs into affiliate-ready links while optionally enriching the response with product offer data.
What It Does
| Capability | Description |
|---|---|
| Affiliate links | Converts Shopee product URLs into affiliate short links through generateShortLink. |
| Product offers | Queries affiliate product offer data through productOfferV2 when product identifiers are available. |
| Product metadata | Extracts title, image URL, product URL, current price, discount rate, and offer link from the API response. |
| Original price estimate | Calculates an approximate original price from priceMin and priceDiscountRate. |
| URL parsing | Extracts shopId and itemId from common Shopee URL formats. |
| Short URL resolving | Follows Shopee short URLs before trying product offer lookup. |
| Affiliate reports | Lists conversions, aggregates a sales summary, and exposes click/link-usage metrics through conversionReport (see Affiliate reports). |
Installation
After the package is published to NuGet:
dotnet add package Shopee.Affiliate
To build from source:
git clone https://github.com/gregojoao/shopee-affiliate.git
cd shopee-affiliate
dotnet restore
dotnet test
dotnet pack -c Release
The package is generated at:
src/Shopee.Affiliate/bin/Release/Shopee.Affiliate.<version>.nupkg
Quick Start
using Shopee.Affiliate.Application;
var options = new ShopeeAffiliateOptions
{
AppId = Environment.GetEnvironmentVariable("SHOPEE_AFFILIATE_APP_ID")!,
Secret = Environment.GetEnvironmentVariable("SHOPEE_AFFILIATE_SECRET")!,
SubIds = new[] { "telegram", "bot" }
};
using var httpClient = new HttpClient();
var client = new ShopeeAffiliateClient(httpClient, options);
var result = await client.GenerateAffiliateLinkAsync(new ShopeeAffiliateLinkRequest
{
OriginUrl = new Uri("https://shopee.com.br/product/627750190/23798776965")
});
Console.WriteLine(result.AffiliateUrl);
Console.WriteLine(result.Source);
Console.WriteLine(result.Product?.ProductTitle);
Console.WriteLine(result.Product?.ProductPrice);
Console.WriteLine(result.Product?.ProductOriginalPrice);
Console.WriteLine(result.Product?.ProductImageUrl);
Configuration
You can pass credentials manually:
using System.Globalization;
using Shopee.Affiliate.Application;
var options = new ShopeeAffiliateOptions
{
AppId = "your-app-id",
Secret = "your-secret",
Endpoint = ShopeeAffiliateOptions.DefaultEndpoint,
SubIds = new[] { "campaign", "channel" },
Timeout = TimeSpan.FromSeconds(90),
PriceCulture = CultureInfo.GetCultureInfo("pt-BR")
};
For ASP.NET Core, Worker Services, or any app using Microsoft.Extensions.DependencyInjection, register the SDK once:
using Shopee.Affiliate.Infrastructure;
builder.Services.AddShopeeAffiliate(builder.Configuration);
Then configure secrets through environment variables, user secrets, Key Vault, or any other configuration provider:
{
"Shopee": {
"Affiliate": {
"AppId": "your-app-id",
"Secret": "your-secret",
"SubIds": [ "campaign", "channel" ],
"Timeout": "00:01:30",
"PriceCulture": "pt-BR"
}
}
}
In production, prefer environment variables or a secret manager instead of committing secrets to appsettings.json.
After registration, inject the client:
using Shopee.Affiliate.Application;
public sealed class DealPublisher(IShopeeAffiliateClient shopee)
{
public async Task PublishAsync(string productUrl)
{
var result = await shopee.GenerateAffiliateLinkAsync(new ShopeeAffiliateLinkRequest
{
OriginUrl = new Uri(productUrl)
});
Console.WriteLine(result.AffiliateUrl);
}
}
You can also configure options directly in code:
using Shopee.Affiliate.Infrastructure;
builder.Services.AddShopeeAffiliate(options =>
{
options.AppId = builder.Configuration["SHOPEE_AFFILIATE_APP_ID"]!;
options.Secret = builder.Configuration["SHOPEE_AFFILIATE_SECRET"]!;
options.SubIds = new[] { "telegram", "bot" };
});
| Option | Default | Purpose |
|---|---|---|
Endpoint |
https://open-api.affiliate.shopee.com.br/graphql |
Shopee Affiliate Open API endpoint for Brazil. |
AppId |
Empty | Shopee Affiliate API app ID. |
Secret |
Empty | Shopee Affiliate API secret used for request signing. |
SubIds |
Empty | Default tracking IDs sent to Shopee when a request does not provide its own SubIds. |
Timeout |
00:01:30 |
Request timeout. |
PriceCulture |
pt-BR |
Culture used to format currency strings. |
Per-call behavior lives on request objects:
| Request Property | Default | Purpose |
|---|---|---|
ShopeeAffiliateLinkRequest.ResolveShortUrls |
true |
Resolves short URLs before product offer lookup. |
ShopeeAffiliateLinkRequest.Strategy |
PreferProductOffer |
Chooses product offer, short link, or product-offer-only behavior. |
SubIds |
Empty | Optional tracking IDs for this call. When empty, the client uses ShopeeAffiliateOptions.SubIds. |
Main APIs
Use IShopeeAffiliateClient when credentials are registered through DI. Use ShopeeAffiliateClient directly when you want to provide ShopeeAffiliateOptions in code.
GenerateAffiliateLinkAsync
High-level helper for the usual bot workflow. It tries to extract product identifiers, query the affiliate product offer, and return the best affiliate URL available.
ShopeeAffiliateLinkResult result = await client.GenerateAffiliateLinkAsync(new ShopeeAffiliateLinkRequest
{
OriginUrl = new Uri(url),
Strategy = ShopeeAffiliateLinkStrategy.PreferProductOffer
});
Available strategies:
| Strategy | Behavior |
|---|---|
PreferProductOffer |
Tries productOfferV2; falls back to generateShortLink if the product offer lookup fails or returns no offer link. |
ShortLinkOnly |
Calls generateShortLink directly. |
ProductOfferOnly |
Requires a valid product offer link and throws ShopeeAffiliateApiException when it is unavailable. |
GenerateShortLinkAsync
Calls generateShortLink directly.
ShopeeShortLinkResult result = await client.GenerateShortLinkAsync(new ShopeeShortLinkRequest
{
OriginUrl = new Uri(url)
});
Console.WriteLine(result.ShortLink);
GetProductOfferAsync
Calls productOfferV2 directly for a known product identity.
using Shopee.Affiliate.Domain;
var identity = new ShopeeAffiliateProductIdentity(
ShopId: "627750190",
ItemId: "23798776965");
ShopeeProductOffer? offer = await client.GetProductOfferAsync(new ShopeeProductOfferRequest
{
ProductIdentity = identity
});
Console.WriteLine(offer?.ProductTitle);
ResolveShopeeUrlAsync
Follows redirects for Shopee short URLs and returns the final URL when possible.
Uri resolvedUrl = await client.ResolveShopeeUrlAsync(new Uri(shortUrl));
Credential errors
The link client throws ShopeeAffiliateCredentialException when Shopee rejects
Affiliate/Open API credentials. It derives from ShopeeAffiliateApiException, so
existing catch blocks keep working, while callers that need to distinguish
credential failures can catch the more specific type.
try
{
ShopeeShortLinkResult result = await client.GenerateShortLinkAsync(new ShopeeShortLinkRequest
{
OriginUrl = new Uri(url)
});
}
catch (ShopeeAffiliateCredentialException ex) when (!ex.IsRetryable)
{
// Disable the credential, alert the operator, or route to reconfiguration.
Console.WriteLine($"{ex.Platform}: {ex.Kind} ({ex.ProviderErrorCode})");
}
catch (ShopeeAffiliateApiException)
{
// Generic GraphQL, HTTP 5xx, timeout, rate-limit, or other API failure.
throw;
}
| Property | Value |
|---|---|
Platform |
Always "shopee". |
Kind |
Invalid, Expired, Unauthorized, or Forbidden. |
StatusCode |
HTTP status when Shopee rejects at the transport layer (401/403). |
ProviderErrorCode |
Shopee GraphQL error code when available, such as 10020. |
ProviderMessage |
Safe, truncated provider message when available. |
IsCredentialError |
Always true. |
IsRetryable |
Always false. |
Affiliate reports
Shopee.Affiliate.Reports.ShopeeAffiliateReportsClient exposes the reporting
surface of the Shopee Affiliate Open API. It signs every call with the same
SHA256 scheme as the link client, posts to the GraphQL endpoint, and returns
strongly-typed DTOs.
Register it the same way you register the link client:
using Shopee.Affiliate.Infrastructure;
builder.Services.AddShopeeAffiliateReports(builder.Configuration);
// or:
builder.Services.AddShopeeAffiliateReports(options =>
{
options.AppId = builder.Configuration["SHOPEE_AFFILIATE_APP_ID"]!;
options.Secret = builder.Configuration["SHOPEE_AFFILIATE_SECRET"]!;
});
Configuration section (defaults Shopee:Affiliate:Reports):
{
"Shopee": {
"Affiliate": {
"Reports": {
"AppId": "your-app-id",
"Secret": "your-secret",
"Endpoint": "https://open-api.affiliate.shopee.com.br/graphql",
"Timeout": "00:00:30"
}
}
}
}
Then inject IShopeeAffiliateReportsClient:
using Shopee.Affiliate.Reports;
public sealed class DashboardService(IShopeeAffiliateReportsClient reports)
{
public async Task<ShopeeSalesSummary> LoadSummaryAsync(DateTimeOffset from, DateTimeOffset to, CancellationToken ct)
{
var conversions = await reports.ListConversionsAsync(new ListShopeeConversionsRequest(
From: from,
To: to,
Status: ShopeeConversionStatusFilter.All,
PageSize: 200), ct);
return await reports.GetSalesSummaryAsync(new ShopeeSalesSummaryRequest(from, to), ct);
}
}
Methods
| Method | GraphQL query | Notes |
|---|---|---|
ListConversionsAsync |
conversionReport |
Cursor pagination via scrollId (expires ~30s). Page is honoured as a convenience by scrolling forward internally. |
GetConversionAsync |
conversionReport(orderId: ...) |
Throws ShopeeAffiliateNotFoundException if no row is returned. |
GetSalesSummaryAsync |
conversionReport (full window) |
Client-side aggregation over every page; Clicks and ConversionRate are always null. |
GetClickStatsAsync |
none | Always returns Supported=false — Shopee does not expose a click endpoint. |
GetGeneratedLinkUsageAsync |
none | Always returns Supported=false — Shopee does not expose link-generation counters. |
Exceptions
All reporting exceptions derive from Shopee.Affiliate.Infrastructure.ShopeeAffiliateException:
| Exception | Trigger |
|---|---|
ShopeeAffiliateAuthException |
Shopee error codes 10020, 10031, 10032, 10033, 10034, 10035 or HTTP 401/403. |
ShopeeAffiliateRateLimitException |
Shopee error code 10030 or HTTP 429. |
ShopeeAffiliateNotFoundException |
Empty conversionReport result for a point lookup. |
ShopeeAffiliateApiException |
Any other GraphQL error (Code, Path, RequestId populated). |
ShopeeAffiliateUnsupportedException |
Reserved for future opt-in hard failures on Supported=false paths. |
Limits and conventions
- Time zone. Shopee operates in
GMT+7. The SDK acceptsDateTimeOffsetso the caller's offset is preserved; the wire format is Unix-seconds. - Maximum window.
conversionReportaccepts at most ~90 days betweenFromandTo. Wider windows are rejected by Shopee with error code11001("Params Error : can only query data for the last 3 months"), surfaced asShopeeAffiliateApiException. Split larger ranges into chunks of ≤ 90 days. - Page size. Capped at
500(Shopee server limit). - Cursor TTL.
scrollIdvalues expire ~30 seconds after issue; resume on fresh windows or restart from page 1 if the cursor is rejected. - Retries. A single automatic retry on HTTP 5xx and request timeouts. HTTP 4xx surfaces immediately.
- Currency.
Money.Currencyis preserved verbatim from Shopee — no conversion happens inside the SDK.
The GraphQL surface used by 1.1.0 is documented at https://www.affiliateshopee.com.br/documentacao.
Architecture
The SDK is organized with a small DDD-inspired structure:
| Layer | Responsibility |
|---|---|
Domain |
Product identity parsing, price formatting, and affiliate offer value objects. |
Application |
Public use cases and service abstractions such as ShopeeAffiliateClient, IShopeeAffiliateClient, requests, options, and results. |
Infrastructure |
GraphQL payloads, Shopee authentication, response mapping, HTTP integration, exceptions, and DI registration. |
Public namespaces follow the physical project structure: use Shopee.Affiliate.Application for clients/options/results, Shopee.Affiliate.Domain for value objects, and Shopee.Affiliate.Infrastructure for DI registration and infrastructure exceptions.
Returned Data
ShopeeAffiliateLinkResult contains:
| Property | Description |
|---|---|
AffiliateUrl |
Best affiliate URL returned by the SDK. |
Source |
Indicates whether the affiliate URL came from ProductOffer or ShortLink. |
ResolvedOriginUrl |
URL after redirect resolution, when resolution was requested. |
Product |
Normalized product offer data, when product offer lookup succeeds. |
ShopeeProductOffer contains:
| Property | Description |
|---|---|
AffiliateUrl |
Product offer affiliate URL. |
ProductTitle |
Product title. |
ProductPrice |
Formatted current price or price range. |
ProductOriginalPrice |
Estimated original price when discount data is available. |
ProductImageUrl |
Product image URL. |
ProductUrl |
Canonical product URL from Shopee. |
ItemId / ShopId |
Shopee product identifiers. |
Supported URL Formats
The SDK can extract shopId and itemId from these common formats:
https://shopee.com.br/product/{shopId}/{itemId}
https://shopee.com.br/{slug}-i.{shopId}.{itemId}
https://shopee.com.br/opaanlp/{shopId}/{itemId}
https://shopee.com.br/...?...shopid={shopId}&itemid={itemId}
When ShopeeAffiliateLinkRequest.ResolveShortUrls is enabled, short URLs are resolved before product identity extraction.
Authentication
Requests are signed with SHA-256:
Authorization: SHA256 Credential={AppId}, Timestamp={Timestamp}, Signature={Signature}
Signature = SHA256(AppId + Timestamp + Payload + Secret)
Timestamp is Unix time in seconds. Payload must be the exact JSON body sent to the GraphQL endpoint.
API Notes
Shopee's official Help Center says the Affiliate API can retrieve Shopee, brand, and product offer lists, generate short links, and retrieve conversion reports:
https://help.shopee.sg/portal/10/article/191702-API-Access
For Brazil, the affiliate Open API is exposed as GraphQL. Publicly available documentation and existing integrations use:
productOfferV2generateShortLink
Important: the public affiliate schema used by this SDK does not expose a dedicated "old price" field. ProductOriginalPrice is calculated with:
original = current / (1 - discountRate / 100)
This is useful for promotion messages, but it can differ slightly from Shopee's displayed price because priceDiscountRate may be rounded.
Development
dotnet restore
dotnet test
dotnet pack -c Release
Publishing
Before publishing a new NuGet version:
- Update
<Version>and<PackageReleaseNotes>insrc/Shopee.Affiliate/Shopee.Affiliate.csproj. - Run the validation:
dotnet test
dotnet pack -c Release
- Push the package:
dotnet nuget push src/Shopee.Affiliate/bin/Release/Shopee.Affiliate.*.nupkg --api-key "$NUGET_API_KEY" --source https://api.nuget.org/v3/index.json
See PUBLISHING.md for the full release checklist.
License
This project is licensed under the MIT License. See LICENSE for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
-
net8.0
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
1.1.1 adds ShopeeAffiliateCredentialException for rejected Shopee Affiliate/Open API credentials, while preserving existing ShopeeAffiliateApiException behavior for temporary, rate-limit, and generic GraphQL failures.