Skip to content

feat: Add async purchase support#436

Open
kirre-bylund wants to merge 2 commits intodevfrom
feat/async-purchases
Open

feat: Add async purchase support#436
kirre-bylund wants to merge 2 commits intodevfrom
feat/async-purchases

Conversation

@kirre-bylund
Copy link
Contributor

Summary

Implements async purchase support for lootlocker/index#1369.

The server-side work is already complete. This PR adds SDK support for the async purchase flow: initiate a purchase, poll its status, and handle the final active/failed outcome — with full auto-polling using the same architecture as the Remote Session feature.

Changes

Runtime/Client/LootLockerEndPoints.cs

  • Added 3 new endpoints under the Purchase header:
    • initiateAsyncPurchasePOST purchase/inspired-ibex/v1
    • pollAsyncPurchaseStatusGET purchase/inspired-ibex/v1/{0}
    • retryAsyncPurchasePOST purchase/inspired-ibex/v1/{0}/retry

Runtime/Game/Requests/PurchaseRequest.cs

  • Added DTOs: LootLockerAsyncPurchaseStatus enum (pending, active, failed), LootLockerAsyncPurchaseInitiatedResponse, LootLockerAsyncPurchaseStatusResponse
  • Added primitive LootLockerAPIManager methods: InitiateAsyncPurchase, GetAsyncPurchaseStatus, RetryAsyncPurchase
  • Added AsyncPurchasePoller : MonoBehaviour, ILootLockerService — coroutine-based auto-polling with:
    • Guid-keyed process dictionary
    • Configurable polling interval (min 1 s, enforced)
    • Configurable timeout
    • Automatic retry on 5xx (up to 5 retries)
    • StatusUpdateCallback on each pending poll, CompletedCallback on active/failed/timeout/cancel
    • Lifecycle management via LootLockerLifecycleManager

Runtime/Game/LootLockerSDKManager.cs

  • Added 7 public facade methods in the #region Purchasing section:
    • InitiateAsyncPurchaseSingleCatalogItem
    • InitiateAsyncPurchaseCatalogItems
    • GetAsyncPurchaseStatus
    • RetryAsyncPurchase
    • InitiateAndPollAsyncPurchaseSingleCatalogItem
    • InitiateAndPollAsyncPurchaseCatalogItems (returns Guid process handle)
    • CancelAsyncPurchasePolling

Testing

Compile Check passed ✅ on this branch.

- Add 3 new endpoints: initiateAsyncPurchase, pollAsyncPurchaseStatus, retryAsyncPurchase
- Add DTOs: LootLockerAsyncPurchaseStatus enum, LootLockerAsyncPurchaseInitiatedResponse,
  LootLockerAsyncPurchaseStatusResponse
- Add primitive API methods: InitiateAsyncPurchase, GetAsyncPurchaseStatus, RetryAsyncPurchase
- Add AsyncPurchasePoller MonoBehaviour service with coroutine-based auto-polling,
  timeout, retry on 5xx, and process lifecycle management
- Add public facade methods to LootLockerSDKManager:
  InitiateAsyncPurchaseSingleCatalogItem, InitiateAsyncPurchaseCatalogItems,
  GetAsyncPurchaseStatus, RetryAsyncPurchase,
  InitiateAndPollAsyncPurchaseSingleCatalogItem,
  InitiateAndPollAsyncPurchaseCatalogItems, CancelAsyncPurchasePolling
@kirre-bylund
Copy link
Contributor Author

Before merging, this needs to be functionally tested

@kirre-bylund kirre-bylund requested review from Copilot and removed request for Copilot March 6, 2026 17:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds SDK support for an async purchase flow (initiate → poll status → retry), including an auto-polling helper service patterned after the existing Remote Session poller.

Changes:

  • Added async purchase endpoints (initiate, status poll, retry).
  • Introduced async purchase DTOs + primitive request methods, plus a coroutine-based poller service for auto-polling.
  • Added public facade methods in LootLockerSDKManager for initiating, polling, retrying, and cancelling polling.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
Runtime/Client/LootLockerEndPoints.cs Adds the three new async purchase endpoints used by the SDK requests.
Runtime/Game/Requests/PurchaseRequest.cs Adds DTOs, request methods, and an AsyncPurchasePoller service to auto-poll async purchases.
Runtime/Game/LootLockerSDKManager.cs Exposes the async purchase flow via public facade methods under the Purchasing region.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

float timeoutAfterMinutes = 5.0f,
string forPlayerWithUlid = null)
{
pollingIntervalSeconds = Math.Max(1.0f, pollingIntervalSeconds);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pollingIntervalSeconds = Math.Max(1.0f, pollingIntervalSeconds); won’t compile because System.Math.Max has no float overload and returns double, which can’t be implicitly assigned to float. Use Mathf.Max(1f, pollingIntervalSeconds) (Unity) or Math.Max(1.0, pollingIntervalSeconds) with an explicit cast back to float.

Suggested change
pollingIntervalSeconds = Math.Max(1.0f, pollingIntervalSeconds);
pollingIntervalSeconds = Mathf.Max(1.0f, pollingIntervalSeconds);

Copilot uses AI. Check for mistakes.
Comment on lines +252 to +256
public enum LootLockerAsyncPurchaseStatus
{
/// <summary>The purchase is still being processed</summary>
pending,
/// <summary>The purchase completed successfully and items have been granted</summary>
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LootLockerAsyncPurchaseStatus is declared inside namespace LootLocker.Requests, but enums in this codebase are consistently placed under namespace LootLocker.LootLockerEnums (e.g., LootLockerNotificationPriority, LootLockerCatalogEntryEntityKind). Consider moving this enum to LootLocker.LootLockerEnums for consistency and discoverability, then update references accordingly.

Copilot uses AI. Check for mistakes.
- Use Mathf.Max instead of Math.Max (float overload issue)
- Move LootLockerAsyncPurchaseStatus enum to LootLocker.LootLockerEnums namespace for consistency
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants