> For the complete documentation index, see [llms.txt](https://docs.zenprotocol.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zenprotocol.com/apps/zen_js/payment-processing.md).

# Payment Processing

## Payment Processing

Zen Protocol is a multi-token blockchain, any contract can issue any number of tokens. Each token (called an *asset*) is represented by the contract identifier and optional sub type (of 32 bytes).

Zen assets are represented by one byte of the value *0* (zero).

Each asset also has a string representation, which is being used in the UI and API. Zen tokens are represented by the string *00* (zero zero).

Unlike bitcoin, when sending an asset we have to specify which asset are we spending. Therefore the API always requires an additional *asset* parameter on the `wallet/send` and `wallet/execute` API calls.

### Hot wallet payment processing

The Zen-Node exposes an API for accepting payments.&#x20;

For each payment we generate a new unique address and provide it to the end-user. Then periodically check the amount received for each address and save it. When the amount for address changed between calls you know the user made a payment. You can also specify the minimum confirmations required to consider a payment as complete.

All the assets belong to the wallet and can be spent by the `wallet/send` API call.

You first have to create a wallet, either through the UI or via the `zen-cli`. The private key is encrypted, however it is still on the hot zen-node machine, therefore this solution should be treated as a hot wallet.

### API Calls

## Send Assets

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/send`

Accepts a list of assets, amounts and destination addresses, in order to create, sign and publish a transaction.

#### Path Parameters

| Name | Type  | Description                                                                                    |
| ---- | ----- | ---------------------------------------------------------------------------------------------- |
|      | array | <p>\[{<br>  "address": "tp1q7n4l3dldcv69wf",<br>  "asset": "00",<br>  "amount": 1234<br>}]</p> |

#### Request Body

| Name     | Type   | Description |
| -------- | ------ | ----------- |
| password | string | "1234"      |

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

```
```

{% endtab %}
{% endtabs %}

## Get New Address

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/getnewaddress`

Generate a unique new address. Returns both the address and the address index. Save the index as well in order to restore the wallet in the future.

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

```
{
    "address": "tzn1q7gye0nkgxuwal949y4ke94mwfwsf7eaafy7p5tkdcr6ujuyglqwsnjv2gt",
    "index": 0
}
```

{% endtab %}
{% endtabs %}

## Received By Address

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/receivedbyaddress`

Return the amount received for each address and asset in the wallet. The amount can only grow, spending an input that belongs to one of the addresses **does not** decrease the amount received. Amount received is the amount the address received in it's entire lifetime.

{% tabs %}
{% tab title="200 An array of addresses and the asset and amount in each address." %}

```
[
    {
        "address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q",
        "asset": "00",
        "amount": 9497378334165913
    },
    {
        "address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q",
        "asset": "000000006a26b38c2875d1379405bb7d140078ccffb560aff839a3d846850e99ab3d9de84265617200000000000000000000000000000000000000000000000000000000",
        "amount": 199999994
    },
    {
        "address": "tzn1qlvm8ey4m5mj6ak3an39qdfzf7yx4uz59flzlant6jp0gzld48egsj433m6",
        "asset": "00",
        "amount": 1855040761794
    }
]
```

{% endtab %}
{% endtabs %}

## Account Discovery

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/restorenewaddresses`

Have a new node run an account discovery on a certain amount of addresses.

#### Path Parameters

| Name | Type   | Description                                                  |
| ---- | ------ | ------------------------------------------------------------ |
| max  | string | Write the number of addresses you want the node to discover. |

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

```
```

{% endtab %}
{% endtabs %}

###

### Cold wallet payment processing

You can also use cold wallet for the payment processing.&#x20;

You will have to use [zen.js](/apps/zen_js.md) library for the process.

Generate an extended private key on a secure computer and import the extended public key.

```javascript
import {Mnemonic, ExtendedKey} from '@zen/zenjs'

const mnemonic = Mnemonic.generateMnemonic(24); // Generate once
console.log('mnemonic phrase', mnemonic);

const publicKey = ExtendedKey.fromMnemonic(mnemonic).neutered();

console.log('Extended Public Key', publicKey.toString());
```

On a hot machine generate a unique address by deriving the key with a unique index. Save the index to later sign the transaction on the secure computer.

```javascript
import {ExtendedKey} from '@zen/zenjs'
import {post} from 'axios'

const publicKey = ExtendedKey.fromString(encodedString);
const address = publicKey.derive(uniqueIndex).toAddress();

// import the address to zen node
post('http://127.0.0.1/:31567/wallet/importwatchonlyaddress',address,{ headers: { 'Content-Type': 'application/json' }});
```

Share the address with the user and track the address for income payments the same as for the hot wallet, by calling `wallet/receivedbyaddress`

To make a payment you will to get the outputs from the zen-node and assemble the transaction on the secure computer. Retrieve the available outputs by calling `wallet/addressoutputs` for each address.

Example of assembling and publishing  transaction:

```javascript
import {TransactionBuilder,ExtendedKey} from '@zen/zenjs'
import {post} from 'axios'

const tb = new TransactionBuilder('main');

// Get the private key by matching the unique index for the input address
const privateKey = ExtendedKey.fromMnemonic(mnemonic).derive(inputAddressIndex).getPrivateKey();

// An example input, use one you retrieved by calling `wallet/addressoutputs`
tb.addInput('0000000000000000000000000000000000000000000000000000000000000000',0, privateKey);

// Address, amount and token (Zen)
tb.addOutput('tp1qfyplhxql09lvvg53dxg7t77tkkxhsp3l6q8xjjpj85hvqlw0ttqswjdapx', 100, '00');

const tx = tb.sign();

// You can take the hex to an hot computer
const hex = tx.toHex();

// Transaction is ready to be published
post('http://127.0.0.1/:31567/blockchain/publishpublishtransaction',hex,{ headers: { 'Content-Type': 'application/json' }});

```
