Bitcoin and Altcoin Wallets 6.4.0

Transaction extends Post_Type
in package

Transaction class

Represents a transaction on the plugin's ledger. A transaction object can represent:

  • a user's blockchain transaction (category=withdrawal or category=deposit)
  • a credit to the user (category=move and amount>0)
  • a debit to the user (category=move and amount<0)
  • a fiat bank deposit or withdrawal (category=withdrawal or category=deposit, and currency->is_fiat()===true )

Once you save() a transaction, depending on its state, it may be modified by cron tasks.

e.g., a transaction with category=withdrawal and status=pending, may be picked up by Withdrawals_Task.

Credit a user

Here we create a transaction to credit a specific user with 0.23 Litecoin. Once the transaction is saved to the DB, it will cound towards that user's balance. The balance does not get subtracted from any other account.

$user_id  = get_current_user_id();
$user     = new \WP_User( $user_id );
$litecoin = \DSWallets\get_first_currency_by_symbol( 'LTC' );

if ( $user->exists() && $litecoin ) {

	$tx = new Transaction;

	$tx->category = 'move';
	$tx->user     = $user;
	$tx->currency = $litecoin;
	$tx->amount   = 0.23 * 10 ** $litecoin->decimals;
	$tx->comment  = "Here's your Litecoin, user!";
	$tx->status   = 'done';

	try {
		$tx->save();
	} catch ( \Exception $e ) {
		error_log( 'Could not save transaction due to: ' . $e->getMessage() );
	}

} else {
	error_log( 'User or litecoin currency not found' );
}

If we want to transfer funds from one user to another and charge fees, the easiest way is the wallets_api_move action from the legacy PHP API.

Debit a user and charge a fee

Now let's create a transaction to debit the same user. The user will be charged 10 USD plus fees, where fees are 5% of the amount. The user will therefore be charged 10.50 USD. We need to set a negative amount and fee. Both these values are integers so we need to shift the decimals. Here's how to do this:

$user_id = get_current_user_id();
$user = new \WP_User( $user_id );
$usd = \DSWallets\get_first_currency_by_symbol( 'USD' );

if ( $user->exists() && $usd ) {

	$tx = new Transaction;

	$tx->category = 'move';
	$tx->user     = $user;
	$tx->currency = $usd;
	$tx->amount   = - 10 * 10 ** $usd->decimals; // two decimals
	$tx->fee      = - ( 0.05 * 10 ) * 10 ** $usd->decimals;
	$tx->comment  = "You have been charged $10 (+5% fee)";
	$tx->status   = 'done';

	try {
		$tx->save();
	} catch ( \Exception $e ) {
		error_log( 'Could not save transaction due to: ' . $e->getMessage() );
	}

} else {
	error_log( 'User or United States Dollar currency not found' );
}

Create a new deposit to a deposit address.

We can add deposits to the ledger. Here we'll deposit 100 satoshis to the deposit address and we'll withold 10% as deposit fee!!!!, so that only 90 satoshis are added to the user's balance. This may have happened on an actual blockchain or not; it's up to us. A Wallet Adapter would use such code to create an object for a newly discovered deposit.

A reference to an Address is required.

$bitcoin = \DSWallets\get_first_currency_by_symbol( 'BTC' );

foreach ( get_all_addresses_for_user_id( get_current_user_id() ) as $address ) {

	if ( 'deposit' == $address->type && $bitcoin->post_id == $address->currency->post_id ) {

		$deposit = new Transaction;

		$deposit->category = 'deposit';
		$deposit->user     = new \WP_User( get_current_user_id() );
		$deposit->address  = $address;
		$deposit->currency = $bitcoin;
		$deposit->amount   = 90 * 10 ** $bitcoin->decimals;
		$deposit->fee      = -10 * 10 ** $bitcoin->decimals; // fee is always negative
		$deposit->comment  = "100 satoshis were deposited to you (minus 10% fee)";
		$deposit->status   = 'done';

		try {

			$tx->save();

			break; // we'll only do this once

		} catch ( \Exception $e ) {
			error_log( 'Could not save transaction due to: ' . $e->getMessage() );
		}
	}
}
Tags
since
6.0.0

Introduced.

author

Alexandros Georgiou info@dashed-slug.net

Table of Contents

