# Make IAP Purchases In-Game

In this how-to, we will implement the purchase flow for Stripe purchases using LootLocker.

### Prerequisites

* [A LootLocker account](https://lootlocker.com/sign-up)
* At least one created game in the [LootLocker Web Console](https://console.lootlocker.com/)
* [Stripe IAP settings configured for your game](/commerce/real-money-purchases/how-to/stripe/configure-stripe-iap-settings.md)
* A [Catalog Listing configured for Stripe IAP](/commerce/real-money-purchases/how-to/stripe/configure-catalog-listing-stripe.md)
* [LootLocker SDK integrated](/the-basics/sdks.md) into your game

### Create a Stripe Checkout Session

Unlike traditional platform IAP systems, Stripe purchases are handled by generating a secure checkout link that opens in the player’s browser.

This keeps sensitive payment information outside of your game while giving the player a trusted Stripe checkout experience.

To start the purchase, create a Stripe Checkout Session using the Catalog Listing ID for the item the player wants to buy.

LootLocker will return a unique checkout URL and an entitlement ID for the pending purchase.

{% tabs %}
{% tab title="Unity" %}

```csharp
LootLockerSDKManager.CreateStripeCheckoutSession(catalogItemId, (response) =>
{
    if (response.success)
    {
        Debug.Log("Stripe session created. Link: " + response.checkout_link);
        
        // Open the Stripe checkout page in the user's browser
        Application.OpenURL(response.checkout_link);
        
        // Show a "Purchase in Progress" UI overlay in your game
        purchaseInProgressScreen.SetActive(true);

        // Start polling for the status of this specific entitlement
        StartCoroutine(CheckPurchaseStatusRoutine(response.entitlement_id));
    }
    else
    {
        Debug.LogError("Failed to create session: " + response.errorData.message);
    }
});
```

{% endtab %}

{% tab title="Unreal" %}
Coming soon
{% endtab %}
{% endtabs %}

### Open the Checkout Link

Open the returned Stripe checkout URL in the player’s browser.

{% tabs %}
{% tab title="Unity" %}

```csharp
Application.OpenURL(checkoutLink);
```

{% endtab %}

{% tab title="Unreal" %}
Coming soon
{% endtab %}
{% endtabs %}

At this point, the player completes the payment through Stripe. Since the payment happens outside the game, you should show an in-game purchase-in-progress screen while waiting for the transaction to complete.

### Check the Purchase Status

After opening the Stripe checkout link, use the entitlement ID returned by LootLocker to check the status of the purchase.

Because the player completes payment externally, your game should poll LootLocker until the entitlement is either completed or no longer valid.

We recommend checking the entitlement status every 5 seconds while the purchase is in progress.

{% tabs %}
{% tab title="Unity" %}

```csharp
IEnumerator CheckPurchaseStatusRoutine(string entitlementId)
{
    while (!purchaseCompleted)
    {
        CheckPurchaseStatus(entitlementId);
        yield return new WaitForSeconds(5f); 
    }
}

void CheckPurchaseStatus(string entitlementId)
{
    LootLockerSDKManager.GetEntitlement(entitlementId, (response) =>
    {
        if (response.success)
        {
            if (response.Status == LootLocker.LootLockerEnums.LootLockerEntitlementHistoryListingStatus.Active)
            {
                // Success: The purchase is complete and rewards have been granted
                purchaseInProgressScreen.SetActive(false);
                purchaseCompleted = true;
            }
            else if (IsFailureStatus(response.Status))
            {
                // Player canceled or payment expired
                purchaseInProgressScreen.SetActive(false);
                purchaseCompleted = true;
            }
        }
    });
}
```

{% endtab %}

{% tab title="Unreal" %}
Coming soon
{% endtab %}
{% endtabs %}

### Handle purchase result

Once the entitlement status becomes active, the purchase has been completed and the configured Catalog Listing rewards have been granted to the player.

At this point, update your in-game UI and unlock or display the purchased content.

If the purchase is canceled, expires, or fails: Inform the player, close the purchase-in-progress screen and allow the player to try again.

### Handling Edge Cases

Because Stripe purchases are completed outside of the game, there are several scenarios your game should handle:

* **User closes the browser:** The purchase may still complete. Continue polling the entitlement status until it resolves.
* **Payment fails or is canceled:** The entitlement will not become active. Stop polling and allow the player to retry.
* **Session expires:** The checkout session may expire if not completed in time. Create a new checkout session if needed.
* **Game is not in focus:** The player may return after completing the purchase. Ensure your game resumes polling or refreshes entitlement state.
* **Network interruptions:** Retry entitlement checks to avoid false negatives.

Regardless of what state your game is in, the purchase will go through if the user completes the purchase in their browser.

{% hint style="warning" %}
Stripe purchases are asynchronous. Always rely on the entitlement status from LootLocker as the source of truth.
{% endhint %}

### Conclusion

In this guide, we implemented the purchase flow for Stripe using LootLocker. Players can now start a Stripe checkout session, complete payment in their browser, and receive the configured rewards once LootLocker confirms the purchase.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.lootlocker.com/commerce/real-money-purchases/how-to/stripe/make-purchases-through-stripe.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
