PluginProbe
WooCommerce / 11.1.0-rc.2
WooCommerce v11.1.0-rc.2
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 All 648 releases
woocommerce / src / Internal / Orders / PaymentInfo.php
PaymentInfo.php
170 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 declare( strict_types=1 );
3
4 namespace Automattic\WooCommerce\Internal\Orders;
5
6 use Automattic\WooCommerce\Utilities\StringUtil;
7 use WC_Abstract_Order;
8
9 /**
10 * Class PaymentInfo.
11 */
12 class PaymentInfo {
13 /**
14 * This array must contain all the names of the files in the CardIcons directory (without extension),
15 * except 'unknown'.
16 */
17 private const KNOWN_CARD_BRANDS = array(
18 'amex',
19 'diners',
20 'discover',
21 'interac',
22 'jcb',
23 'mastercard',
24 'visa',
25 );
26
27 /**
28 * Get info about the card used for payment on an order.
29 *
30 * @param WC_Abstract_Order $order The order in question.
31 *
32 * @return array
33 */
34 public static function get_card_info( WC_Abstract_Order $order ): array {
35 $method = $order->get_payment_method();
36
37 /**
38 * Filter to allow payment gateways to provide payment card info for an order.
39 *
40 * @since 9.5.0
41 *
42 * @param array|null $info The card info.
43 * @param WC_Abstract_Order $order The order.
44 */
45 $info = apply_filters( 'wc_order_payment_card_info', array(), $order );
46 if ( ! is_array( $info ) ) {
47 $info = array();
48 }
49
50 // Fallback for WooPayments.
51 if ( empty( $info ) && 'woocommerce_payments' === $method ) {
52 $info = self::get_wcpay_card_info( $order );
53 }
54
55 $defaults = array(
56 'payment_method' => $method,
57 'brand' => '',
58 'icon' => '',
59 'last4' => '',
60 );
61 $info = wp_parse_args( $info, $defaults );
62
63 if ( empty( $info['icon'] ) ) {
64 $info['icon'] = self::get_card_icon( $info['brand'] );
65 }
66
67 return $info;
68 }
69
70 /**
71 * Generate a CSS-compatible SVG icon of a card brand.
72 *
73 * @param string $brand The brand of the card.
74 *
75 * @return string
76 */
77 private static function get_card_icon( ?string $brand ): string {
78 $brand = strtolower( (string) $brand );
79
80 if ( ! in_array( $brand, self::KNOWN_CARD_BRANDS, true ) ) {
81 $brand = 'unknown';
82 }
83
84 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode, WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
85 return base64_encode( file_get_contents( __DIR__ . "/CardIcons/{$brand}.svg" ) );
86 }
87
88 /**
89 * Get info about the card used for payment on an order, when the payment gateway is WooPayments.
90 *
91 * @see https://docs.stripe.com/api/charges/object#charge_object-payment_method_details
92 *
93 * @param WC_Abstract_Order $order The order in question.
94 *
95 * @return array
96 */
97 private static function get_wcpay_card_info( WC_Abstract_Order $order ): array {
98 if ( 'woocommerce_payments' !== $order->get_payment_method() ) {
99 return array();
100 }
101
102 // This is a Woo-specific meta key, not used within WooPayments.
103 $cache_meta_key = '_wcpay_raw_payment_method_details';
104 $payment_details = null;
105 $stored_payment_details = $order->get_meta( $cache_meta_key );
106 if ( is_string( $stored_payment_details ) && strlen( $stored_payment_details ) > 0 ) {
107 $payment_details = json_decode( $stored_payment_details, true );
108 }
109
110 if ( ! $payment_details ) {
111 if ( ! class_exists( \WC_Payments::class ) ) {
112 return array();
113 }
114
115 $payment_method_id = $order->get_meta( '_payment_method_id' );
116 if ( ! $payment_method_id ) {
117 return array();
118 }
119
120 try {
121 $payment_details = \WC_Payments::get_payments_api_client()->get_payment_method( $payment_method_id );
122 } catch ( \Throwable $ex ) {
123 $order_id = $order->get_id();
124 $message = $ex->getMessage();
125 wc_get_logger()->error(
126 sprintf(
127 '%s - retrieving info for payment method %s for order %s: %s',
128 StringUtil::class_name_without_namespace( static::class ),
129 $payment_method_id,
130 $order_id,
131 $message
132 ),
133 array(
134 'source' => 'payment-info',
135 )
136 );
137
138 return array();
139 }
140
141 // Cache payment method details.
142 $order->update_meta_data( $cache_meta_key, wp_json_encode( $payment_details ) );
143 $order->save_meta_data();
144 }
145
146 $card_info = array();
147
148 if ( isset( $payment_details['type'], $payment_details[ $payment_details['type'] ] ) ) {
149 $details = $payment_details[ $payment_details['type'] ];
150 switch ( $payment_details['type'] ) {
151 case 'card':
152 default:
153 $card_info['brand'] = $details['brand'] ?? '';
154 $card_info['last4'] = $details['last4'] ?? '';
155 break;
156 case 'card_present':
157 case 'interac_present':
158 $card_info['brand'] = $details['brand'] ?? '';
159 $card_info['last4'] = $details['last4'] ?? '';
160 $card_info['account_type'] = $details['receipt']['account_type'] ?? '';
161 $card_info['aid'] = $details['receipt']['dedicated_file_name'] ?? '';
162 $card_info['app_name'] = $details['receipt']['application_preferred_name'] ?? '';
163 break;
164 }
165 }
166
167 return array_map( 'sanitize_text_field', $card_info );
168 }
169 }
170