Completed
Push — update/pay-with-paypal-save-fa... ( 4eb26c...a6d1fd )
by
unknown
14:09 queued 05:13
created

Jetpack_Simple_Payments::output_purchase_box()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 26
rs 9.504
c 0
b 0
f 0
1
<?php
2
/*
3
 * Simple Payments lets users embed a PayPal button fully integrated with wpcom to sell products on the site.
4
 * This is not a proper module yet, because not all the pieces are in place. Until everything is shipped, it can be turned
5
 * into module that can be enabled/disabled.
6
*/
7
class Jetpack_Simple_Payments {
8
	// These have to be under 20 chars because that is CPT limit.
9
	static $post_type_order = 'jp_pay_order';
10
	static $post_type_product = 'jp_pay_product';
11
12
	static $shortcode = 'simple-payment';
13
14
	static $css_classname_prefix = 'jetpack-simple-payments';
15
16
	static $required_plan;
17
18
	// Increase this number each time there's a change in CSS or JS to bust cache.
19
	static $version = '0.25';
20
21
	// Classic singleton pattern:
22
	private static $instance;
23
	private function __construct() {}
24 View Code Duplication
	static function getInstance() {
25
		if ( ! self::$instance ) {
26
			self::$instance = new self();
27
			self::$instance->register_init_hooks();
28
			self::$required_plan = ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium';
29
		}
30
		return self::$instance;
31
	}
32
33
	private function register_scripts_and_styles() {
34
		/**
35
		 * Paypal heavily discourages putting that script in your own server:
36
		 * @see https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/add-paypal-button/
37
		 */
38
		wp_register_script( 'paypal-checkout-js', 'https://www.paypalobjects.com/api/checkout.js', array(), null, true );
39
		wp_register_script( 'paypal-express-checkout', plugins_url( '/paypal-express-checkout.js', __FILE__ ),
40
			array( 'jquery', 'paypal-checkout-js' ), self::$version );
41
		wp_register_style( 'jetpack-simple-payments', plugins_url( '/simple-payments.css', __FILE__ ), array( 'dashicons' ) );
42
	}
43
44
	private function register_init_hooks() {
45
		add_action( 'init', array( $this, 'init_hook_action' ) );
46
		add_action( 'rest_api_init', array( $this, 'register_meta_fields_in_rest_api' ) );
47
	}
48
49
	private function register_shortcode() {
50
		add_shortcode( self::$shortcode, array( $this, 'parse_shortcode' ) );
51
	}
52
53
	public function init_hook_action() {
54
		add_filter( 'rest_api_allowed_post_types', array( $this, 'allow_rest_api_types' ) );
55
		add_filter( 'jetpack_sync_post_meta_whitelist', array( $this, 'allow_sync_post_meta' ) );
56
		if ( ! is_admin() ) {
57
			$this->register_scripts_and_styles();
58
		}
59
		$this->register_shortcode();
60
		$this->setup_cpts();
61
62
		add_filter( 'the_content', array( $this, 'remove_auto_paragraph_from_product_description' ), 0 );
63
	}
64
65
	/**
66
	 * Enqueue the static assets needed in the frontend.
67
	 */
68
	public function enqueue_frontend_assets() {
69
		if ( ! wp_style_is( 'jetpack-simple-payments', 'enqueued' ) ) {
70
			wp_enqueue_style( 'jetpack-simple-payments' );
71
		}
72
73
		if ( ! wp_script_is( 'paypal-express-checkout', 'enqueued' ) ) {
74
			wp_enqueue_script( 'paypal-express-checkout' );
75
		}
76
	}
77
78
	/**
79
	 * Add an inline script for setting up the PayPal checkout button.
80
	 *
81
	 * @param int     $id Product ID.
82
	 * @param int     $dom_id ID of the DOM element with the purchase message.
83
	 * @param boolean $is_multiple Whether multiple items of the same product can be purchased.
84
	 */
85
	public function setup_paypal_checkout_button( $id, $dom_id, $is_multiple ) {
86
		wp_add_inline_script(
87
			'paypal-express-checkout',
88
			sprintf(
89
				"try{PaypalExpressCheckout.renderButton( '%d', '%d', '%s', '%d' );}catch(e){}",
90
				esc_js( $this->get_blog_id() ),
91
				esc_js( $id ),
92
				esc_js( $dom_id ),
93
				esc_js( $is_multiple )
94
			)
95
		);
96
	}
97
98
	function remove_auto_paragraph_from_product_description( $content ) {
99
		if ( get_post_type() === self::$post_type_product ) {
100
			remove_filter( 'the_content', 'wpautop' );
101
		}
102
103
		return $content;
104
	}
105
106
	function get_blog_id() {
107
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
108
			return get_current_blog_id();
109
		}
110
111
		return Jetpack_Options::get_option( 'id' );
112
	}
