# PlayFab: EconomyV2

Sample PlayFab EconomyV2 Azure Cloud Functions

These samples push PlayFab real-money and paid-purchase events to the Creator Code attribution endpoint from an Azure Cloud Function, so purchases are attributed to creators.

## Azure Functions

### Prerequisites

1. [Nexus Support-a-Creator Getting Started Guide](/api-quick-start-guide/)
2. [PlayFab Azure Cloud Functions Quick Start Guide](https://docs.microsoft.com/en-us/gaming/playfab/features/automation/cloudscript-af/quickstart)

### Example functions

<Tabs syncKey="lang">
<TabItem label="JavaScript">
```javascript
handlers.PushToNexus = function (args) 
{
    const requiredFields = ['creatorCode', 'transactionCurrency', 'transactionAmount', 'transactionID'];

    for (let field of requiredFields) 
    {
        if (!args[field]) 
        {
            log.error(`Missing required field: ${field}`);
            return;
        }
    }

    const contentBody = 
    {
        creatorId: args.creatorCode,
        playerName: args.playerName || "Unknown Player",
        currency: args.transactionCurrency,
        description: args.transactionName || "No Description",
        subtotal: args.transactionAmount,
        transactionId: args.transactionID,
        transactionDate: new Date().toISOString(),
    };

    const contentType = "application/json";
    const headers = 
    {
        'X-SHARED-SECRET': 'nexus_sk_your_key_here'
    };
    const url = "https://api.nexus-dev.gg/v1/attributions/transactions";

    try 
    {
        const response = http.request(url, "POST", JSON.stringify(contentBody), contentType, headers);
        if (response.status >= 200 && response.status < 300) 
        {
            log.debug("Success:", response.body);
        } 
        else 
        {
            log.error("HTTP Error:", response.status, response.body);
        }
        return response;
    } 
    catch (error) 
    {
        log.error("Request failed:", error);
        return null;
    }
};
```
</TabItem>

<TabItem label="C#">
```csharp
using PlayFab;
using PlayFab.ServerModels;
using System;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;

public class PlayFabCloudScript
{
    private static readonly HttpClient httpClient = new HttpClient();

    public static object PushToNexus(ExecuteFunctionRequest args)
    {
        var requiredFields = new[] { "creatorCode", "transactionCurrency", "transactionAmount", "transactionID" };

        foreach (var field in requiredFields)
        {
            if (!args.FunctionParameter.ContainsKey(field) || args.FunctionParameter[field] == null)
            {
                PlayFabServerAPI.WritePlayerEvent(new WriteServerPlayerEventRequest
                {
                    EventName = "error",
                    Body = new Dictionary<string, object> { { "message", $"Missing required field: {field}" } }
                });
                return null;
            }
        }

        var contentBody = new
        {
            creatorId = args.FunctionParameter["creatorCode"],
            playerName = args.FunctionParameter.ContainsKey("playerName") ? args.FunctionParameter["playerName"] : "Unknown Player",
            currency = args.FunctionParameter["transactionCurrency"],
            description = args.FunctionParameter.ContainsKey("transactionName") ? args.FunctionParameter["transactionName"] : "No Description",
            subtotal = args.FunctionParameter["transactionAmount"],
            transactionId = args.FunctionParameter["transactionID"],
            transactionDate = DateTime.UtcNow.ToString("o")
        };

        var contentJson = JsonConvert.SerializeObject(contentBody);
        var content = new StringContent(contentJson, Encoding.UTF8, "application/json");
        var request = new HttpRequestMessage(HttpMethod.Post, "https://api.nexus-dev.gg/v1/attributions/transactions")
        {
            Content = content
        };
        request.Headers.Add("X-SHARED-SECRET", "nexus_sk_your_key_here");

        try
        {
            var response = httpClient.SendAsync(request).Result;
            var responseBody = response.Content.ReadAsStringAsync().Result;

            if (response.IsSuccessStatusCode)
            {
                PlayFabServerAPI.WritePlayerEvent(new WriteServerPlayerEventRequest
                {
                    EventName = "debug",
                    Body = new Dictionary<string, object> { { "message", "Success" }, { "response", responseBody } }
                });
            }
            else
            {
                PlayFabServerAPI.WritePlayerEvent(new WriteServerPlayerEventRequest
                {
                    EventName = "error",
                    Body = new Dictionary<string, object> { { "message", "HTTP Error" }, { "statusCode", response.StatusCode }, { "response", responseBody } }
                });
            }

            return responseBody;
        }
        catch (Exception ex)
        {
            PlayFabServerAPI.WritePlayerEvent(new WriteServerPlayerEventRequest
            {
                EventName = "error",
                Body = new Dictionary<string, object> { { "message", "Request failed" }, { "exception", ex.Message } }
            });
            return null;
        }
    }
}
```
</TabItem>
</Tabs>

Both samples call the attribution endpoint:

<ApiMethod method="POST" path="/attributions/transactions" />
<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/creatorattribution/" />
<LinkCard title="API quick-start guide" description="Set up your keys and your program before you wire up these functions." href="/api-quick-start-guide/" />

## PlayFab events

### Handling real-money purchases in PlayFab

PlayFab exposes two events you can send to Nexus:

1. **`player_realmoney_purchase`**: fires when a player makes a real-money purchase and carries the amount, currency, and transaction details. Use it to attribute real-money purchases to creators.
2. **`player_paid_for_purchase`**: fires when a player completes a purchase and also covers in-game-currency purchases, so it can attribute both real-money and virtual-currency transactions.

### Choosing the right event

Choose between `player_realmoney_purchase` and `player_paid_for_purchase` based on which purchases you attribute:

* **Use `player_realmoney_purchase`**: If your creator program requires tracking and rewarding creators solely based on real-money transactions, this event is the best choice. It ensures that only actual monetary purchases are captured and processed, aligning with scenarios where real-money revenue is the primary focus.
* **Use `player_paid_for_purchase`**: If your creator program needs to handle a broader range of transactions, including both real-money and in-game currency purchases, this event offers greater flexibility. It allows Nexus to process all types of purchases, making it ideal for scenarios where virtual currency transactions are also relevant for creator rewards or attribution.

<LinkCard title="PlayFab: player_paid_for_purchase event" description="Microsoft Learn reference for the player_paid_for_purchase PlayStream event." href="https://learn.microsoft.com/en-us/gaming/playfab/api-references/events/player-paid-for-purchase" />

<LinkCard title="PlayFab: player_realmoney_purchase event" description="Microsoft Learn reference for the player_realmoney_purchase PlayStream event." href="https://learn.microsoft.com/en-us/gaming/playfab/api-references/events/player-realmoney-purchase" />
