---
title: Contoh Penggunaan API Produk
slug: world-sdk-guide-id/contoh-penggunaan-api-produk
docTags: 
createdAt: 2024-09-02T08:34:13.134Z
---

Berikut adalah contoh penggunaan Product API untuk mengelola Mata Uang Dunia dan Produk Dunia.

Contoh ini memungkinkan Anda untuk mendapatkan pemahaman dasar tentang Product API dan menerapkan pengiriman serta penerimaan pesan antara server dan klien, sehingga Anda dapat dengan mudah menguji pemberian dan pengurangan mata uang dunia dan produk.

Contoh ini mencakup deskripsi dari skrip klien Mata Uang Dunia dan Produk Dunia, diikuti oleh skrip server terintegrasi yang menangani semua pemrosesan sisi server, dan mencakup fungsi-fungsi berikut:

- Pemberian Mata Uang Dunia
- Pengurangan Mata Uang Dunia
- Pemberian Produk Dunia tanpa Pengurangan Mata Uang
- Pengurangan Produk Dunia

![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-LVomjGT16SVteQlTOo7ug-20240904-102419.gif)



## Pemberian & Pengurangan Mata Uang Dunia

Di bawah ini adalah kode klien lengkap untuk mengelola pemberian dan pengurangan mata uang dunia, serta cara mengimplementasikannya.

### Skrip Klien Mata Uang

:::CodeblockTabs
CurrencyManagerSample

```typescript
import { Button, Text } from 'UnityEngine.UI';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { LocalPlayer, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room, RoomData } from 'ZEPETO.Multiplay';
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
 
export default class CurrencyManagerSample extends ZepetoScriptBehaviour {
 
    public currencyId: string;
    public increaseQuantity: number;
    public decreaseQuantity: number;
    public increaseCurrencyBtn: Button;
    public decreaseCurrencyBtn: Button;
    public balanceText: Text;
    public multiplay: ZepetoWorldMultiplay;
 
    private _localPlayer: LocalPlayer;
 
    Start() {
 
        ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
            this._localPlayer = ZepetoPlayers.instance.LocalPlayer;
            this.loadCurrencyBalance(this.currencyId);
        });
 
        // Menangani peristiwa bergabungnya ruangan untuk pembaruan UI mata uang
        this.multiplay.RoomJoined += (room: Room) => {
            room.AddMessageHandler("SyncCurrencyInfo", (message: CurrencyMessage) => {
                const currentCurrencyId = message.currencyId;
                const currentQuantity = message.quantity;
                this.balanceUIUpdate(currentCurrencyId, currentQuantity);
            });
        };
 
        // Pendengar peristiwa tombol untuk meningkatkan mata uang : Permintaan Kredit
        this.increaseCurrencyBtn.onClick.AddListener(() => {
            const data = new RoomData();
            data.Add("currencyId", this.currencyId);
            data.Add("quantity", this.increaseQuantity);
            this.multiplay.Room?.Send("CreditCurrency", data.GetObject());
        })
 
        // Pendengar peristiwa tombol untuk mengurangi mata uang : Permintaan Debit
        this.decreaseCurrencyBtn.onClick.AddListener(() => {
            const data = new RoomData();
            data.Add("currencyId", this.currencyId);
            data.Add("quantity", this.decreaseQuantity);
            this.multiplay.Room?.Send("DebitCurrency", data.GetObject());
        })
 
    }
 
    // Meminta jumlah mata uang yang ditentukan saat ini
    private loadCurrencyBalance(currentCurrencyId: string) {
        this.multiplay.Room?.Send("LoadBalance", currentCurrencyId);
    }
 
    // Memperbarui UI untuk mencerminkan jumlah mata uang saat ini
    private balanceUIUpdate(currentCurrencyId: string, currentQuantity: number) {
        this.balanceText.text = currentQuantity.toString();
    }
 
}
 
// Antarmuka untuk pesan sinkronisasi mata uang
interface CurrencyMessage {
    currencyId: string,
    quantity: number,
}
```
:::



### Deskripsi Skrip Klien Mata Uang

- Ketika karakter dimuat, pesan Ruangan dikirim ke server untuk memuat saldo mata uang yang ada. UI kemudian diperbarui berdasarkan informasi saldo yang diterima dari server.

