@@ -62,6 +62,10 @@ public function generate_html_note(): string {
62
62
$ lines = array_merge ( $ lines , $ fee_breakdown_lines );
63
63
}
64
64
65
+ if ( $ this ->has_tax () ) {
66
+ $ lines [] = $ this ->compose_tax_string ();
67
+ }
68
+
65
69
$ lines [] = $ this ->compose_net_string ();
66
70
67
71
$ html = '' ;
@@ -106,8 +110,16 @@ public function compose_fee_string(): string {
106
110
$ fixed = WC_Payments_Utils::interpret_stripe_amount ( (int ) $ fee_rates ['fixed ' ], $ fixed_currency );
107
111
$ history = $ fee_rates ['history ' ];
108
112
109
- $ fee_currency = $ data ['transaction_details ' ]['store_currency ' ];
110
- $ fee_amount = WC_Payments_Utils::interpret_stripe_amount ( (int ) $ data ['transaction_details ' ]['store_fee ' ], $ fee_currency );
113
+ if ( $ this ->has_tax () ) {
114
+ $ before_tax = $ data ['fee_rates ' ]['before_tax ' ];
115
+ $ fee_amount = $ before_tax ['amount ' ];
116
+ $ fee_currency = $ before_tax ['currency ' ];
117
+ } else {
118
+ $ fee_currency = $ data ['transaction_details ' ]['store_currency ' ];
119
+ $ fee_amount = (int ) $ data ['transaction_details ' ]['store_fee ' ];
120
+ }
121
+
122
+ $ formatted_fee_amount = $ this ->convert_and_format_fee_amount ( $ fee_amount , $ fee_currency );
111
123
112
124
$ base_fee_label = $ this ->is_base_fee_only ()
113
125
? __ ( 'Base fee ' , 'woocommerce-payments ' )
@@ -120,7 +132,7 @@ public function compose_fee_string(): string {
120
132
'%1$s (capped at %2$s): %3$s ' ,
121
133
$ base_fee_label ,
122
134
WC_Payments_Utils::format_currency ( $ fixed , $ fixed_currency ),
123
- WC_Payments_Utils:: format_currency ( - $ fee_amount , $ fee_currency )
135
+ $ formatted_fee_amount
124
136
);
125
137
}
126
138
$ is_same_symbol = $ this ->has_same_currency_symbol ( $ data ['transaction_details ' ]['store_currency ' ], $ data ['transaction_details ' ]['customer_currency ' ] );
@@ -131,7 +143,7 @@ public function compose_fee_string(): string {
131
143
self ::format_fee ( $ percentage ),
132
144
WC_Payments_Utils::format_currency ( $ fixed , $ fixed_currency ),
133
145
$ is_same_symbol ? ' ' . $ data ['transaction_details ' ]['customer_currency ' ] : '' ,
134
- WC_Payments_Utils:: format_currency ( - $ fee_amount , $ fee_currency ) ,
146
+ $ formatted_fee_amount ,
135
147
$ is_same_symbol ? " $ fee_currency " : ''
136
148
);
137
149
}
@@ -273,6 +285,38 @@ public function get_fee_breakdown() {
273
285
return $ fee_history_strings ;
274
286
}
275
287
288
+ /**
289
+ * Compose tax string.
290
+ *
291
+ * @return string|null
292
+ */
293
+ public function compose_tax_string (): ?string {
294
+ if ( ! $ this ->has_tax () ) {
295
+ return null ;
296
+ }
297
+
298
+ $ tax = $ this ->captured_event ['fee_rates ' ]['tax ' ];
299
+ $ tax_amount = $ tax ['amount ' ];
300
+ if ( 0 === $ tax_amount ) {
301
+ return null ;
302
+ }
303
+
304
+ $ tax_currency = $ tax ['currency ' ];
305
+ $ formatted_amount = $ this ->convert_and_format_fee_amount ( $ tax_amount , $ tax_currency );
306
+
307
+ $ tax_description = ' ' . $ this ->get_localized_tax_description ();
308
+ $ percentage_rate = $ tax ['percentage_rate ' ];
309
+ $ formatted_percentage = ' ( ' . self ::format_fee ( $ percentage_rate ) . '%) ' ;
310
+
311
+ return sprintf (
312
+ /* translators: 1: tax description 2: tax percentage 3: tax amount */
313
+ __ ( 'Tax%1$s%2$s: %3$s ' , 'woocommerce-payments ' ),
314
+ $ tax_description ,
315
+ $ formatted_percentage ,
316
+ $ formatted_amount
317
+ );
318
+ }
319
+
276
320
/**
277
321
* Check if this is a FX event.
278
322
*
@@ -461,4 +505,102 @@ private function format_explicit_currency_with_base( float $amount, string $curr
461
505
private function has_same_currency_symbol ( string $ base_currency , string $ currency ): bool {
462
506
return strcasecmp ( $ base_currency , $ currency ) !== 0 && get_woocommerce_currency_symbol ( $ base_currency ) === get_woocommerce_currency_symbol ( $ currency );
463
507
}
508
+
509
+ /**
510
+ * Check if the event has tax information.
511
+ *
512
+ * @return bool
513
+ */
514
+ private function has_tax (): bool {
515
+ return isset ( $ this ->captured_event ['fee_rates ' ]['tax ' ] );
516
+ }
517
+
518
+ /**
519
+ * Get localized tax description based on the tax description ID contained in the captured event.
520
+ *
521
+ * @return string|null
522
+ */
523
+ private function get_localized_tax_description (): ?string {
524
+ if ( ! isset ( $ this ->captured_event ['fee_rates ' ]['tax ' ]['description ' ] ) ) {
525
+ return null ;
526
+ }
527
+
528
+ $ tax_description_id = $ this ->captured_event ['fee_rates ' ]['tax ' ]['description ' ];
529
+
530
+ $ tax_descriptions = [
531
+ // European Union VAT.
532
+ 'AT VAT ' => __ ( 'AT VAT ' , 'woocommerce-payments ' ), // Austria.
533
+ 'BE VAT ' => __ ( 'BE VAT ' , 'woocommerce-payments ' ), // Belgium.
534
+ 'BG VAT ' => __ ( 'BG VAT ' , 'woocommerce-payments ' ), // Bulgaria.
535
+ 'CY VAT ' => __ ( 'CY VAT ' , 'woocommerce-payments ' ), // Cyprus.
536
+ 'CZ VAT ' => __ ( 'CZ VAT ' , 'woocommerce-payments ' ), // Czech Republic.
537
+ 'DE VAT ' => __ ( 'DE VAT ' , 'woocommerce-payments ' ), // Germany.
538
+ 'DK VAT ' => __ ( 'DK VAT ' , 'woocommerce-payments ' ), // Denmark.
539
+ 'EE VAT ' => __ ( 'EE VAT ' , 'woocommerce-payments ' ), // Estonia.
540
+ 'ES VAT ' => __ ( 'ES VAT ' , 'woocommerce-payments ' ), // Spain.
541
+ 'FI VAT ' => __ ( 'FI VAT ' , 'woocommerce-payments ' ), // Finland.
542
+ 'FR VAT ' => __ ( 'FR VAT ' , 'woocommerce-payments ' ), // France.
543
+ 'GB VAT ' => __ ( 'UK VAT ' , 'woocommerce-payments ' ), // United Kingdom.
544
+ 'GR VAT ' => __ ( 'GR VAT ' , 'woocommerce-payments ' ), // Greece.
545
+ 'HR VAT ' => __ ( 'HR VAT ' , 'woocommerce-payments ' ), // Croatia.
546
+ 'HU VAT ' => __ ( 'HU VAT ' , 'woocommerce-payments ' ), // Hungary.
547
+ 'IE VAT ' => __ ( 'IE VAT ' , 'woocommerce-payments ' ), // Ireland.
548
+ 'IT VAT ' => __ ( 'IT VAT ' , 'woocommerce-payments ' ), // Italy.
549
+ 'LT VAT ' => __ ( 'LT VAT ' , 'woocommerce-payments ' ), // Lithuania.
550
+ 'LU VAT ' => __ ( 'LU VAT ' , 'woocommerce-payments ' ), // Luxembourg.
551
+ 'LV VAT ' => __ ( 'LV VAT ' , 'woocommerce-payments ' ), // Latvia.
552
+ 'MT VAT ' => __ ( 'MT VAT ' , 'woocommerce-payments ' ), // Malta.
553
+ 'NL VAT ' => __ ( 'NL VAT ' , 'woocommerce-payments ' ), // Netherlands.
554
+ 'PL VAT ' => __ ( 'PL VAT ' , 'woocommerce-payments ' ), // Poland.
555
+ 'PT VAT ' => __ ( 'PT VAT ' , 'woocommerce-payments ' ), // Portugal.
556
+ 'RO VAT ' => __ ( 'RO VAT ' , 'woocommerce-payments ' ), // Romania.
557
+ 'SE VAT ' => __ ( 'SE VAT ' , 'woocommerce-payments ' ), // Sweden.
558
+ 'SI VAT ' => __ ( 'SI VAT ' , 'woocommerce-payments ' ), // Slovenia.
559
+ 'SK VAT ' => __ ( 'SK VAT ' , 'woocommerce-payments ' ), // Slovakia.
560
+
561
+ // GST Countries.
562
+ 'AU GST ' => __ ( 'AU GST ' , 'woocommerce-payments ' ), // Australia.
563
+ 'NZ GST ' => __ ( 'NZ GST ' , 'woocommerce-payments ' ), // New Zealand.
564
+ 'SG GST ' => __ ( 'SG GST ' , 'woocommerce-payments ' ), // Singapore.
565
+
566
+ // Other Tax Systems.
567
+ 'CH VAT ' => __ ( 'CH VAT ' , 'woocommerce-payments ' ), // Switzerland.
568
+ 'JP JCT ' => __ ( 'JP JCT ' , 'woocommerce-payments ' ), // Japan Consumption Tax.
569
+ ];
570
+
571
+ return $ tax_descriptions [ $ tax_description_id ] ?? __ ( 'Tax ' , 'woocommerce-payments ' );
572
+ }
573
+
574
+ /**
575
+ * Given the fee amount and currency, converts it to the store currency if necessary and formats using formatCurrency.
576
+ *
577
+ * @param float $fee_amount Fee amount to convert and format.
578
+ * @param string $fee_currency Fee currency to convert from.
579
+ *
580
+ * @return string Formatted fee amount in the store currency.
581
+ */
582
+ private function convert_and_format_fee_amount ( float $ fee_amount , string $ fee_currency ) {
583
+ $ fee_exchange_rate = $ this ->captured_event ['fee_rates ' ]['fee_exchange_rate ' ] ?? null ;
584
+ if ( ! $ this ->is_fx_event () || ! $ fee_exchange_rate ) {
585
+ return WC_Payments_Utils::format_currency (
586
+ -abs ( WC_Payments_Utils::interpret_stripe_amount ( $ fee_amount , $ fee_currency ) ),
587
+ $ fee_currency
588
+ );
589
+ }
590
+
591
+ $ rate = $ fee_exchange_rate ['rate ' ];
592
+ $ from_currency = $ fee_exchange_rate ['from_currency ' ] ?? null ;
593
+ $ store_currency = $ this ->captured_event ['transaction_details ' ]['store_currency ' ] ?? null ;
594
+
595
+ // Convert based on the direction of the exchange rate.
596
+ $ converted_amount =
597
+ $ fee_currency === $ from_currency
598
+ ? $ fee_amount * $ rate // Converting from store currency to customer currency.
599
+ : $ fee_amount / $ rate ; // Converting from customer currency to store currency.
600
+
601
+ return WC_Payments_Utils::format_currency (
602
+ -abs ( WC_Payments_Utils::interpret_stripe_amount ( $ converted_amount , $ store_currency ) ),
603
+ $ store_currency
604
+ );
605
+ }
464
606
}
0 commit comments