Identifier

An identifier allows you to keep track of wallets and their deposits as well as withdrawals.

Note: The code on this page should be regarded as pseudocode. Refer to the pages in the documentation describing the specific functions for details and fully correct examples.

Important Points

  • Deposit Addresses are permanently mapped to the identifier they were created with

  • Transactions to such an address will always include the identifier

  • identifier and recipientId represent the same concepts (for deposits and payouts respectively)

It is strongly recommended to keep a one-to-one mapping between users and deposit addresses.

Why?

  • A permanently assigned deposit-address means new wallets do not have to be created every time a deposit is initiated (or otherwise selected from a pre-generated pool through some algorithm). After requesting a deposit-address for an identifier, you know the identifier and address are linked forever and therefore would not need to request a deposit-address again for that identifier. Should you still want to check the address it is still much more efficient as AP will simply look up the wallet in a database instead of creating a new wallet on the blockchain - which can be a lengthy procedure.

  • If you manage a set of users, it will be easier for you to keep track of which user has which address used for deposits (as it will be only one, and always the same one). Similarly, your users will only have to deal with one address (or really one per network) for depositing, minimizing any risk of deposits going into the wrong wallet.

Detailed Description

In the documentation and the code, you will come across the concept of an "identifier" (sometimes "recipientId"). The identifier is just that, something that uniquely identifies deposit addresses, deposits, and withdrawals. Normally, the identifier will be a userId or similar, though it is up to you exactly how you use it.

Deposits

Creating a deposit address

The first place you will encounter the identifier is usually when creating a wallet (deposit address) for your software, perhaps for one of your users to deposit funds into. If you control a number of users, it is likely you store their data with some unique property like an ID or a username. This could then be used in the call to get a deposit address:

AkashicPay.getDepositAddress('TRX', 'user1') 
// -> 'TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb'

The returned address (TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb in the above example) is now permanently assigned to the identifier 'user1'. Any subsequent call of the same function will return the same address:

AkashicPay.getDepositAddress('TRX', 'user1') 
// -> 'TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb'

If you change the Network or the identifier, you will naturally get a different address:

AkashicPay.getDepositAddress('TRX', 'user2') 
// -> 'TDkteGBASJSvoHSeAAwej3LAfFLj7zhhaE'

AkashicPay.getDepositAddress('ETH', 'user1') 
// -> '0x159cA92b12F67E5676d82C238f4906692618A555' (diffrent format on Ethereum)

Deposit Callbacks

If the user we have identified as user1 now decides to make a deposit to wallet TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb you will receive a callback to the URL(s) you setup on AkashicPay.com. Present in the callback object will be a field titled identifier with the value user1. This allows you to easily identify deposits with the user they belong to. Of course, if you'd like, you could store the address (TTV...) in your database and use that instead.

Payouts/Withdrawals

Processing payouts (withdrawals)

For payouts/withdrawals you must include an identifier/recipientId in the function-call. Normally this should be the same identifier as used previously if the payout is associated with the same user. Continuing our example, let's say user1 is ready to withdraw their funds. They might submit a request to you, which you initiate by using the SDK:

AkashicPay.payout('user1', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

This will initiate a transaction from AkashicPay to external wallet TAzsQ... for the value of 10 USDT on the Tron (TRX) Network. Due to the way AkashicPay works, the withdrawal may be sent from one of many wallets. There is thus no guarantee (in fact, it is unlikely) that the withdrawal is sent from the same address user1 uses for deposits, and you should never rely on this to be true.

Note that the payout-identifier does not have to be the same as the deposit-identifier. If you, for example, would like to track the individual transactions on a more granular level in addition to the user initiating them, a simple approach could be to numerate the transactions through the identifier:

AkashicPay.payout('user1-tx1', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

AkashicPay.payout('user1-tx2', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '5', 'TRX', 'USDT')

However, we strongly recommend not using this approach for deposits, for the reasons mentioned above.

Payout Callbacks

When the withdrawal is triggered using the function as above, you will again receive a callback to the URL(s) you have setup on AkashicPay.com. When you receive the payout-callback the transaction has been confirmed and it is safe to credit the user.

Special Cases

Payout without identifier?

Depending on your usage, there may be cases where including the identifier seems unnecessary. For example doing an internal transaction to a special wallet or when doing a payout of profits. In general, for these sort of payouts that do not concern any users, the identifier is largely superfluous. However, we still require the identifier to be present for all transactions to ensure everything can be tracked unambiguously. This is due to the fact that there is no safe way to separate two transactions otherwise, as it is technically possible for two otherwise equal transactions to take place at the same time. We therefore encourage you to also keep track of all transactions using sensible identifiers. For example:

AkashicPay.payout('INTERNAL_TRANSFER', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

AkashicPay.payout('PROFIT_PAYOUT', 'TDprmTxVAkC7a8RuFNFB3ukysRMeGELXsM', '1000', 'TRX', 'USDT')

Of course, any string-argument is permitted, so if you are absolutely sure you do not want to keep track of the transaction through the identifier, you could just supply any random string and immediately forget about it:

NB! Do not use an empty string!

AkashicPay.payout('foo', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

AkashicPay.payout('NaN', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

Multiple deposit addresses?

Of course, there is nothing preventing you from providing "user1" in your system with multiple deposit addresses. Perhaps one address will be used for special promotions or other cases. In this case, you could simply do something like:

AkashicPay.getDepositAddress('TRX', 'user1-normal') 
// -> 'TDprmTxVAkC7a8RuFNFB3ukysRMeGELXsM'
AkashicPay.getDepositAddress('TRX', 'user1-special') 
// -> 'TRMzP9A18iQNvaFn33zkhhnN5exmLWZ5Ad'

Perhaps you store this on your user as e.g.

{
    userId: 'user1',
    wallets: [{address: 'TDprmTxVAkC7a8RuFNFB3ukysRMeGELXsM', 
            identifier: 'user1-normal'},
             {address: 'TRMzP9A18iQNvaFn33zkhhnN5exmLWZ5Ad',
              identifier: 'user1-special'}]
}

As usual, any deposits to the above two addresses would now return the respective identifier.

This is an example showcasing how AkashicPay can be used. However, we recommend always keeping a one-to-one mapping between user and deposit address for maximal efficiency and minimal potential for confusion.

Last updated