$object_cache  : mixed
$post_id  : int
The id of the post that this object represents.
$address  : Address|null
Only for deposits and withdrawals, falsy otherwise.
$amount  : int
Amount transacted, represented as an integer.
$block  : int
Blockchain max height.
$category  : string
TX "category".
$chain_fee  : int
Blockchain fee.
$comment  : string
Transaction comment.
$currency  : Currency|null
Currency transacted.
$dirty  : bool
Whether the TX data has changed since last DB load.
$error  : string
Error message.
$fee  : int
Fee charged, represented as an integer.
$nonce  : string
Confirmation nonce.
$parent_id  : int
Parent `post_id`.
$status  : string
Status
$tags  : array<string|int, ?string>
Array of tags.
$timestamp  : int
Timestamp.
$txid  : string|null
Blockchain TXID
$user  : WP_User|null
User
__get()  : mixed
Allows getting one of this object's fields.
__set()  : mixed
Sets a field of this Transaction object.
__toString()  : string
To String.
delete()  : mixed
Trashes this object in the DB.
from_values()  : Transaction
Factory to construct a transaction in one go from database values.
get_amount_as_string()  : string
Get amount as string.
get_confirmation_link()  : string|null
get_other_tx()  : Transaction|null
load()  : Transaction
Load a Transaction from its custom post entry.
load_many()  : array<string|int, Transaction>
Retrieve many transactions by their post_ids.
manage_custom_columns()  : mixed
meta_box_attributes()  : mixed
meta_box_attributes_bank_fiat()  : mixed
meta_box_attributes_blockchain()  : mixed
meta_box_other_tx()  : mixed
register()  : mixed
register_meta_boxes()  : mixed
register_post_type()  : mixed
register_taxonomy()  : mixed
render_custom_column()  : mixed
save()  : void
Save the transaction state on the DB.
save_post()  : mixed
Save post meta values taken from metabox inputs
saveButDontNotify()  : void
Save the transaction state on the DB.
status_transition()  : mixed
Here we do all sorts of hacky shenanigans to detect the true status transition for a tx.
render_bool_field()  : mixed
render_boolean_field()  : mixed
render_number_field()  : mixed
render_secret_field()  : mixed
render_select_field()  : mixed
render_string_field()  : mixed
render_strings_field()  : mixed

Properties

$amount

Amount transacted, represented as an integer.

private int $amount = 0

The amount must be shifted by $this->decimals decimal places to get the actual float amount.

$block

Blockchain max height.

private int $block = 0

Blockchain height for calculating number of confirmations. Only for deposits and withdrawals, falsy otherwise.

$category

TX "category".

private string $category = 'move'

One of: deposit, withdrawal, move. Not to be confused with WP taxonomies. This is a slug.

$chain_fee

Blockchain fee.

private int $chain_fee = 0

Fee charged on the blockchain for the entire transaction, as integer. The amount must be shifted by $this->decimals decimal places to get the actual float amount.

$comment

Transaction comment.

private string $comment = ''

Free text string, stored on the post_title column in the DB.

$dirty

Whether the TX data has changed since last DB load.

private bool $dirty = false

When save() is called, data should be saved only if dirty.

Whether data needs saving.

$error

Error message.

private string $error = ''

For transactions with failed status, can contain a useful error message.

Tags
see

$this->status

$fee

Fee charged, represented as an integer.

private int $fee = 0

The amount must be shifted by $this->decimals decimal places to get the actual float amount.

$nonce

Confirmation nonce.

private string $nonce = ''

For email confirmations of transactions. If empty, the transaction is confirmed or does not require confirmation. Useful only for pending transactions.

$parent_id

Parent `post_id`.

private int $parent_id = 0

If it's a credit transaction, the debit transaction to which it corresponds. Credit transactions have category = move and amount >= 0. Debit transactions have category = move and amount < 0.

$status

Status

private string $status = 'pending'

One of: pending, done, cancelled, failed. If value is failed, then $error must also be set.

Tags
see

$this->error

$tags

Array of tags.

private array<string|int, ?string> $tags = null

Tags correspond to term slugs in the wallets_tx_tags taxonomy.

$timestamp

Timestamp.

private int $timestamp = 0

Unix timestamp according to the blockchain. If not available, returns the post's creation date timestamp.

$txid

Blockchain TXID

private string|null $txid = null

Only for blockchain transactions, null otherwise.

$user

User

private WP_User|null $user = null

The transaction counts towards this user's balance.

Methods

__get()

Allows getting one of this object's fields.

public __get(mixed $name) : mixed
Parameters
$name : mixed

The name of the field to retrieve.

Return values
mixed

__set()

Sets a field of this Transaction object.

public __set(string $name, mixed $value) : mixed
Parameters
$name : string

Can be: post_id, category, user, txid, address, currency, amount, fee, chain_fee, comment, block, timestamp, nonce, status, error, parent_id.

$value : mixed

The value to set to the field.

Tags
see
Post_Type::__set()
throws
InvalidArgumentException

If value is not appropriate for field or if field does not exist.

Return values
mixed

delete()

Trashes this object in the DB.

public delete([mixed $force = false ]) : mixed
Parameters
$force : mixed = false
Tags
throws
Exception

If the object was not on the DB or if it could not be trashed.

Return values
mixed

from_values()

Factory to construct a transaction in one go from database values.

public static from_values(int $post_id, string $post_title, string $post_status, string $post_parent, array<string|int, mixed> $postmeta, array<string|int, string> $tags) : Transaction
Parameters
$post_id : int

The ID of the post in the database

$post_title : string

The post's title to be used as transaction comment

$post_status : string

The status of the post, to populate the transaction state field

$post_parent : string

The post's parent post, for transaction counterparts

$postmeta : array<string|int, mixed>

Key-value pairs

$tags : array<string|int, string>

The slugs of the terms on taxonomy wallets_tx_tags

Return values
Transaction

The constructed instance of the transaction object

get_amount_as_string()

Get amount as string.

