# 记录 transaction 事件

> Track in-app purchases and failed transactions to measure revenue and monitor transaction health.

使用 `transaction` 事件可以跟踪成功的应用内购。此事件包含的数组和一些特殊 `Product` 对象可以捕获在单个交易中购买的多个物品和游戏币。transaction 事件的结构包含多个 `Product` 对象以记录 `productsSpent` 和 `productsReceived`。

不成功的交易在专用的 `transactionFailed` 事件下进行跟踪，其中包含有关购买交易的详细信息以及交易失败的原因。后台中的收入指标不会受此影响。

您可以通过 SDK 或 REST API 手动发送 `transaction` 和 `transactionFailed` 事件。如果使用的是 [Unity IAP](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/manual/Overview.html) 4.2 或更高版本，则会自动发送这些事件。

**重要**：如果还使用了 IAP 插件，则手动将交易发送到 Analytics 会导致交易被计数两次并报告虚高的收入。

> **Warning:**
>
> **重要**：您可以在 **Analytics** > \*\*SQL Data Explorer（SQL 数据资源管理器）\*\*工具中查看由于 Apple 和 Google **沙盒购买**而收到的 transaction 事件，但这些事件不会影响后台的 Revenue（收入）报告。

### 手动发送事件##record-automatically-using-the-iap-plug-in

`transaction` 和 `transactionFailed` 事件是具有预定义架构的标准事件，您必须匹配这些架构才能在后台中的收入 KPI 下处理和跟踪事件。您可以在 [Event Manager（事件管理器）](event-manager)文档中参考事件的架构。

## 报告成功的购买##send-events-manually

在以下示例中，`transaction` 事件记录玩家使用真实美元购买包含虚拟货币和多个物品的宝箱。如需有关此事件和参数的详细信息，请参阅 [Event Manager（事件管理器）](event-manager)。

使用以下代码创建 `transaction` 事件：

```cs
public void SendTransaction()
{
	var productsReceived = new Product()
	{
		Items = new List<Item>()
		{
			new Item(){ ItemName = "Golden Battle Axe"      , ItemType = "Weapon", ItemAmount = 1},
			new Item(){ ItemName = "Flaming Sword"          , ItemType = "Weapon", ItemAmount = 1},
			new Item(){ ItemName = "Jewel Encrusted Shield" , ItemType = "Armour", ItemAmount = 1}
		},
		VirtualCurrencies = new List<VirtualCurrency>()
		{
			new VirtualCurrency()
			{
				VirtualCurrencyName = "Gold",
				VirtualCurrencyType = "PREMIUM",
				VirtualCurrencyAmount = 100
			}
		}
	};

	var productsSpent = new Product()
	{
		RealCurrency = new RealCurrency()
		{
			RealCurrencyType = "USD",
			RealCurrencyAmount = 499
		}
	};

	AnalyticsService.Instance.Transaction(new TransactionParameters()
	{
		ProductsReceived = productsReceived,
		ProductsSpent = productsSpent,
		TransactionID = "100000576198248",
		TransactionName = "IAP - A Large Treasure Chest",
		TransactionType = TransactionType.PURCHASE,
		TransactionServer = TransactionServer.APPLE,
		TransactionReceipt = "ewok9Ja81............991KS=="
	});
}
```

## 报告失败的购买##validate-transactions

`transactionFailed` 事件可以捕获不成功的应用内购。购买失败可能有多种原因，包括网络故障、付款失败或设备设置。

在以下示例中，`transactionFailed` 事件记录玩家尝试使用真实美元购买包含虚拟货币和多个物品的宝箱，但用户随即取消购买。如需有关此事件和参数的详细信息，请参阅 [Event Manager（事件管理器）](event-manager)的文档。

使用以下代码创建 `transactionFailed` 事件：