113
114
	/**
115
	 * Used to check whether Simple Payments are enabled for given site.
116
	 *
117
	 * @return bool True if Simple Payments are enabled, false otherwise.
118
	 */
119
	function is_enabled_jetpack_simple_payments() {
120
		/**
121
		 * Can be used by plugin authors to disable the conflicting output of Simple Payments.
122
		 *
123
		 * @since 6.3.0
124
		 *
125
		 * @param bool True if Simple Payments should be disabled, false otherwise.
126
		 */
127
		if ( apply_filters( 'jetpack_disable_simple_payments', false ) ) {
128
			return false;
129
		}
130
131
		// For WPCOM sites
132 View Code Duplication
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM && function_exists( 'has_any_blog_stickers' ) ) {
133
			$site_id = $this->get_blog_id();
134
			return has_any_blog_stickers( array( 'premium-plan', 'business-plan', 'ecommerce-plan' ), $site_id );
135
		}
136
137
		// For all Jetpack sites
138
		return Jetpack::is_active() && Jetpack_Plan::supports( 'simple-payments');
139
	}
140
141
	function parse_shortcode( $attrs, $content = false ) {
142
		if ( empty( $attrs['id'] ) ) {
143
			return;
144
		}
145
		$product = get_post( $attrs['id'] );
146
		if ( ! $product || is_wp_error( $product ) ) {
147
			return;
148
		}
149
		if ( $product->post_type !== self::$post_type_product || 'publish' !== $product->post_status ) {
150
			return;
151
		}
152
153
		// We allow for overriding the presentation labels
154
		$data = shortcode_atts( array(
155
			'blog_id'     => $this->get_blog_id(),
156
			'dom_id'      => uniqid( self::$css_classname_prefix . '-' . $product->ID . '_', true ),
157
			'class'       => self::$css_classname_prefix . '-' . $product->ID,
158
			'title'       => get_the_title( $product ),
159
			'description' => $product->post_content,
160
			'cta'         => get_post_meta( $product->ID, 'spay_cta', true ),
161
			'multiple'    => get_post_meta( $product->ID, 'spay_multiple', true ) || '0'
162
		), $attrs );
163
164
		$data['price'] = $this->format_price(
165
			get_post_meta( $product->ID, 'spay_price', true ),
166
			get_post_meta( $product->ID, 'spay_currency', true )
167
		);
168
169
		$data['id'] = $attrs['id'];
170
171
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
172
			require_once WP_CONTENT_DIR . '/lib/display-context.php';
173
			$context = \A8C\Display_Context\get_current_context();
174
			if ( \A8C\Display_Context\EMAIL === $context ) {
175
				// Avoid enqueueing unsupported files by emails.
176
				return $this->output_shortcode( $data );
177
			}
178
		}
179
180
		if ( ! $this->is_enabled_jetpack_simple_payments() ) {
181
			if ( ! is_feed() ) {
182
				return $this->output_admin_warning( $data );
183
			}
184
			return;
185
		}
186
187
		$this->enqueue_frontend_assets();
188
		$this->setup_paypal_checkout_button( $attrs['id'], $data['dom_id'], $data['multiple'] );
189
190
		return $this->output_shortcode( $data );
191
	}
192
193
	function output_admin_warning( $data ) {
194
		if ( ! current_user_can( 'manage_options' ) ) {
195
			return;
196
		}
197
198
		jetpack_require_lib( 'components' );
199
		return Jetpack_Components::render_upgrade_nudge( array(
200
			'plan' => self::$required_plan
201
		) );
202
	}
203
204
	/**
205
	 * Get the HTML output to use as PayPal purchase box.
206
	 *
207
	 * @param string  $dom_id ID of the DOM element with the purchase message.
208
	 * @param boolean $is_multiple Whether multiple items of the same product can be purchased.
209
	 *
210
	 * @return string
211
	 */
