Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.61% covered (warning)
83.61%
51 / 61
55.56% covered (warning)
55.56%
5 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
WC_Order_Meta_Helper
83.61% covered (warning)
83.61%
51 / 61
55.56% covered (warning)
55.56%
5 / 9
21.76
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 set_raw_address
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 get_raw_payment_address
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 set_btc_total_price
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 get_btc_total_price
66.67% covered (warning)
66.67%
6 / 9
0.00% covered (danger)
0.00%
0 / 1
3.33
 set_exchange_rate
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 get_exchange_rate
66.67% covered (warning)
66.67%
6 / 9
0.00% covered (danger)
0.00%
0 / 1
3.33
 set_confirmed_amount_received
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 get_confirmed_amount_received
66.67% covered (warning)
66.67%
6 / 9
0.00% covered (danger)
0.00%
0 / 1
3.33
1<?php
2/**
3 * Constants for order meta-keys. Helper functions to return typed values.
4 *
5 * @package    brianhenryie/bh-wp-bitcoin-gateway
6 */
7
8namespace BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Helpers;
9
10use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Wallet\Bitcoin_Address;
11use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Wallet\Bitcoin_Address_WP_Post_Interface;
12use BrianHenryIE\WP_Bitcoin_Gateway\Brick\Money\Money;
13use BrianHenryIE\WP_Bitcoin_Gateway\JsonMapper\JsonMapperInterface;
14use Exception;
15use Psr\Log\LoggerAwareInterface;
16use Psr\Log\LoggerAwareTrait;
17use WC_Order;
18
19/**
20 * Helper functions so the format the data is saved in meta can be changed later.
21 */
22class WC_Order_Meta_Helper implements LoggerAwareInterface {
23    use LoggerAwareTrait;
24
25    const string BITCOIN_ADDRESS_META_KEY = 'bh_wp_bitcoin_gateway_payment_address';
26
27    const string EXCHANGE_RATE_AT_TIME_OF_PURCHASE_META_KEY = 'bh_wp_bitcoin_gateway_exchange_rate_at_time_of_purchase';
28
29    const string ORDER_TOTAL_BITCOIN_AT_TIME_OF_PURCHASE_META_KEY = 'bh_wp_bitcoin_gateway_bitcoin_total_at_time_of_purchase';
30
31    /**
32     * @see Bitcoin_Address_WP_Post_Interface::CONFIRMED_AMOUNT_RECEIVED_META_KEY
33     */
34    const string BITCOIN_AMOUNT_CONFIRMED_RECEIVED_META_KEY = 'bh_wp_bitcoin_gateway_bitcoin_confirmed_amount_received';
35
36    /**
37     * Constructor
38     *
39     * @param JsonMapperInterface $json_mapper To parse JSON to typed objects.
40     */
41    public function __construct(
42        protected JsonMapperInterface $json_mapper,
43    ) {
44    }
45
46    /**
47     * Save the payment address string to order meta.
48     *
49     * @param WC_Order        $wc_order The WooCommerce order.
50     * @param Bitcoin_Address $payment_address The address object to read the address string from.
51     * @param bool            $save_now Should `WC_Order::save()` be called immediately.
52     */
53    public function set_raw_address( WC_Order $wc_order, Bitcoin_Address $payment_address, bool $save_now = true ): void {
54        $wc_order->add_meta_data(
55            self::BITCOIN_ADDRESS_META_KEY,
56            $payment_address->get_raw_address(),
57            true
58        );
59        if ( $save_now ) {
60            $wc_order->save();
61        }
62    }
63
64    /**
65     * Get the saved payment address, if present.
66     *
67     * @param WC_Order $wc_order The WooCommerce order.
68     */
69    public function get_raw_payment_address( WC_Order $wc_order ): ?string {
70        $payment_address_meta = $wc_order->get_meta( self::BITCOIN_ADDRESS_META_KEY );
71        return is_string( $payment_address_meta ) ? $payment_address_meta : null;
72    }
73
74    /**
75     * Save the order value in BTC. (Record the amount the customer has been asked to pay in BTC.).
76     *
77     * Saves as JSON string, e.g. `{"amount":"0.0000543","currency":"BTC"}`.
78     *
79     * @param WC_Order $wc_order The WooCommerce order.
80     * @param Money    $btc_total The order total in BTC.
81     * @param bool     $save_now Should `WC_Order::save()` be called immediately.
82     * @see Bitcoin_Address::$target_amount
83     */
84    public function set_btc_total_price( WC_Order $wc_order, Money $btc_total, bool $save_now = true ): void {
85        $money_json_string = wp_json_encode( $btc_total->jsonSerialize() );
86        $wc_order->add_meta_data(
87            self::ORDER_TOTAL_BITCOIN_AT_TIME_OF_PURCHASE_META_KEY,
88            $money_json_string,
89            true
90        );
91        if ( $save_now ) {
92            $wc_order->save();
93        }
94    }
95
96    /**
97     * The order price in Bitcoin at the time of purchase.
98     *
99     * @param WC_Order $wc_order The WooCommerce order.
100     *
101     * @return ?Money The order total in BTC.
102     */
103    public function get_btc_total_price( WC_Order $wc_order ): ?Money {
104        $btc_total_meta_string = $wc_order->get_meta( self::ORDER_TOTAL_BITCOIN_AT_TIME_OF_PURCHASE_META_KEY );
105        if ( ! is_string( $btc_total_meta_string ) ) {
106            return null;
107        }
108        try {
109            return $this->json_mapper->mapToClassFromString(
110                $btc_total_meta_string,
111                Money::class
112            );
113        } catch ( Exception ) {
114            return null;
115        }
116    }
117
118    /**
119     * Save the exchange rate used to calculate the expected payment amount.
120     *
121     * @param WC_Order $wc_order The WooCommerce order.
122     * @param Money    $exchange_rate 1 BTC = x.
123     * @param bool     $save_now Should `WC_Order::save()` be called immediately.
124     */
125    public function set_exchange_rate( WC_Order $wc_order, Money $exchange_rate, bool $save_now = true ): void {
126        $exchange_rate_json_string = wp_json_encode( $exchange_rate->jsonSerialize() );
127        $wc_order->add_meta_data(
128            self::EXCHANGE_RATE_AT_TIME_OF_PURCHASE_META_KEY,
129            $exchange_rate_json_string,
130            true
131        );
132        if ( $save_now ) {
133            $wc_order->save();
134        }
135    }
136
137    /**
138     * Get the Bitcoin to fiat exchange rate for this order.
139     * The price of 1 Bitcoin at the time of purchase.
140     *
141     * @param WC_Order $wc_order The WooCommerce order.
142     * @return ?Money The exchange rate.
143     */
144    public function get_exchange_rate( WC_Order $wc_order ): ?Money {
145        $exchange_rate_meta_json_string = $wc_order->get_meta( self::EXCHANGE_RATE_AT_TIME_OF_PURCHASE_META_KEY );
146        if ( ! is_string( $exchange_rate_meta_json_string ) ) {
147            return null;
148        }
149        try {
150            return $this->json_mapper->mapToClassFromString(
151                $exchange_rate_meta_json_string,
152                Money::class
153            );
154        } catch ( Exception ) {
155            return null;
156        }
157    }
158
159    /**
160     * Set the confirmed Bitcoin amount received for this order.
161     *
162     * @param WC_Order $wc_order The order to save the meta on.
163     * @param Money    $updated_confirmed_value The confirmed amount received in Bitcoin.
164     * @param bool     $save_now Should `WC_Order::save()` be called immediately.
165     */
166    public function set_confirmed_amount_received(
167        WC_Order $wc_order,
168        Money $updated_confirmed_value,
169        bool $save_now = true
170    ): void {
171        $updated_confirmed_value_json_string = wp_json_encode( $updated_confirmed_value->jsonSerialize() );
172        $wc_order->add_meta_data(
173            self::BITCOIN_AMOUNT_CONFIRMED_RECEIVED_META_KEY,
174            $updated_confirmed_value_json_string,
175            true
176        );
177        if ( $save_now ) {
178            $wc_order->save();
179        }
180    }
181
182    /**
183     * Get the total value with the required number of confirmations at the last checked time.
184     *
185     * @param WC_Order $wc_order The WooCommerce order.
186     */
187    public function get_confirmed_amount_received( WC_Order $wc_order ): ?Money {
188        $confirmed_amount_meta_string = $wc_order->get_meta( self::BITCOIN_AMOUNT_CONFIRMED_RECEIVED_META_KEY );
189        if ( ! is_string( $confirmed_amount_meta_string ) ) {
190            return null;
191        }
192        try {
193            return $this->json_mapper->mapToClassFromString(
194                $confirmed_amount_meta_string,
195                Money::class
196            );
197        } catch ( Exception ) {
198            return null;
199        }
200    }
201}