```cs
public void SendTransactionFailed()
{
	var productsReceived = new Product()
	{
		items = new List<Item>()
		{
			new Item(){ ItemName = "Golden Battle Axe"      , ItemType = "Weapon", ItemAmount = 1},
			new Item(){ ItemName = "Flaming Sword"          , ItemType = "Weapon", ItemAmount = 1},
			new Item(){ ItemName = "Jewel Encrusted Shield" , ItemType = "Armour", ItemAmount = 1}
		},
		VirtualCurrencies = new List<VirtualCurrency>()
		{
			new VirtualCurrency()
			{
				VirtualCurrencyName = "Gold",
				VirtualCurrencyType = "PREMIUM",
				VirtualCurrencyAmount = 100
			}
		}
	};

	var productsSpent = new Product()
	{
		RealCurrency = new RealCurrency()
		{
			RealCurrencyType = "USD",
			RealCurrencyAmount = 499
		}
	};

	AnalyticsService.Instance.TransactionFailed(new TransactionFailedParameters 
	{
		FailureReason = "cancelled",
		ProductsReceived = productsReceived,
		ProductsSpent = productsSpent,
		TransactionID = "100000576198248",
		TransactionName = "IAP - A Large Treasure Chest",
		TransactionType = TransactionType.PURCHASE,
		TransactionServer = TransactionServer.APPLE
	});
}
```

## 使用 IAP 插件自动记录

通过 [Unity IAP](https://docs.unity3d.com/Packages/com.unity.purchasing@latest?subfolder=/manual/Overview.html) 进行的交易自动转发到 Analytics，使用与手动发送事件时相同的 `transaction` 事件架构。transaction 事件会影响 Analytics 中提供的收入 KPI。不成功的交易由 `transactionFailed` 事件下的 IAP 插件自动跟踪。

## 验证交易

交易验证会检查交易是否为合法购买。

平台可以对 iOS 和 Android 商店进行交易收据验证，以确保后台中显示的任何收入都是真正的收入，而不是游戏被黑客劫持或越狱后的结果。

为了使用交易验证，您需要：

* 提供相关商店的验证密钥，以便 Analytics 平台可以针对商店验证收据。您可以在 [Dashboard（后台）](https://dashboard.unity3d.com/)的 \*\*Project Settings（项目设置）\*\*下执行此操作。
* 在 `transaction` 事件中包含收据验证参数，以便通知平台需要验证交易（这将因商店而异）。

transaction 事件包含一个供 IAP 收据验证服务使用的 `revenueValidated` 参数；如果您使用了收入验证，则会自动填充此参数。可用的值为：

| 值 | 结果                        |
| - | ------------------------- |
| 0 | 此交易未使用收入验证服务，包含在您的收入图表中。  |
| 1 | 此交易已通过验证，包含在您的收入图表中。      |
| 2 | 此交易未通过验证，不包含在您的收入图表中。     |
| 3 | 此交易由于错误而无法验证，不包含在您的收入图表中。 |

### Apple 商店##report-successful-purchases

Analytics 会自动尝试对 iOS 交易进行收据验证。请将以下代码添加到 iOS 交易以验证收据：

```plaintext
"transactionServer": "APPLE",
"transactionID":"100000576198248",
"transactionReceipt": "ewok9Ja81............991KS=="
```

`transactionReceipt ` 是从 Apple 返回的 BASE 64 编码收据数据。请参阅 Apple 开发者网站，了解有关 [Apple 收据验证](https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html)的详细信息。

### Google Play##report-failed-purchases

您必须提供 Google 公钥。要更新 Google 密钥，请转到 **Project Settings（项目设置）**> **In-app purchase (IAP) settings（应用内购 (IAP) 设置）**，然后填充 Google 许可证密钥。

请将以下代码添加到 Android 交易的 transaction 事件中以验证收据：

```plaintext
"transactionServer":"GOOGLE",
"transactionReceipt":"{
	\"orderId\":\"GPA.1234-5678-9012-34567\",
	\"packageName\":\"com.example.app\",
	\"productId\":\"exampleSku\",
	\"purchaseTime\":1345678900000,
	\"purchaseState\":0,
	\"developerPayload\":\"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ\",
	\"purchaseToken\":\"opaque-token-up-to-1000-characters\"
}", 
"transactionReceiptSignature":"rNvoHwiBdLSW+........VncbYVJ61fmfsQ=="
```

**重要**：由于交易收据和私钥会生成 `transactionReceiptSignature`，为了验证收据，其必须是 Google 提供的确切字符串，并作为字符串（而不是嵌套的 JSON 对象）传递。