212
	public function output_purchase_box( $dom_id, $is_multiple ) {
213
		$items = '';
214
		$css_prefix = self::$css_classname_prefix;
215
216
		if ( $is_multiple ) {
217
			$items = sprintf( '
218
				<div class="%1$s">
219
					<input class="%2$s" type="number" value="1" min="1" id="%3$s" />
220
				</div>
221
				',
222
				esc_attr( "${css_prefix}-items" ),
223
				esc_attr( "${css_prefix}-items-number" ),
224
				esc_attr( "{$dom_id}_number" )
225
			);
226
		}
227
228
		return sprintf(
229
			'<div class="%1$s" id="%2$s"></div><div class="%3$s">%4$s<div class="%5$s" id="%6$s"></div></div>',
230
			esc_attr( "${css_prefix}-purchase-message" ),
231
			esc_attr( "{$dom_id}-message-container" ),
232
			esc_attr( "${css_prefix}-purchase-box" ),
233
			$items,
234
			esc_attr( "${css_prefix}-button" ),
235
			esc_attr( "{$dom_id}_button" )
236
		);
237
	}
238
239
	/**
240
	 * Get the HTML output to replace the `simple-payments` shortcode.
241
	 *
242
	 * @param array $data Product data.
243
	 * @return string
244
	 */
245
	public function output_shortcode( $data ) {
246
		$css_prefix = self::$css_classname_prefix;
247
248
		$image = "";
249
		if( has_post_thumbnail( $data['id'] ) ) {
250
			$image = sprintf( '<div class="%1$s"><div class="%2$s">%3$s</div></div>',
251
				esc_attr( "${css_prefix}-product-image" ),
252
				esc_attr( "${css_prefix}-image" ),
253
				get_the_post_thumbnail( $data['id'], 'full' )
254
			);
255
		}
256
257
		return sprintf( '
258
<div class="%1$s">
259
	<div class="%2$s">
260
		%3$s
261
		<div class="%4$s">
262
			<div class="%5$s"><p>%6$s</p></div>
263
			<div class="%7$s"><p>%8$s</p></div>
264
			<div class="%9$s"><p>%10$s</p></div>
265
			%11$s
266
		</div>
267
	</div>
268
</div>
269
',
270
			esc_attr( "{$data['class']} ${css_prefix}-wrapper" ),
271
			esc_attr( "${css_prefix}-product" ),
272
			$image,
273
			esc_attr( "${css_prefix}-details" ),
274
			esc_attr( "${css_prefix}-title" ),
275
			esc_html( $data['title'] ),
276
			esc_attr( "${css_prefix}-description" ),
277
			wp_kses( $data['description'], wp_kses_allowed_html( 'post' ) ),
278
			esc_attr( "${css_prefix}-price" ),
279
			esc_html( $data['price'] ),
280
			$this->output_purchase_box( $data['dom_id'], $data['multiple'] )
281
		);
282
	}
283
284
	/**
285
	 * Format a price with currency
286
	 *
287
	 * Uses currency-aware formatting to output a formatted price with a simple fallback.
288
	 *
289
	 * Largely inspired by WordPress.com's Store_Price::display_currency
290
	 *
291
	 * @param  string $price    Price.
292
	 * @param  string $currency Currency.
293
	 * @return string           Formatted price.
294
	 */
295
	private function format_price( $price, $currency ) {
296
		$currency_details = self::get_currency( $currency );
297
298
		if ( $currency_details ) {
299
			// Ensure USD displays as 1234.56 even in non-US locales.
300
			$amount = 'USD' === $currency
301
				? number_format( $price, $currency_details['decimal'], '.', ',' )
302
				: number_format_i18n( $price, $currency_details['decimal'] );
303
304
			return sprintf(
305
				$currency_details['format'],
306
				$currency_details['symbol'],
307
				$amount
308
			);
309
		}
310
311
		// Fall back to unspecified currency symbol like `¤1,234.05`.
312
		// @link https://en.wikipedia.org/wiki/Currency_sign_(typography).
313
		if ( ! $currency ) {
314
			return '¤' . number_format_i18n( $price, 2 );
315
		}
316
317
		return number_format_i18n( $price, 2 ) . ' ' . $currency;
318
	}
319
320
	/**
321
	 * Allows custom post types to be used by REST API.
322
	 * @param $post_types
323
	 * @see hook 'rest_api_allowed_post_types'
324
	 * @return array
325
	 */
326
	function allow_rest_api_types( $post_types ) {
327
		$post_types[] = self::$post_type_order;
328
		$post_types[] = self::$post_type_product;
329
		return $post_types;
330
	}
