Skip to content

Commit 1a7f1a7

Browse files
Requested fixes for next release (#127)
* Check if other gateways is enabled before hide checkout button issue #97 * Enable subscription amount change support Issue #106 * Accept states without letters mark variations on shipping restriction - Issue #122 * Render cart button on update shipping method * Unify version checker * Get order charge permission and charge id method * Force v2 version on orders * Remove duplicated assignation * Add charge id for the orders with open capture * Parse V1 ipn response to process it with V2 handler * Skip v1 IPN handler on migration done * Lowercase version on parsed IPN notification * Change string replace function and save order * Log notification Data for the V1 IPN * Fix typos * PHPCS issues * PHPCS manual fixes * PHPCS fixes * Fix function call. * Undo version change * Set Order Transaction Id (Saucal Issue #125) * Force Decimals to 2 on amounts sent to API Co-authored-by: Matias Saggiorato <saggiorato@saucal.com> Co-authored-by: Matias Saggiorato <matiassaggiorato@gmail.com>
1 parent 5cb02bc commit 1a7f1a7

13 files changed

+301
-61
lines changed

assets/js/amazon-wc-checkout.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
$( document.body ).on( 'updated_wc_div', renderButton );
6060
$( document.body ).on( 'updated_checkout', renderButton );
6161
$( document.body ).on( 'payment_method_selected', renderButton );
62+
$( document.body ).on( 'updated_shipping_method', renderButton );
6263

6364
function attemptRefreshData() {
6465
var dataCont = $( '#wc-apa-update-vals' );

includes/admin/class-wc-amazon-payments-advanced-order-admin.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function order_actions() {
2929

3030
$order_id = absint( $_POST['order_id'] );
3131
$order = wc_get_order( $order_id );
32-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
32+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_id );
3333
$id = isset( $_POST['amazon_id'] ) ? wc_clean( $_POST['amazon_id'] ) : '';
3434
$action = sanitize_title( $_POST['amazon_action'] );
3535

@@ -55,7 +55,7 @@ public function order_actions_non_ajax() {
5555
$order_id = absint( $_GET['post'] ); // TODO: This may break when custom data stores are implemented in the future.
5656
$order = wc_get_order( $order_id );
5757

58-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
58+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_id );
5959

6060
$id = isset( $_GET['amazon_id'] ) ? wc_clean( $_GET['amazon_id'] ) : '';
6161
$action = sanitize_title( $_GET['amazon_action'] );
@@ -134,7 +134,7 @@ public function authorization_box() {
134134
$order_id = absint( $post->ID );
135135
$order = wc_get_order( $order_id );
136136

137-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
137+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_id );
138138

139139
do_action( 'wc_amazon_authorization_box_render', $order, $version );
140140
}
@@ -174,7 +174,7 @@ public function auth_box_render( $order, $version ) {
174174

175175
$need_refresh = false;
176176

177-
$charge_permission_id = $order->get_meta( 'amazon_charge_permission_id' );
177+
$charge_permission_id = WC_Amazon_Payments_Advanced::get_order_charge_permission( $order->get_id() );
178178

179179
$charge_permission_cached_status = wc_apa()->get_gateway()->get_cached_charge_permission_status( $order );
180180

@@ -208,7 +208,7 @@ public function auth_box_render( $order, $version ) {
208208
break;
209209
}
210210

211-
$charge_id = $order->get_meta( 'amazon_charge_id' );
211+
$charge_id = WC_Amazon_Payments_Advanced::get_order_charge_id( $order->get_id() );
212212

213213
if ( ! empty( $charge_id ) ) {
214214
$charge_cached_status = wc_apa()->get_gateway()->get_cached_charge_status( $order );

includes/class-wc-amazon-payments-advanced-api.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,82 @@ private static function location_is_postcode( $location ) {
179179
return 'postcode' === $location->type;
180180
}
181181

182+
/**
183+
* Remove string from string letters.
184+
*
185+
* @param string $string String to clean.
186+
* @return string
187+
*/
188+
private static function remove_signs( $string ) {
189+
$marked_letters = array(
190+
'Š' => 'S',
191+
'š' => 's',
192+
'Ž' => 'Z',
193+
'ž' => 'z',
194+
'À' => 'A',
195+
'Á' => 'A',
196+
'Â' => 'A',
197+
'Ã' => 'A',
198+
'Ä' => 'A',
199+
'Å' => 'A',
200+
'Æ' => 'A',
201+
'Ç' => 'C',
202+
'È' => 'E',
203+
'É' => 'E',
204+
'Ê' => 'E',
205+
'Ë' => 'E',
206+
'Ì' => 'I',
207+
'Í' => 'I',
208+
'Î' => 'I',
209+
'Ï' => 'I',
210+
'Ñ' => 'N',
211+
'Ò' => 'O',
212+
'Ó' => 'O',
213+
'Ô' => 'O',
214+
'Õ' => 'O',
215+
'Ö' => 'O',
216+
'Ø' => 'O',
217+
'Ù' => 'U',
218+
'Ú' => 'U',
219+
'Û' => 'U',
220+
'Ü' => 'U',
221+
'Ý' => 'Y',
222+
'Þ' => 'B',
223+
'ß' => 'Ss',
224+
'à' => 'a',
225+
'á' => 'a',
226+
'â' => 'a',
227+
'ã' => 'a',
228+
'ä' => 'a',
229+
'å' => 'a',
230+
'æ' => 'a',
231+
'ç' => 'c',
232+
'è' => 'e',
233+
'é' => 'e',
234+
'ê' => 'e',
235+
'ë' => 'e',
236+
'ì' => 'i',
237+
'í' => 'i',
238+
'î' => 'i',
239+
'ï' => 'i',
240+
'ð' => 'o',
241+
'ñ' => 'n',
242+
'ò' => 'o',
243+
'ó' => 'o',
244+
'ô' => 'o',
245+
'õ' => 'o',
246+
'ö' => 'o',
247+
'ø' => 'o',
248+
'ù' => 'u',
249+
'ú' => 'u',
250+
'û' => 'u',
251+
'ý' => 'y',
252+
'þ' => 'b',
253+
'ÿ' => 'y',
254+
);
255+
return strtr( $string, apply_filters( 'woocommerce_amazon_pa_signs_to_remove', $marked_letters ) );
256+
}
257+
182258
/**
183259
* Return shipping restrictions for checkout sessions
184260
*
@@ -252,7 +328,12 @@ protected static function get_shipping_restrictions() {
252328

253329
$zones[ $country ]->statesOrRegions[] = $state;
254330
if ( 'US' !== $country ) {
331+
255332
$zones[ $country ]->statesOrRegions[] = $all_states[ $country ][ $state ];
333+
$variation_state = self::remove_signs( $all_states[ $country ][ $state ] );
334+
if ( $variation_state !== $all_states[ $country ][ $state ] ) {
335+
$zones[ $country ]->statesOrRegions[] = $variation_state;
336+
}
256337
}
257338
}
258339
}

includes/class-wc-amazon-payments-advanced-ipn-handler.php

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,32 @@ public function handle_notification_ipn_v2( $message ) {
408408
$notification_version = isset( $message['Message']['NotificationVersion'] ) ? strtolower( $message['Message']['NotificationVersion'] ) : 'v1';
409409

410410
if ( 'v2' !== $notification_version ) {
411-
return;
412-
}
411+
$notification_data = self::safe_load_xml( $message['Message']['NotificationData'], LIBXML_NOCDATA );
412+
413+
switch ( $message['Message']['NotificationType'] ) {
414+
case 'PaymentCapture':
415+
$type = 'CHARGE';
416+
$charge_id = (string) $notification_data->CaptureDetails->AmazonCaptureId; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
417+
break;
418+
case 'PaymentRefund':
419+
$type = 'REFUND';
420+
$charge_id = (string) $notification_data->RefundDetails->AmazonRefundId; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
421+
break;
422+
default:
423+
wc_apa()->log( 'No handler for notification with type ' . $message['Message']['NotificationType'], $notification_data );
424+
return;
425+
}
413426

414-
$notification = $message['Message'];
427+
$notification = array(
428+
'NotificationVersion' => 'v1',
429+
'NotificationType' => 'STATE_CHANGE',
430+
'ObjectType' => $type,
431+
'ObjectId' => $charge_id,
432+
);
433+
wc_apa()->log( 'Parsed IPN Notification from V1 to V2', $notification_data );
434+
} else {
435+
$notification = $message['Message'];
436+
}
415437

416438
if ( ! isset( $notification['MockedIPN'] ) ) { // Only log real IPNs received.
417439
wc_apa()->log( 'Received IPN', $notification );
@@ -574,4 +596,41 @@ public function handle_async_polling( $amazon_id, $type ) {
574596

575597
$this->handle_notification_ipn_v2( $mock_ipn );
576598
}
599+
600+
/**
601+
* Safe load XML.
602+
*
603+
* @param string $source XML input.
604+
* @param int $options Options.
605+
*
606+
* @return SimpleXMLElement|bool
607+
*/
608+
public static function safe_load_xml( $source, $options = 0 ) {
609+
$old = null;
610+
611+
if ( '<' !== substr( $source, 0, 1 ) ) {
612+
return false;
613+
}
614+
615+
if ( function_exists( 'libxml_disable_entity_loader' ) ) {
616+
$old = libxml_disable_entity_loader( true );
617+
}
618+
619+
$dom = new DOMDocument();
620+
$return = $dom->loadXML( $source, $options );
621+
622+
if ( ! is_null( $old ) ) {
623+
libxml_disable_entity_loader( $old );
624+
}
625+
626+
if ( ! $return ) {
627+
return false;
628+
}
629+
630+
if ( isset( $dom->doctype ) ) {
631+
return false;
632+
}
633+
634+
return simplexml_import_dom( $dom );
635+
}
577636
}

includes/class-wc-amazon-payments-advanced-rest-api-controller.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,10 @@ public function get_reference_state( $request ) {
264264
wc_apa()->get_gateway()->get_cached_charge_status( $order );
265265
}
266266

267-
$charge_permission_id = $order->get_meta( 'amazon_charge_permission_id' );
267+
$charge_permission_id = WC_Amazon_Payments_Advanced::get_order_charge_permission( $order->get_id() );
268268
$charge_permission_cached_status = wc_apa()->get_gateway()->get_cached_charge_permission_status( $order, true );
269269

270-
$charge_id = $order->get_meta( 'amazon_charge_id' );
270+
$charge_id = WC_Amazon_Payments_Advanced::get_order_charge_id( $order->get_id() );
271271
$charge_cached_status = wc_apa()->get_gateway()->get_cached_charge_status( $order, true );
272272

273273
// TODO: Implement subscriptions v1 billing agreement, along with auth and capture methods for that.
@@ -303,9 +303,8 @@ public function authorize( $request ) {
303303
if ( is_wp_error( $order_post ) ) {
304304
return $order_post;
305305
}
306-
307306
$order = wc_get_order( $order_post->ID );
308-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
307+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_post->ID );
309308
if ( 'v1' === strtolower( $version ) ) {
310309
$error = $this->get_missing_reference_id_request_error( $order_post );
311310
if ( is_wp_error( $error ) ) {
@@ -321,7 +320,7 @@ public function authorize( $request ) {
321320
$result['authorized'] = false;
322321
} else {
323322
$result['authorized'] = true;
324-
$result['amazon_charge_id'] = $order->get_meta( 'amazon_charge_id' );
323+
$result['amazon_charge_id'] = WC_Amazon_Payments_Advanced::get_order_charge_id( $order->get_id() );
325324
}
326325
return rest_ensure_response( $result );
327326
}
@@ -342,9 +341,8 @@ public function authorize_and_capture( $request ) {
342341
if ( is_wp_error( $order_post ) ) {
343342
return $order_post;
344343
}
345-
346344
$order = wc_get_order( $order_post->ID );
347-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
345+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_post->ID );
348346
if ( 'v1' === strtolower( $version ) ) {
349347
$error = $this->get_missing_reference_id_request_error( $order_post );
350348
if ( is_wp_error( $error ) ) {
@@ -361,7 +359,7 @@ public function authorize_and_capture( $request ) {
361359
} else {
362360
$result['authorized'] = true;
363361
$result['captured'] = true;
364-
$result['amazon_charge_id'] = $order->get_meta( 'amazon_charge_id' );
362+
$result['amazon_charge_id'] = WC_Amazon_Payments_Advanced::get_order_charge_id( $order->get_id() );
365363
}
366364
return rest_ensure_response( $result );
367365
}
@@ -423,7 +421,7 @@ public function close_authorization( $request ) {
423421
}
424422

425423
$order = wc_get_order( $order_post->ID );
426-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
424+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_post->ID );
427425
if ( 'v1' === strtolower( $version ) ) {
428426
$error = $this->get_missing_authorization_id_request_error( $order_post );
429427
if ( is_wp_error( $error ) ) {
@@ -471,7 +469,7 @@ public function capture( $request ) {
471469
}
472470

473471
$order = wc_get_order( $order_post->ID );
474-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
472+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_post->ID );
475473
if ( 'v1' === strtolower( $version ) ) {
476474
$error = $this->get_missing_authorization_id_request_error( $order_post );
477475
if ( is_wp_error( $error ) ) {
@@ -507,7 +505,7 @@ public function capture( $request ) {
507505
$result['captured'] = false;
508506
} else {
509507
$result['captured'] = true;
510-
$result['amazon_charge_id'] = $order->get_meta( 'amazon_charge_id' );
508+
$result['amazon_charge_id'] = WC_Amazon_Payments_Advanced::get_order_charge_id( $order->get_id() );
511509
}
512510
return rest_ensure_response( $result );
513511
}
@@ -530,7 +528,7 @@ public function refund( $request ) {
530528
}
531529

532530
$order = wc_get_order( $order_post->ID );
533-
$version = version_compare( $order->get_meta( 'amazon_payment_advanced_version' ), '2.0.0' ) >= 0 ? 'v2' : 'v1';
531+
$version = WC_Amazon_Payments_Advanced::get_order_version( $order_post->ID );
534532
if ( 'v1' === strtolower( $version ) ) {
535533
$error = $this->get_missing_capture_id_request_error( $order_post );
536534
if ( is_wp_error( $error ) ) {

includes/class-wc-gateway-amazon-payments-advanced-abstract.php

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,10 +437,12 @@ public function get_form_fields() {
437437
),
438438
),
439439
'hide_standard_checkout_button' => array(
440-
'title' => __( 'Standard checkout button', 'woocommerce-gateway-amazon-payments-advanced' ),
441-
'type' => 'checkbox',
442-
'label' => __( 'Hide standard checkout button on cart page', 'woocommerce-gateway-amazon-payments-advanced' ),
443-
'default' => 'no',
440+
'title' => __( 'Standard checkout button', 'woocommerce-gateway-amazon-payments-advanced' ),
441+
'description' => __( 'Hide standard checkout button on chart page. Only applies when there are not other gateways enabled.', 'woocommerce-gateway-amazon-payments-advanced' ),
442+
'desc_tip' => true,
443+
'type' => 'checkbox',
444+
'label' => __( 'Hide standard checkout button on cart page', 'woocommerce-gateway-amazon-payments-advanced' ),
445+
'default' => 'no',
444446
),
445447
'misc_options' => array(
446448
'title' => __( 'Miscellaneous', 'woocommerce-gateway-amazon-payments-advanced' ),
@@ -464,6 +466,15 @@ public function get_form_fields() {
464466
),
465467
);
466468

469+
if ( $this->has_other_gateways_enabled() ) {
470+
$this->form_fields['hide_standard_checkout_button'] = array_merge(
471+
$this->form_fields['hide_standard_checkout_button'],
472+
array(
473+
'disabled' => true,
474+
)
475+
);
476+
}
477+
467478
/**
468479
* For new merchants "enforce" the use of LPA ( Hide "Use Login with Amazon App" and consider it ticked.)
469480
* For old merchants, keep "Use Login with Amazon App" checkbox, as they can fallback to APA (no client id)
@@ -932,4 +943,21 @@ public function has_v1_settings() {
932943
return ! empty( $this->settings['seller_id'] );
933944
}
934945

946+
/**
947+
* Checks if site has other gateways enabled.
948+
*
949+
* @return bool
950+
*/
951+
public function has_other_gateways_enabled() {
952+
$gateways = WC()->payment_gateways()->get_available_payment_gateways();
953+
unset( $gateways['amazon_payments_advanced'] );
954+
if ( ! empty( $gateways ) ) {
955+
foreach ( $gateways as $gateway ) {
956+
if ( 'yes' === $gateway->enabled ) {
957+
return true;
958+
}
959+
}
960+
}
961+
return false;
962+
}
935963
}

includes/class-wc-gateway-amazon-payments-advanced-privacy.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ public function order_data_exporter( $email_address, $page = 1 ) {
107107
),
108108
array(
109109
'name' => __( 'Amazon Pay charge permission id', 'woocommerce-gateway-amazon-payments-advanced' ),
110-
'value' => get_post_meta( $order->get_id(), 'amazon_charge_permission_id', true ),
110+
'value' => WC_Amazon_Payments_Advanced::get_order_charge_permission( $order->get_id() ),
111111
),
112112
array(
113113
'name' => __( 'Amazon Pay charge id', 'woocommerce-gateway-amazon-payments-advanced' ),
114-
'value' => get_post_meta( $order->get_id(), 'amazon_charge_id', true ),
114+
'value' => WC_Amazon_Payments_Advanced::get_order_charge_id( $order->get_id() ),
115115
),
116116
),
117117
);
@@ -176,7 +176,7 @@ public function subscriptions_data_exporter( $email_address, $page = 1 ) {
176176
),
177177
array(
178178
'name' => __( 'Amazon Pay charge permission id', 'woocommerce-gateway-amazon-payments-advanced' ),
179-
'value' => get_post_meta( $subscription->get_id(), 'amazon_charge_permission_id', true ),
179+
'value' => WC_Amazon_Payments_Advanced::get_order_charge_permission( $subscription->get_id() ),
180180
),
181181
),
182182
);

0 commit comments

Comments
 (0)