```typescript
this.multiplay.Room?.Send("LoadBalance", currentCurrencyId);
```

- Untuk memfasilitasi pertukaran pesan, `CurrencyMessage` antarmuka didefinisikan.

```typescript
interface CurrencyMessage {
    currencyId: string,
    quantity: number,
}
```

- Ketika seorang pengguna meningkatkan atau mengurangi mata uang mereka, mereka mengirim permintaan ke server sebagai Pesan Ruangan.
  Ini mencakup data tentang mata uang mana yang akan ditingkatkan atau dikurangi dan seberapa banyak.

```typescript
this.multiplay.Room?.Send("CreditCurrency", data.GetObject());
this.multiplay.Room?.Send("DebitCurrency", data.GetObject());
```

- Server kemudian memproses peningkatan atau pengurangan mata uang dan mengirim informasi saldo akhir ke klien. Klien menerima informasi ini dan memperbarui UI.

[Lihat skrip server lengkap](docId:3m067mdrmuFhbSKEhGrsB)&#x20;


```typescript
this.multiplay.RoomJoined += (room: Room) => {
    room.AddMessageHandler("SyncCurrencyInfo", (message: CurrencyMessage) => {
        const currentCurrencyId = message.currencyId;
        const currentQuantity = message.quantity;
        this.updateBalanceUI(currentCurrencyId, currentQuantity);
    });
};
```



## Memberikan & Mengurangi Produk Dunia

Di bawah ini adalah kode klien lengkap untuk mengelola pemberian dan pengurangan produk dunia, serta cara mengimplementasikannya.

### Skrip Klien Produk

:::CodeblockTabs
ProductManagerSample

```typescript
import { Button, Text } from 'UnityEngine.UI';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { LocalPlayer, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room, RoomData } from 'ZEPETO.Multiplay';
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
import { InventoryRecord, InventoryService } from 'ZEPETO.Inventory';
import { WaitUntil } from 'UnityEngine';
 
export default class ProductManagerSample extends ZepetoScriptBehaviour {
 
    public productId: string;
    public productAddQuantity: number;
    public acquireItemBtn: Button;
    public useItemBtn: Button;
    public itemCountText: Text;
    public multiplay: ZepetoWorldMultiplay;
 
    private _localPlayer: LocalPlayer;
 
    Start() {
 
        ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
            this._localPlayer = ZepetoPlayers.instance.LocalPlayer;
            this.StartCoroutine(this.refreshProductUI());
        });
 
        // Menangani peristiwa bergabung ke ruangan untuk pembaruan UI produk
        this.multiplay.RoomJoined += (room: Room) => {
            room.AddMessageHandler("SyncProductInfo", (message: ProductMessage) => {
                this.StartCoroutine(this.refreshProductUI());
            });
        };
 
        // Pendengar peristiwa tombol untuk mendapatkan item: Tambah Produk
        this.acquireItemBtn.onClick.AddListener(() => {
            const data = new RoomData();
            data.Add("productId", this.productId);
            data.Add("quantity", this.productAddQuantity);
            this.multiplay.Room?.Send("AddProduct", data.GetObject());
        })
 
        // Pendengar peristiwa tombol untuk menggunakan item: Gunakan Produk
        this.useItemBtn.onClick.AddListener(() => {
            const data = new RoomData();
            data.Add("productId", this.productId);
            data.Add("quantity", 1);
            this.multiplay.Room?.Send("UseProduct", data.GetObject());
        })
 
    }
     
    private * refreshProductUI() {
        const request = InventoryService.GetAsync(this.productId);
        yield new WaitUntil(() => request.keepWaiting == false);
        // Jika permintaan berhasil, perbarui UI Produk
        if (request.responseData.isSuccess) {
            this.updateItemCountText(request.responseData.product);
        }
        else {
            console.log("Gagal memuat item produk.");
        }
    }
 
    private updateItemCountText(item: InventoryRecord) {
        if (item != null) {
            this.itemCountText.text = item.quantity.toString();
        }
        else {
            this.itemCountText.text = "0";
        }
    }
 
}
 
// Antarmuka untuk pesan produk.
interface ProductMessage {
    productId: string,
    productAction: ProductAction,
}
 
// Enum untuk mendefinisikan jenis tindakan produk.
export enum ProductAction {
    Gunakan,
    Tambah,
}
```
:::