331
332
	function allow_sync_post_meta( $post_meta ) {
333
		return array_merge( $post_meta, array(
334
			'spay_paypal_id',
335
			'spay_status',
336
			'spay_product_id',
337
			'spay_quantity',
338
			'spay_price',
339
			'spay_customer_email',
340
			'spay_currency',
341
			'spay_cta',
342
			'spay_email',
343
			'spay_multiple',
344
			'spay_formatted_price',
345
		) );
346
	}
347
348
	/**
349
	 * Enable Simple payments custom meta values for access through the REST API.
350
	 * Field’s value will be exposed on a .meta key in the endpoint response,
351
	 * and WordPress will handle setting up the callbacks for reading and writing
352
	 * to that meta key.
353
	 *
354
	 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
355
	 */
356
	public function register_meta_fields_in_rest_api() {
357
		register_meta( 'post', 'spay_price', array(
358
			'description'       => esc_html__( 'Simple payments; price.', 'jetpack' ),
359
			'object_subtype'    => self::$post_type_product,
360
			'sanitize_callback' => array( $this, 'sanitize_price' ),
361
			'show_in_rest'      => true,
362
			'single'            => true,
363
			'type'              => 'number',
364
		) );
365
366
		register_meta( 'post', 'spay_currency', array(
367
			'description'       => esc_html__( 'Simple payments; currency code.', 'jetpack' ),
368
			'object_subtype'    => self::$post_type_product,
369
			'sanitize_callback' => array( $this, 'sanitize_currency' ),
370
			'show_in_rest'      => true,
371
			'single'            => true,
372
			'type'              => 'string',
373
		) );
374
375
		register_meta( 'post', 'spay_cta', array(
376
			'description'       => esc_html__( 'Simple payments; text with "Buy" or other CTA', 'jetpack' ),
377
			'object_subtype'    => self::$post_type_product,
378
			'sanitize_callback' => 'sanitize_text_field',
379
			'show_in_rest'      => true,
380
			'single'            => true,
381
			'type'              => 'string',
382
		) );
383
384
		register_meta( 'post', 'spay_multiple', array(
385
			'description'       => esc_html__( 'Simple payments; allow multiple items', 'jetpack' ),
386
			'object_subtype'    => self::$post_type_product,
387
			'sanitize_callback' => 'rest_sanitize_boolean',
388
			'show_in_rest'      => true,
389
			'single'            => true,
390
			'type'              => 'boolean',
391
		) );
392
393
		register_meta( 'post', 'spay_email', array(
394
			'description'       => esc_html__( 'Simple payments button; paypal email.', 'jetpack' ),
395
			'sanitize_callback' => 'sanitize_email',
396
			'show_in_rest'      => true,
397
			'single'            => true,
398
			'type'              => 'string',
399
		) );
400
401
		register_meta( 'post', 'spay_status', array(
402
			'description'       => esc_html__( 'Simple payments; status.', 'jetpack' ),
403
			'object_subtype'    => self::$post_type_product,
404
			'sanitize_callback' => 'sanitize_text_field',
405
			'show_in_rest'      => true,
406
			'single'            => true,
407
			'type'              => 'string',
408
		) );
409
	}
410
411
	/**
412
	 * Sanitize three-character ISO-4217 Simple payments currency
413
	 *
414
	 * List has to be in sync with list at the block's client side and widget's backend side:
415
	 * @link https://github.com/Automattic/jetpack/blob/31efa189ad223c0eb7ad085ac0650a23facf9ef5/extensions/blocks/simple-payments/constants.js#L9-L39
416
	 * @link https://github.com/Automattic/jetpack/blob/31efa189ad223c0eb7ad085ac0650a23facf9ef5/modules/widgets/simple-payments.php#L19-L44
417
	 *
418
	 * Currencies should be supported by PayPal:
419
	 * @link https://developer.paypal.com/docs/api/reference/currency-codes/
420
	 *
421
	 * Indian Rupee (INR) not supported because at the time of the creation of this file
422
	 * because it's limited to in-country PayPal India accounts only.
423
	 * Discussion: https://github.com/Automattic/wp-calypso/pull/28236
424
	 */
425
	public static function sanitize_currency( $currency ) {
426
		$valid_currencies = array(
427
			'USD',
428
			'EUR',
429
			'AUD',
430
			'BRL',
431
			'CAD',
432
			'CZK',
433
			'DKK',
434
			'HKD',
435
			'HUF',
436
			'ILS',
437
			'JPY',
438
			'MYR',
439
			'MXN',
440
			'TWD',
441
			'NZD',
442
			'NOK',
443
			'PHP',
444
			'PLN',
445
			'GBP',
446
			'RUB',
447
			'SGD',
448
			'SEK',
449
			'CHF',
450
			'THB',
451
		);
452
453
		return in_array( $currency, $valid_currencies ) ? $currency : false;
454
	}