public get_amount_as_string([string $field = 'amount' ][, bool $use_pattern = false ][, bool $positive = false ]) : string

Values such as the transacted amount, the fee, and the chain_fee are stored as integers, in order to avoid floating point errors.

This convenience function will render the specified field as a string with the correct amount of decimal places for the transaction's currency.

Parameters
$field : string = 'amount'

One of 'amount', 'fee', 'chain_fee', 'amountplusfee'.

$use_pattern : bool = false

If true, will use the sprintf pattern from the currency. If false, will simply render the decimal amount.

$positive : bool = false

Whether to force the result to be positive (absolute value).

Tags
throws
InvalidArgumentException

If an invalid field is specified.

Return values
string

The amount, rendered.

public get_confirmation_link() : string|null
Return values
string|null

load()

Load a Transaction from its custom post entry.

public static load(int $post_id) : Transaction
Parameters
$post_id : int

The post_id for the object to load.

Tags
inheritdoc
see
Post_Type::load()
throws
Exception

If not found or failed to instantiate.

Return values
Transaction

load_many()

Retrieve many transactions by their post_ids.

public static load_many(array<string|int, int> $post_ids[, string|null $unused = null ]) : array<string|int, Transaction>

Any post_ids not found are skipped silently.

Parameters
$post_ids : array<string|int, int>

The post IDs

$unused : string|null = null

Do not use. Ignored.

Tags
throws
Exception

If DB access or instantiation fails.

since
6.2.6

Introduced.

Return values
array<string|int, Transaction>

The transactions

manage_custom_columns()

public static manage_custom_columns(mixed $columns) : mixed
Parameters
$columns : mixed
Return values
mixed

meta_box_attributes()

public static meta_box_attributes(mixed $post, mixed $meta_box) : mixed
Parameters
$post : mixed
$meta_box : mixed
Return values
mixed

meta_box_attributes_bank_fiat()

public static meta_box_attributes_bank_fiat(mixed $post, mixed $meta_box) : mixed
Parameters
$post : mixed
$meta_box : mixed
Return values
mixed

meta_box_attributes_blockchain()

public static meta_box_attributes_blockchain(mixed $post, mixed $meta_box) : mixed
Parameters
$post : mixed
$meta_box : mixed
Return values
mixed

meta_box_other_tx()

public static meta_box_other_tx(mixed $post, mixed $meta_box) : mixed
Parameters
$post : mixed
$meta_box : mixed
Return values
mixed

register_meta_boxes()

public static register_meta_boxes() : mixed
Return values
mixed

register_post_type()

public static register_post_type() : mixed
Return values
mixed

register_taxonomy()

public static register_taxonomy() : mixed
Return values
mixed

render_custom_column()

public static render_custom_column(mixed $column, mixed $post_id) : mixed
Parameters
$column : mixed
$post_id : mixed
Return values
mixed

save()

Save the transaction state on the DB.

public save() : void

Assigns a new post_id if not already assigned, or edits existing transaction if post_id is set.

Return values
void

save_post()

Save post meta values taken from metabox inputs

public static save_post(mixed $post_id, mixed $post, mixed $update) : mixed
Parameters
$post_id : mixed
$post : mixed
$update : mixed
Return values
mixed

saveButDontNotify()

Save the transaction state on the DB.

public saveButDontNotify() : void

Assigns a new post_id if not already assigned, or edits existing transaction if post_id is set.

This delegate to save() does not trigger any notification emails.

Tags
see

$this->save()

Return values
void

status_transition()

Here we do all sorts of hacky shenanigans to detect the true status transition for a tx.

public static status_transition(string $new_status, string $old_status, WP_Post $post) : mixed

The complication is that the post status can change for any number of reasons and without warning. For example, if you set a status to pending and hit publish, the post status for the transaction will be first set to publish by WordPress, then the plugin code will set it back to draft.

Parameters
$new_status : string

The "new" status, as reported by the transition_post_status action.

$old_status : string

The "old" status, as reported by the transition_post_status action.

$post : WP_Post

The transaction post object.

Return values
mixed

render_bool_field()

protected static render_bool_field(mixed $schema, mixed $value) : mixed
Parameters
$schema : mixed
$value : mixed
Return values
mixed

render_boolean_field()

protected static render_boolean_field(mixed $schema, mixed $value) : mixed
Parameters
$schema : mixed
$value : mixed
Return values
mixed

render_number_field()

protected static render_number_field(mixed $schema, mixed $value) : mixed
Parameters
$schema : mixed
$value : mixed
Return values
mixed

render_secret_field()

protected static render_secret_field(mixed $schema, mixed $value) : mixed
Parameters
$schema : mixed
$value : mixed
Return values
mixed

render_select_field()

protected static render_select_field(mixed $schema, mixed $value) : mixed
Parameters
$schema : mixed
$value : mixed
Return values
mixed

render_string_field()

protected static render_string_field(mixed $schema, mixed $value) : mixed
Parameters
$schema : mixed
$value : mixed
Return values
mixed

render_strings_field()

protected static render_strings_field(mixed $schema, mixed $value) : mixed
Parameters
$schema : mixed
$value : mixed
Return values
mixed

Search results