### Deskripsi Skrip Klien Produk

- Ketika karakter dimuat, gunakan `InventoryService` dari [ZEPETO.Inventory](https://developer.zepeto.me/docs/product/namespaces/ZEPETO_Inventory/) untuk memuat inventaris awal produk. Kemudian perbarui UI.

```typescript
private * refreshProductUI() {
        const request = InventoryService.GetAsync(this.productId);
        yield new WaitUntil(() => request.keepWaiting == false);
        if (request.responseData.isSuccess) {
            this.updateItemCountText(request.responseData.product);
        }
        else {
            console.log("Gagal memuat item produk.");
        }
    }
```

- Untuk mengirim dan menerima pesan, definisikan `ProductMessage` antarmuka. Definisikan sebuah `ProductAction` Enum untuk implementasi contoh.

```typescript
interface ProductMessage {
    productId: string,
    productAction: ProductAction,
}
 
export enum ProductAction {
    Gunakan,
    Tambah,
}
```

- Ketika Anda meningkatkan atau mengurangi produk, Anda mengirim data tersebut ke server sebagai Pesan Ruangan.
  Ini mencakup data tentang produk mana yang akan ditingkatkan atau dikurangi dan seberapa banyak.

```typescript
this.multiplay.Room?.Send("AddProduct", data.GetObject());
this.multiplay.Room?.Send("UseProduct", data.GetObject());
```

- Setelah memproses perubahan produk, server mengirimkan informasi inventaris akhir kepada klien, yang memperbarui UI sesuai.

[Lihat skrip server lengkap](docId:3m067mdrmuFhbSKEhGrsB)&#x20;

```typescript
this.multiplay.RoomJoined += (room: Room) => {
    room.AddMessageHandler("SyncProductInfo", (message: ProductMessage) => {
        this.StartCoroutine(this.refreshProductUI());
    });
};
```

:::hint{type="success"}
- Umumnya, produk dunia harus memerlukan mata uang untuk dibeli.
- Dalam hal ini, Anda dapat dengan mudah menjualnya dengan **Tombol Pembelian Produk** dengan merujuk pada panduan [Monetize Your World! Mengatur Produk dan Mata Uang](docId:8mv4M22Vt9kYAwU6xKfqM)&#x20;
:::



## Skrip Server

Berikut adalah kode server lengkap yang mengelola mata uang dunia dan produk, serta cara mengimplementasikannya.

### Skrip Server Lengkap

```typescript
import { Sandbox, SandboxOptions, SandboxPlayer } from "ZEPETO.Multiplay";
import { loadCurrency } from "ZEPETO.Multiplay.Currency";
import { loadInventory } from "ZEPETO.Multiplay.Inventory";

export default class extends Sandbox {

    async onCreate(options: SandboxOptions) {

        // Mata Uang
        //Permintaan memuat mata uang
        this.onMessage("LoadBalance", (client, message: string) => {
            this.loadBalance(client, message);
        });
        //Permintaan menambahkan kredit
        this.onMessage("CreditCurrency", (client, message: CurrencyMessage ) => {
            const currencyId = message.currencyId;
            const quantity = message.quantity;
            this.addCredit(client, currencyId, quantity);
        });
        //Permintaan mendebit kredit
        this.onMessage("DebitCurrency", (client, message: CurrencyMessage ) => {
            const currencyId = message.currencyId;
            const quantity = message.quantity;
            this.onDebit(client, currencyId, quantity);
        });

        // Produk
        //Permintaan menambahkan item
        this.onMessage("AddProduct", (client, message: any) => {
            const productId = message.productId;
            const quantity = message.quantity;
            this.addProduct(client, productId, quantity);
        });
        //Permintaan menggunakan item
        this.onMessage("UseProduct", (client, message: any) => {
            const productId = message.productId;
            const quantity = message.quantity;
            this.useProduct(client, productId, quantity);
        });

    }

    async addCredit(client: SandboxPlayer, currencyId: string, quantity: number) {
        try {
            const currency = await loadCurrency(client.userId);
            await currency.credit(currencyId, quantity);
            this.loadBalance(client, currencyId);
        } catch (e) {
            console.error(`AddCredit Error: ${e}`);
        }
    }

    async onDebit(client: SandboxPlayer, currencyId: string, quantity: number) {
        try {
            const currency = await loadCurrency(client.userId);
            if (await currency.debit(currencyId, quantity) === true) {
                this.loadBalance(client, currencyId);
            } else {
                console.error("DebitCredit Error: Mata Uang Tidak Cukup");
            }
        } catch (e) {
            console.error(`DebitCredit Error: ${e}`);
        }
    }

    async loadBalance(client: SandboxPlayer, currencyId: string) {
        try {
            const currency = await loadCurrency(client.userId);
            let balancesObject = await currency.getBalances();
            let balancesMap: Map<string, number> = new Map(Object.entries(balancesObject));
            const specificCurrencyID = currencyId;
            const specificBalance = balancesMap.get(specificCurrencyID) ?? 0;
            const currencySync: CurrencyMessage = {
                currencyId: specificCurrencyID,
                quantity: specificBalance
            }
            client.send("SyncCurrencyInfo", currencySync);
        } catch (e) {
            console.error(`loadBalance Error: ${e}`);
        }
    }

    async addProduct(client: SandboxPlayer, productId: string, quantity: number) {
        try {
            const inventory = await loadInventory(client.userId);
            await inventory.add(productId, quantity);
            const productMessage: ProductMessage = {
                productId: productId,
                productAction: ProductAction.Add
            }
            client.send("SyncProductInfo", productMessage);
        } catch (e) {
            console.error(`addProduct Error: ${e}`);
        }
    }

    async useProduct(client: SandboxPlayer, productId: string, quantity: number) {
        try {
            const inventory = await loadInventory(client.userId);
            await inventory.use(productId, quantity);
            const productMessage: ProductMessage = {
                productId: productId,
                productAction: ProductAction.Use
            }
            client.send("SyncProductInfo", productMessage);
        } catch (e) {
            console.error(`useProduct Error: ${e}`);
        }
    }

    onJoin(client: SandboxPlayer) {
        // Logika OnJoin di sini
    }

    onTick(deltaTime: number): void {
        // Logika Tick di sini
    }

    onLeave(client: SandboxPlayer, consented?: boolean) {
        // Tangani logika keluar di sini
    }

}

// Antarmuka untuk pesan mata uang
interface CurrencyMessage {
    currencyId: string,
    quantity: number,
}

// Antarmuka untuk pesan produk.
interface ProductMessage {
    productId: string,
    productAction: ProductAction,
}

// Enum untuk mendefinisikan jenis tindakan produk.
export enum ProductAction {
    Use,
    Add,
}
```



### Deskripsi Skrip Server

- Kelola mata uang dunia melalui [ZEPETO.Multiplay.Currency](https://developer.zepeto.me/docs/multiplay-server/namespaces/ZEPETO_Multiplay_Currency/).
- Gunakan `currency.credit()` dan `currency.debit()` untuk meningkatkan atau mengurangi saldo mata uang yang diinginkan. Setelah itu, panggil `currency.getBalances()` untuk mendapatkan saldo saat ini untuk setiap mata uang.

```typescript
currency.credit(currencyId, quantity);
currency.debit(currencyId, quantity);
currency.getBalances();
```

- Kelola produk dunia melalui [ZEPETO.Multiplay.Inventory](https://developer.zepeto.me/docs/multiplay-server/namespaces/ZEPETO_Multiplay_Inventory).
- Gunakan `inventory.add()` dan `inventory.use()` untuk meningkatkan atau mengurangi saldo mata uang yang diinginkan.

```typescript
inventory.add(productId, quantity);
inventory.use(productId, quantity);
```

- Menangani permintaan dari klien untuk meningkatkan atau mengurangi mata uang dan produk.
- Gunakan `loadBalance()` untuk mendapatkan informasi mata uang yang terdaftar di ZEPETO Studio.
- Jika ada beberapa mata uang, Anda dapat mengkondisikan pada nilai ID mata uang tertentu untuk mendapatkan saldo hanya mata uang tersebut.
- Kirim nilai saldo akhir kepada klien sebagai Pesan Ruangan.