455
456
	/**
457
	 * Sanitize price:
458
	 *
459
	 * Positive integers and floats
460
	 * Supports two decimal places.
461
	 * Maximum length: 10.
462
	 *
463
	 * See `price` from PayPal docs:
464
	 * @link https://developer.paypal.com/docs/api/orders/v1/#definition-item
465
	 *
466
	 * @param      $value
467
	 * @return null|string
468
	 */
469
	public static function sanitize_price( $price ) {
470
		return preg_match( '/^[0-9]{0,10}(\.[0-9]{0,2})?$/', $price ) ? $price : false;
471
	}
472
473
	/**
474
	 * Sets up the custom post types for the module.
475
	 */
476
	function setup_cpts() {
477
478
		/*
479
		 * ORDER data structure. holds:
480
		 * title = customer_name | 4xproduct_name
481
		 * excerpt = customer_name + customer contact info + customer notes from paypal form
482
		 * metadata:
483
		 * spay_paypal_id - paypal id of transaction
484
		 * spay_status
485
		 * spay_product_id - post_id of bought product
486
		 * spay_quantity - quantity of product
487
		 * spay_price - item price at the time of purchase
488
		 * spay_customer_email - customer email
489
		 * ... (WIP)
490
		 */
491
		$order_capabilities = array(
492
			'edit_post'             => 'edit_posts',
493
			'read_post'             => 'read_private_posts',
494
			'delete_post'           => 'delete_posts',
495
			'edit_posts'            => 'edit_posts',
496
			'edit_others_posts'     => 'edit_others_posts',
497
			'publish_posts'         => 'publish_posts',
498
			'read_private_posts'    => 'read_private_posts',
499
		);
500
		$order_args = array(
501
			'label'                 => esc_html_x( 'Order', 'noun: a quantity of goods or items purchased or sold', 'jetpack' ),
502
			'description'           => esc_html__( 'Simple Payments orders', 'jetpack' ),
503
			'supports'              => array( 'custom-fields', 'excerpt' ),
504
			'hierarchical'          => false,
505
			'public'                => false,
506
			'show_ui'               => false,
507
			'show_in_menu'          => false,
508
			'show_in_admin_bar'     => false,
509
			'show_in_nav_menus'     => false,
510
			'can_export'            => true,
511
			'has_archive'           => false,
512
			'exclude_from_search'   => true,
513
			'publicly_queryable'    => false,
514
			'rewrite'               => false,
515
			'capabilities'          => $order_capabilities,
516
			'show_in_rest'          => true,
517
		);
518
		register_post_type( self::$post_type_order, $order_args );
519
520
		/*
521
		 * PRODUCT data structure. Holds:
522
		 * title - title
523
		 * content - description
524
		 * thumbnail - image
525
		 * metadata:
526
		 * spay_price - price
527
		 * spay_formatted_price
528
		 * spay_currency - currency code
529
		 * spay_cta - text with "Buy" or other CTA
530
		 * spay_email - paypal email
531
		 * spay_multiple - allow for multiple items
532
		 * spay_status - status. { enabled | disabled }
533
		 */
534
		$product_capabilities = array(
535
			'edit_post'             => 'edit_posts',
536
			'read_post'             => 'read_private_posts',
537
			'delete_post'           => 'delete_posts',
538
			'edit_posts'            => 'publish_posts',
539
			'edit_others_posts'     => 'edit_others_posts',
540
			'publish_posts'         => 'publish_posts',
541
			'read_private_posts'    => 'read_private_posts',
542
		);
543
		$product_args = array(
544
			'label'                 => esc_html__( 'Product', 'jetpack' ),
545
			'description'           => esc_html__( 'Simple Payments products', 'jetpack' ),
546
			'supports'              => array( 'title', 'editor','thumbnail', 'custom-fields', 'author' ),
547
			'hierarchical'          => false,
548
			'public'                => false,
549
			'show_ui'               => false,
550
			'show_in_menu'          => false,
551
			'show_in_admin_bar'     => false,
552
			'show_in_nav_menus'     => false,
553
			'can_export'            => true,
554
			'has_archive'           => false,
555
			'exclude_from_search'   => true,
556
			'publicly_queryable'    => false,
557
			'rewrite'               => false,
558
			'capabilities'          => $product_capabilities,
559
			'show_in_rest'          => true,
560
		);
561
		register_post_type( self::$post_type_product, $product_args );
562
	}
