# Jettons payments processing (https://docs-dmpho5eos-ton-core-docs.vercel.app/llms/payments/jettons/content.md)



Processing jetton payments requires understanding TON's sharded token architecture. Unlike single-contract token systems, each jetton type consists of a master contract and individual wallet contracts for each holder.

<Callout type="note">
  Jettons are fungible tokens on TON. Each jetton has a master contract (minter) and separate wallet contracts for every holder. Read more in [How Jettons Work](/llms/standard/tokens/jettons/how-it-works/content.md).
</Callout>

<Callout type="caution">
  Jetton processing is security-critical. Incorrect validation of jetton wallet addresses or transfer notifications can lead to accepting fake tokens or crediting wrong amounts.
</Callout>

## Key concepts [#key-concepts]

Before implementing jetton payment processing, understand these core concepts:

**Jetton architecture**: Each jetton type has one master contract that stores metadata and total supply. Each address holding the jetton has a separate jetton wallet contract at a deterministic address derived from the master contract and owner address.

**Transfer flow**: Jetton transfers involve multiple messages. A user sends a `transfer` message to their jetton wallet, which sends an `internal_transfer` to the recipient's jetton wallet, which then sends a `transfer_notification` to the recipient's address if `forward_ton_amount > 0`.

<Callout type="caution">
  Jetton transfers are considered successful only when the recipient receives `transfer_notification`. Services must set `forward_ton_amount` to at least 0.000000001 TON (1 nanoton) when sending tokens to trigger notifications. Without this, transfers won't be compliant and may not be processed by exchanges and other services.
</Callout>

**Security model**: Always validate that jetton wallets belong to the expected master contract. Anyone can deploy fake jetton wallet contracts with arbitrary balances.

This article covers processing jetton deposits using transfer notifications. All approaches require maintaining an allowlist of trusted jetton master contracts.

For architectural patterns and deposit methods comparison, see [Toncoin processing](/llms/payments/toncoin/content.md).

## Processing deposits [#processing-deposits]

<Callout type="danger" title="Funds at risk">
  Skipping any validation step or changing their order can lead to incorrect deposit processing and potential loss of funds.
</Callout>

### Setup [#setup]

Processing jetton deposits requires:

* **Allowlist of trusted jetton masters**: List of jetton master contract addresses to accept
* **Deposit wallet address**: Service wallet (e.g., wallet v4 or v5)

### Initial configuration [#initial-configuration]

1. For each allowlisted jetton master, derive the jetton wallet address for the deposit wallet using the master contract's `get_wallet_address()` method
2. Store the mapping of `jetton master` → `jetton wallet` → `deposit wallet` in the database
3. Begin monitoring transactions to the deposit wallet address

### Processing incoming transactions [#processing-incoming-transactions]

When a transaction arrives at the deposit wallet:

1. Check that `tx.in_msg.source` matches a known jetton wallet for this deposit wallet
2. Verify the master → jetton wallet relationship:
   * Call `get_wallet_address(deposit-wallet)` on the master contract
   * Confirm the returned address matches the sender
3. Verify there are no outgoing messages (`tx.out_msgs.length === 0`)
4. Parse the message body:
   * Check the opcode (first 32 bits of `tx.in_msg.body`) equals `0x7362d09c` (transfer\_notification)
   * Extract `query_id`, `amount`, `sender`, and `forward_payload` [according to TL-B](/llms/standard/tokens/jettons/api/content.md)
5. Verify the amount matches the expected value

### Crediting user accounts [#crediting-user-accounts]

After validation, extract deposit information:

* For [invoice-based deposits][inv-dep]: Parse the invoice ID from `forward_payload`, match it against the database, and credit the corresponding user account.
* For [address-based deposits][add-dep]: Match the `deposit-wallet` address against the database and credit the user account.

<Callout type="note">
  Not production-ready code, use only for educational purposes:

  * [Invoice-based jetton deposits][inv-dep]
  * [Unique address jetton deposits][add-dep]
</Callout>

[inv-dep]: https://github.com/ton-org/docs-examples/blob/jetton-processing-only/guidebook/jetton-processing/src/deposits/jetton-invoices.ts

[add-dep]: https://github.com/ton-org/docs-examples/blob/jetton-processing-only/guidebook/jetton-processing/src/deposits/jetton-unique-addresses.ts

## Security considerations [#security-considerations]

### Master-wallet verification [#master-wallet-verification]

Never trust jetton wallet addresses without verification. Always perform these checks:

1. Get the jetton master address from the allowlist
2. Call `jetton_master.get_wallet_address(owner_address)`
3. Verify the returned address matches the jetton wallet that sent the notification

### Transfer notification validation [#transfer-notification-validation]

When processing deposits via `transfer_notification`:

* Verify the opcode is exactly `0x7362d09c`
* Check the sender address is an expected jetton wallet
* Extract `amount` in base units (not decimal)
* Validate the `sender` field against expected user addresses
* Parse `forward_payload` carefully—it may be malformed
* Check for bounce indicators (single outgoing message back to sender)

### Fake jetton detection [#fake-jetton-detection]

Attackers can deploy jettons with identical names, symbols, and images:

* Always verify the jetton master address against the allowlist
* Never trust metadata (name, symbol, image) for authentication
* Display the master contract address in admin interfaces
* Implement a manual approval workflow for adding new jettons

## Common attack patterns [#common-attack-patterns]

### Fake jetton wallets [#fake-jetton-wallets]

**Attack**: Attacker deploys a contract claiming to be a jetton wallet with an inflated balance.

**Mitigation**: Verify the master-wallet relationship by calling `get_wallet_address()` on the master contract.

### Invoice ID reuse [#invoice-id-reuse]

**Attack**: User attempts to reuse a settled invoice identifier.

**Mitigation**: Mark invoices as used after the first successful deposit.

### Master contract spoofing [#master-contract-spoofing]

**Attack**: Deploying a fake master contract that validates the attacker's fake jetton wallets.

**Mitigation**: Maintain a strict allowlist of trusted master contracts and verify all jetton wallets against it.

## Implementation checklist [#implementation-checklist]

Before enabling jetton processing in production:

### Testing [#testing]

1. Deploy and test on testnet with real user scenarios
2. Verify master-wallet relationships for all allowlisted jettons
3. Test with fake jetton wallets to confirm rejection
4. Validate transfer notification parsing with various payload formats
5. Test bounce detection and handling
6. Test invoice ID collision and reuse scenarios
7. Test full flow: deposit → credit → withdrawal → confirmation