563
564
	/**
565
	 * Format a price for display
566
	 *
567
	 * Largely taken from WordPress.com Store_Price class
568
	 *
569
	 * The currency array will have the shape:
570
	 *   format  => string sprintf format with placeholders `%1$s`: Symbol `%2$s`: Price.
571
	 *   symbol  => string Symbol string
572
	 *   desc    => string Text description of currency
573
	 *   decimal => int    Number of decimal places
574
	 *
575
	 * @param  string $the_currency The desired currency, e.g. 'USD'.
576
	 * @return ?array               Currency object or null if not found.
0 ignored issues
show
Documentation introduced by
The doc-type ?array could not be parsed: Unknown type name "?array" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
577
	 */
578
	private static function get_currency( $the_currency ) {
579
		$currencies = array(
580
			'USD' => array(
581
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
582
				'symbol'  => '$',
583
				'decimal' => 2,
584
			),
585
			'GBP' => array(
586
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
587
				'symbol'  => '&#163;',
588
				'decimal' => 2,
589
			),
590
			'JPY' => array(
591
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
592
				'symbol'  => '&#165;',
593
				'decimal' => 0,
594
			),
595
			'BRL' => array(
596
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
597
				'symbol'  => 'R$',
598
				'decimal' => 2,
599
			),
600
			'EUR' => array(
601
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
602
				'symbol'  => '&#8364;',
603
				'decimal' => 2,
604
			),
605
			'NZD' => array(
606
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
607
				'symbol'  => 'NZ$',
608
				'decimal' => 2,
609
			),
610
			'AUD' => array(
611
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
612
				'symbol'  => 'A$',
613
				'decimal' => 2,
614
			),
615
			'CAD' => array(
616
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
617
				'symbol'  => 'C$',
618
				'decimal' => 2,
619
			),
620
			'ILS' => array(
621
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
622
				'symbol'  => '₪',
623
				'decimal' => 2,
624
			),
625
			'RUB' => array(
626
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
627
				'symbol'  => '₽',
628
				'decimal' => 2,
629
			),
630
			'MXN' => array(
631
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
632
				'symbol'  => 'MX$',
633
				'decimal' => 2,
634
			),
635
			'MYR' => array(
636
				'format'  => '%2$s%1$s', // 1: Symbol 2: currency value
637
				'symbol'  => 'RM',
638
				'decimal' => 2,
639
			),
640
			'SEK' => array(
641
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
642
				'symbol'  => 'Skr',
643
				'decimal' => 2,
644
			),
645
			'HUF' => array(
646
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
647
				'symbol'  => 'Ft',
648
				'decimal' => 0, // Decimals are supported by Stripe but not by PayPal.
649
			),
650
			'CHF' => array(
651
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
652
				'symbol'  => 'CHF',
653
				'decimal' => 2,
654
			),
655
			'CZK' => array(
656
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
657
				'symbol'  => 'Kč',
658
				'decimal' => 2,
659
			),
660
			'DKK' => array(
661
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
662
				'symbol'  => 'Dkr',
663
				'decimal' => 2,
664
			),
665
			'HKD' => array(
666
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
667
				'symbol'  => 'HK$',
668
				'decimal' => 2,
669
			),
670
			'NOK' => array(
671
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
672
				'symbol'  => 'Kr',
673
				'decimal' => 2,
674
			),
675
			'PHP' => array(
676
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
677
				'symbol'  => '₱',
678
				'decimal' => 2,
679
			),
680
			'PLN' => array(
681
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
682
				'symbol'  => 'PLN',
683
				'decimal' => 2,
684
			),
685
			'SGD' => array(
686
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
687
				'symbol'  => 'S$',
688
				'decimal' => 2,
689
			),
690
			'TWD' => array(
691
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
692
				'symbol'  => 'NT$',
693
				'decimal' => 0, // Decimals are supported by Stripe but not by PayPal.
694
			),
695
			'THB' => array(
696
				'format'  => '%2$s%1$s', // 1: Symbol 2: currency value
697
				'symbol'  => '฿',
698
				'decimal' => 2,
699
			),
700
		);
701
702
		if ( isset( $currencies[ $the_currency ] ) ) {
703
			return $currencies[ $the_currency ];
704
		}
705
		return null;
706
	}
707
}
708
Jetpack_Simple_Payments::getInstance();
709