Changeset 3424485
- Timestamp:
- 12/21/2025 07:05:08 AM (3 months ago)
- Location:
- subscription
- Files:
-
- 30 edited
- 1 copied
-
tags/1.8.12 (copied) (copied from subscription/trunk)
-
tags/1.8.12/changelog.txt (modified) (1 diff)
-
tags/1.8.12/includes/Admin/Subscriptions.php (modified) (5 diffs)
-
tags/1.8.12/includes/Admin/views/related-subscriptions.php (modified) (1 diff)
-
tags/1.8.12/includes/Admin/views/subscription-info.php (modified) (1 diff)
-
tags/1.8.12/includes/Admin/views/subscription-list.php (modified) (1 diff)
-
tags/1.8.12/includes/Frontend/MyAccount.php (modified) (2 diffs)
-
tags/1.8.12/includes/Frontend/Order.php (modified) (1 diff)
-
tags/1.8.12/includes/Illuminate/Gateways/Paypal/Paypal.php (modified) (4 diffs)
-
tags/1.8.12/includes/Illuminate/Helper.php (modified) (3 diffs)
-
tags/1.8.12/includes/Illuminate/Subscription/Subscription.php (modified) (1 diff)
-
tags/1.8.12/includes/Illuminate/views/subscription-table.php (modified) (2 diffs)
-
tags/1.8.12/languages/wp_subscription.pot (modified) (10 diffs)
-
tags/1.8.12/subscription.php (modified) (3 diffs)
-
tags/1.8.12/templates/myaccount/subscriptions.php (modified) (1 diff)
-
tags/1.8.12/vendor/composer/installed.php (modified) (2 diffs)
-
trunk/changelog.txt (modified) (1 diff)
-
trunk/includes/Admin/Subscriptions.php (modified) (5 diffs)
-
trunk/includes/Admin/views/related-subscriptions.php (modified) (1 diff)
-
trunk/includes/Admin/views/subscription-info.php (modified) (1 diff)
-
trunk/includes/Admin/views/subscription-list.php (modified) (1 diff)
-
trunk/includes/Frontend/MyAccount.php (modified) (2 diffs)
-
trunk/includes/Frontend/Order.php (modified) (1 diff)
-
trunk/includes/Illuminate/Gateways/Paypal/Paypal.php (modified) (4 diffs)
-
trunk/includes/Illuminate/Helper.php (modified) (3 diffs)
-
trunk/includes/Illuminate/Subscription/Subscription.php (modified) (1 diff)
-
trunk/includes/Illuminate/views/subscription-table.php (modified) (2 diffs)
-
trunk/languages/wp_subscription.pot (modified) (10 diffs)
-
trunk/subscription.php (modified) (3 diffs)
-
trunk/templates/myaccount/subscriptions.php (modified) (1 diff)
-
trunk/vendor/composer/installed.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
subscription/tags/1.8.12/changelog.txt
r3419216 r3424485 1 1 *** WPSubscription Changelog *** 2 3 2025-12-21 - version 1.8.12 4 * fix: Subscription details default endpoint. 5 * fix: Proper subscription timings. 6 * fix: WordPress test up to version. 7 * fix: Other minor bugs. 2 8 3 9 2025-12-14 - version 1.8.11 -
subscription/tags/1.8.12/includes/Admin/Subscriptions.php
r3392314 r3424485 137 137 if ( 'subscrpt_start_date' === $column ) { 138 138 $start_date = get_post_meta( $post_id, '_subscrpt_start_date', true ); 139 echo ! empty( $start_date ) ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-';139 echo ! empty( $start_date ) ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; 140 140 } elseif ( 'subscrpt_customer' === $column ) { 141 141 ?> … … 151 151 } elseif ( 'subscrpt_next_date' === $column ) { 152 152 $next_date = get_post_meta( $post_id, '_subscrpt_next_date', true ); 153 echo ! empty( $next_date ) ? esc_html( gmdate( 'F d, Y', $next_date ) ) : '-';153 echo ! empty( $next_date ) ? esc_html( wp_date( 'F d, Y', $next_date ) ) : '-'; 154 154 } elseif ( 'subscrpt_status' === $column ) { 155 155 $status_obj = get_post_status_object( get_post_status( $post_id ) ); … … 377 377 'start_date' => array( 378 378 'label' => __( 'Started date', 'wp_subscription' ), 379 'value' => ! empty( $start_date ) ? gmdate( 'F d, Y', $trial && $trial_start_date ? $trial_start_date : $start_date ) : '-',379 'value' => ! empty( $start_date ) ? wp_date( 'F d, Y', $trial && $trial_start_date ? $trial_start_date : $start_date ) : '-', 380 380 ), 381 381 'next_date' => array( 382 382 'label' => __( 'Payment due date', 'wp_subscription' ), 383 'value' => ! empty( $next_date ) ? gmdate( 'F d, Y', $trial && $trial_end_date && 'on' === $trial_mode ? $trial_end_date : ( $next_date ?? '-' ) ) : '-',383 'value' => ! empty( $next_date ) ? wp_date( 'F d, Y', $trial && $trial_end_date && 'on' === $trial_mode ? $trial_end_date : ( $next_date ?? '-' ) ) : '-', 384 384 ), 385 385 'status' => array( … … 408 408 'trial_period' => array( 409 409 'label' => __( 'Trial Period', 'wp_subscription' ), 410 'value' => ( $trial_start_date && $trial_end_date ? ' [ ' . gmdate( 'F d, Y', $trial_start_date ) . ' - ' . gmdate( 'F d, Y', $trial_end_date ) . ' ] ' : __( 'Trial isn\'t activated yet! ', 'wp_subscription' ) ),410 'value' => ( $trial_start_date && $trial_end_date ? ' [ ' . wp_date( 'F d, Y', $trial_start_date ) . ' - ' . wp_date( 'F d, Y', $trial_end_date ) . ' ] ' : __( 'Trial isn\'t activated yet! ', 'wp_subscription' ) ), 411 411 ), 412 412 ) + array_slice( $rows, 3, count( $rows ) - 1, true ); … … 488 488 489 489 $started_date = $subscription_data['start_date'] ?? ''; 490 $started_date = ! empty( $started_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $started_date ) ) : '-';490 $started_date = ! empty( $started_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $started_date ) ) : '-'; 491 491 492 492 $next_payment_date = $subscription_data['next_date'] ?? ''; 493 $next_payment_date = ! empty( $next_payment_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $next_payment_date ) ) : '-';493 $next_payment_date = ! empty( $next_payment_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $next_payment_date ) ) : '-'; 494 494 495 495 $is_grace_period = isset( $subscription_data['grace_period'] ); 496 496 $grace_remaining = $subscription_data['grace_period']['remaining_days'] ?? 0; 497 497 $grace_end_date = $subscription_data['grace_period']['end_date'] ?? ''; 498 $grace_end_date = ! empty( $grace_end_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $grace_end_date ) ) : '';498 $grace_end_date = ! empty( $grace_end_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $grace_end_date ) ) : ''; 499 499 500 500 ?> -
subscription/tags/1.8.12/includes/Admin/views/related-subscriptions.php
r3381229 r3424485 41 41 42 42 $start_date = $subscription_data['start_date'] ?? ''; 43 $start_date = ! empty( $start_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $start_date ) ) : '-';43 $start_date = ! empty( $start_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $start_date ) ) : '-'; 44 44 45 45 $next_date = $subscription_data['next_date'] ?? ''; 46 $next_date = ! empty( $next_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $next_date ) ) : '-';46 $next_date = ! empty( $next_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $next_date ) ) : '-'; 47 47 48 48 $price = $subscription_data['price'] ?? 0; -
subscription/tags/1.8.12/includes/Admin/views/subscription-info.php
r3413403 r3424485 220 220 <tr> 221 221 <th style="padding:8px 10px;">Started date</th> 222 <td style="padding:8px 10px;"><?php echo $start_date ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-'; ?></td>222 <td style="padding:8px 10px;"><?php echo $start_date ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; ?></td> 223 223 </tr> 224 224 <tr> 225 225 <th style="padding:8px 10px;">Payment due date</th> 226 <td style="padding:8px 10px;"><?php echo $renewal_date ? esc_html( gmdate( 'F d, Y', $renewal_date ) ) : '-'; ?></td>226 <td style="padding:8px 10px;"><?php echo $renewal_date ? esc_html( wp_date( 'F d, Y', $renewal_date ) ) : '-'; ?></td> 227 227 </tr> 228 228 <tr> -
subscription/tags/1.8.12/includes/Admin/views/subscription-list.php
r3381229 r3424485 150 150 <?php endif; ?> 151 151 </td> 152 <td><?php echo $start_date ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-'; ?></td>153 <td><?php echo $renewal_date ? esc_html( gmdate( 'F d, Y', $renewal_date ) ) : '-'; ?></td>152 <td><?php echo $start_date ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; ?></td> 153 <td><?php echo $renewal_date ? esc_html( wp_date( 'F d, Y', $renewal_date ) ) : '-'; ?></td> 154 154 <td> 155 155 <?php if ( $is_grace_period && $grace_remaining > 0 ) : ?> -
subscription/tags/1.8.12/includes/Frontend/MyAccount.php
r3419216 r3424485 100 100 101 101 $start_date = $subscription_data['start_date'] ?? ''; 102 $start_date = ! empty( $start_date ) ? gmdate( 'F j, Y', strtotime( $start_date ) ) : '-';102 $start_date = ! empty( $start_date ) ? wp_date( 'F j, Y', strtotime( $start_date ) ) : '-'; 103 103 104 104 $next_date = $subscription_data['next_date'] ?? ''; 105 $next_date = ! empty( $next_date ) ? gmdate( 'F j, Y', strtotime( $next_date ) ) : '-';105 $next_date = ! empty( $next_date ) ? wp_date( 'F j, Y', strtotime( $next_date ) ) : '-'; 106 106 107 107 $trial = get_post_meta( $id, '_subscrpt_trial', true ); … … 122 122 $grace_remaining = $subscription_data['grace_period']['remaining_days'] ?? 0; 123 123 $grace_end_date = $subscription_data['grace_period']['end_date'] ?? ''; 124 $grace_end_date = ! empty( $grace_end_date ) ? gmdate( 'F j, Y', strtotime( $grace_end_date ) ) : '';124 $grace_end_date = ! empty( $grace_end_date ) ? wp_date( 'F j, Y', strtotime( $grace_end_date ) ) : ''; 125 125 126 126 $subscrpt_nonce = wp_create_nonce( 'subscrpt_nonce' ); -
subscription/tags/1.8.12/includes/Frontend/Order.php
r3406135 r3424485 47 47 48 48 $start_date_string = $subscription_data['start_date'] ?? ''; 49 $start_date = ! empty( $start_date_string ) ? gmdate( 'F d, Y', strtotime( $start_date_string ) ) : '-';49 $start_date = ! empty( $start_date_string ) ? wp_date( 'F d, Y', strtotime( $start_date_string ) ) : '-'; 50 50 51 51 $next_date_string = $subscription_data['next_date'] ?? ''; 52 $next_date = ! empty( $next_date_string ) ? gmdate( 'F d, Y', strtotime( $next_date_string ) ) : '-';52 $next_date = ! empty( $next_date_string ) ? wp_date( 'F d, Y', strtotime( $next_date_string ) ) : '-'; 53 53 54 54 $cost = $subscription_data['price'] ?? '0.00'; -
subscription/tags/1.8.12/includes/Illuminate/Gateways/Paypal/Paypal.php
r3349190 r3424485 416 416 */ 417 417 public function process_webhook() { 418 if ( ! isset( $_GET['wc-api'] ) || $this->id !== $_GET['wc-api'] ) { 419 wp_subscrpt_write_log( 'PayPal webhook called without valid API endpoint.' ); 420 return; 421 } 422 423 // Get Webhook Data. 424 $webhook_data = stripslashes_deep( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification 425 $headers = getallheaders(); 426 427 if ( empty( $webhook_data ) || ! count( $webhook_data ) ) { 428 $post_data = file_get_contents( 'php://input' ); 429 // Sanitize the raw input before decoding. 430 $post_data = sanitize_text_field( $post_data ); 431 $webhook_data = json_decode( $post_data, true ); 432 433 if ( ! $webhook_data ) { 434 wp_subscrpt_write_log( 'Webhook data is empty.' ); 435 wp_subscrpt_write_debug_log( "process_webhook EMPTY \n" . file_get_contents( 'php://input' ) ); 436 exit( 'Webhook data is empty.' ); 437 } 418 // Get raw webhook data. 419 $raw_body = file_get_contents( 'php://input' ); 420 $headers = function_exists( 'getallheaders' ) ? getallheaders() : []; 421 422 if ( empty( $raw_body ) ) { 423 wp_subscrpt_write_log( 'PayPal webhook data is empty.' ); 424 wp_subscrpt_write_debug_log( "PayPal - process_webhook EMPTY \n" . $raw_body ); 425 wp_die( 'PayPal webhook data is empty.', '400 Bad Request', [ 'response' => 400 ] ); 438 426 } 439 427 440 428 // Verify webhook. 441 $this->verify_webhook( $headers, $webhook_data ); 429 $this->verify_webhook( $headers, $raw_body ); 430 431 // Decode webhook data. 432 $webhook_data = json_decode( $raw_body, true ); 442 433 443 434 // Get event type from webhook data. … … 526 517 * Verify webhook data from PayPal. 527 518 * 528 * @param array $headers Headers from the request.529 * @param array $webhook_data Webhook datafrom PayPal.530 */ 531 public function verify_webhook( array $headers, array $webhook_data) {519 * @param array $headers Headers from the request. 520 * @param string $raw_body Webhook raw body from PayPal. 521 */ 522 public function verify_webhook( array $headers, string $raw_body ) { 532 523 // Get PayPal Access Token. 533 524 $access_token = $this->get_paypal_access_token(); … … 537 528 } 538 529 539 // Prepare the request to verify the webhook.530 // Prepare the request data to verify the webhook. 540 531 $payload = [ 541 'auth_algo' => $headers['P aypal-Auth-Algo'] ?? '',542 'cert_url' => $headers['P aypal-Cert-Url'] ?? '',543 'transmission_id' => $headers['P aypal-Transmission-Id'] ?? '',544 'transmission_sig' => $headers['P aypal-Transmission-Sig'] ?? '',545 'transmission_time' => $headers['P aypal-Transmission-Time'] ?? '',532 'auth_algo' => $headers['PAYPAL-AUTH-ALGO'] ?? $headers['Paypal-Auth-Algo'] ?? '', 533 'cert_url' => $headers['PAYPAL-CERT-URL'] ?? $headers['Paypal-Cert-Url'] ?? '', 534 'transmission_id' => $headers['PAYPAL-TRANSMISSION-ID'] ?? $headers['Paypal-Transmission-Id'] ?? '', 535 'transmission_sig' => $headers['PAYPAL-TRANSMISSION-SIG'] ?? $headers['Paypal-Transmission-Sig'] ?? '', 536 'transmission_time' => $headers['PAYPAL-TRANSMISSION-TIME'] ?? $headers['Paypal-Transmission-Time'] ?? '', 546 537 'webhook_id' => $this->webhook_id ?? '', 547 'webhook_event' => $ webhook_data,538 'webhook_event' => $raw_body, 548 539 ]; 549 540 550 $verified = $this->verify_paypal_webhook( $payload, $access_token ); 541 // Verify webhook via REST API. 542 $verified = $this->verify_paypal_webhook_rest_api( $payload, $raw_body, $access_token ); 543 544 if ( ! $verified ) { 545 // Fallback to manual method if REST API verification fails. 546 wp_subscrpt_write_log( 'PayPal webhook REST API verification failed. Retrying with manual verification.' ); 547 548 $verified = $this->verify_paypal_webhook_manual( $payload, $raw_body ); 549 } 551 550 552 551 if ( ! $verified ) { 553 552 wp_subscrpt_write_log( 'PayPal webhook verification failed.' ); 554 wp_subscrpt_write_debug_log( 'Webhook verification failed for data: ' . wp_json_encode( $webhook_data ));553 wp_subscrpt_write_debug_log( 'Webhook verification failed for data: ' . $raw_body ); 555 554 wp_die( 'Error: PayPal webhook verification failed.', '403 Forbidden', array( 'response' => 403 ) ); 556 555 } 556 } 557 558 /** 559 * Verify PayPal webhook with REST API. 560 * 561 * @param array $payload Payload data for verification. 562 * @param string $raw_body Webhook raw body from PayPal. 563 * @param string $access_token PayPal Access Token. 564 */ 565 protected function verify_paypal_webhook_rest_api( array $payload, string $raw_body, string $access_token ): bool { 566 // Fix the webhook_event to be an array. 567 $payload['webhook_event'] = json_decode( $raw_body, true ); 568 569 // Verify webhook signature via PayPal REST API. 570 try { 571 $url = $this->api_endpoint . '/v1/notifications/verify-webhook-signature'; 572 $args = [ 573 'method' => 'POST', 574 'headers' => [ 575 'Authorization' => 'Bearer ' . $access_token, 576 'Content-Type' => 'application/json', 577 ], 578 'body' => wp_json_encode( $payload ), 579 ]; 580 581 $response = wp_remote_post( $url, $args ); 582 $response_data = json_decode( wp_remote_retrieve_body( $response ), true ); 583 $verification_status = $response_data['verification_status'] ?? null; 584 585 if ( empty( $verification_status ) || 'success' !== strtolower( $verification_status ) ) { 586 wp_subscrpt_write_debug_log( 'PayPal Webhook Verification: ' . wp_json_encode( $response_data ) ); 587 return false; 588 } 589 590 return ( 'success' === strtolower( $verification_status ) ) ? true : false; 591 592 } catch ( Exception $e ) { 593 $log_message = 'PayPal Webhook Verification Failed: ' . $e->getMessage(); 594 wp_subscrpt_write_log( $log_message ); 595 wp_subscrpt_write_debug_log( $log_message ); 596 return false; 597 } 598 } 599 600 /** 601 * Verify PayPal webhook manually (self verification). 602 * 603 * @param array $payload Payload data for verification. 604 * @param string $raw_body Webhook raw body from PayPal. 605 */ 606 protected function verify_paypal_webhook_manual( array $payload, string $raw_body ): bool { 607 // Enforce CRC32 for 32-bit systems (edge case) 608 $crc = sprintf( '%u', crc32( $raw_body ) ); 609 610 // Build Message 611 $message = implode( 612 '|', 613 [ 614 $payload['transmission_id'], 615 $payload['transmission_time'], 616 $payload['webhook_id'], 617 $crc, 618 ] 619 ); 620 621 // Fetch & cache cert 622 $cert_url = esc_url_raw( $payload['cert_url'] ); 623 $cache_key = 'paypal_cert_' . md5( $cert_url ); 624 625 $cert_pem = get_transient( $cache_key ); 626 627 if ( ! $cert_pem ) { 628 $response = wp_remote_get( $cert_url, [ 'timeout' => 20 ] ); 629 if ( is_wp_error( $response ) ) { 630 return false; 631 } 632 633 $cert_pem = wp_remote_retrieve_body( $response ); 634 set_transient( $cache_key, $cert_pem, DAY_IN_SECONDS ); 635 } 636 637 if ( empty( $cert_pem ) ) { 638 return false; 639 } 640 641 // Signature 642 $signature = base64_decode( $payload['transmission_sig'], true ); 643 644 if ( false === $signature ) { 645 return false; 646 } 647 648 // Final verification 649 $verified = openssl_verify( 650 $message, 651 $signature, 652 $cert_pem, 653 OPENSSL_ALGO_SHA256 654 ); 655 656 return ( 1 === $verified ); 557 657 } 558 658 … … 1454 1554 1455 1555 /** 1456 * Verify PayPal webhook.1457 *1458 * @param array $verification_data Verification data to verify.1459 * @param string $access_token PayPal Access Token.1460 */1461 public function verify_paypal_webhook( array $verification_data, string $access_token ): bool {1462 try {1463 $url = $this->api_endpoint . '/v1/notifications/verify-webhook-signature';1464 $args = [1465 'method' => 'POST',1466 'headers' => [1467 'Authorization' => 'Bearer ' . $access_token,1468 'Content-Type' => 'application/json',1469 ],1470 'body' => wp_json_encode( $verification_data ),1471 ];1472 1473 $response = wp_remote_post( $url, $args );1474 $response_data = json_decode( wp_remote_retrieve_body( $response ) );1475 1476 if ( empty( $response_data->verification_status ?? null ) || 'SUCCESS' !== $response_data->verification_status ) {1477 wp_subscrpt_write_debug_log( 'PayPal Webhook Verification: ' . wp_json_encode( $response_data ) );1478 return false;1479 }1480 1481 if ( 'SUCCESS' === $response_data->verification_status ) {1482 return true;1483 } else {1484 return false;1485 }1486 } catch ( Exception $e ) {1487 $log_message = 'PayPal Webhook Verification Failed: ' . $e->getMessage();1488 wp_subscrpt_write_log( $log_message );1489 wp_subscrpt_write_debug_log( $log_message );1490 return false;1491 }1492 }1493 1494 /**1495 1556 * Get PayPal order details. 1496 1557 * -
subscription/tags/1.8.12/includes/Illuminate/Helper.php
r3415062 r3424485 25 25 */ 26 26 public static function get_typos( $number, $typo, $translate = false ) { 27 if ( 1 === (int) $number && 'days' === $typo ) { 28 return $translate ? __( 'day', 'wp_subscription' ) : 'day'; 29 } elseif ( 1 === (int) $number && 'weeks' === $typo ) { 30 return $translate ? __( 'week', 'wp_subscription' ) : 'week'; 31 } elseif ( 1 === (int) $number && 'months' === $typo ) { 32 return $translate ? __( 'month', 'wp_subscription' ) : 'month'; 33 } elseif ( 1 === (int) $number && 'years' === $typo ) { 34 return $translate ? __( 'year', 'wp_subscription' ) : 'year'; 35 } else { 36 return $typo; 27 switch ( strtolower( $typo ) ) { 28 case 'day': 29 case 'days': 30 return $translate 31 ? _n( 'day', 'days', $number, 'wp_subscription' ) 32 : ( (int) $number === 1 ? 'day' : 'days' ); 33 34 case 'week': 35 case 'weeks': 36 return $translate 37 ? _n( 'week', 'weeks', $number, 'wp_subscription' ) 38 : ( (int) $number === 1 ? 'week' : 'weeks' ); 39 40 case 'month': 41 case 'months': 42 return $translate 43 ? _n( 'month', 'months', $number, 'wp_subscription' ) 44 : ( (int) $number === 1 ? 'month' : 'months' ); 45 46 case 'year': 47 case 'years': 48 return $translate 49 ? _n( 'year', 'years', $number, 'wp_subscription' ) 50 : ( (int) $number === 1 ? 'year' : 'years' ); 51 52 default: 53 return $typo; 37 54 } 38 55 } … … 290 307 291 308 $time = 1 === (int) $item_meta['time'] ? null : $item_meta['time'] . '-'; 292 $type = self::get_typos( $item_meta['time'], $item_meta['type'] );309 $type = self::get_typos( $item_meta['time'], $item_meta['type'], true ); 293 310 294 311 $formatted_price = wc_price( … … 297 314 'currency' => $order->get_currency(), 298 315 ) 299 ) . ' / ' . $time . $type;316 ) . ' / ' . $time . ucfirst( $type ); 300 317 301 318 if ( $display_trial ) { 302 $trial = $item_meta['trial'];303 319 $has_trial = isset( $item_meta['trial'] ) && strlen( $item_meta['trial'] ) > 2; 320 $trial = $item_meta['trial'] ?? ''; 304 321 305 322 if ( $has_trial ) { 306 $trial_html = '<br/><small> + Got ' . $trial . ' free trial!</small>'; 323 // translators: %s: trial period. 324 $trial_html = '<br/><small> ' . sprintf( __( '+ %s free trial!', 'wp_subscription' ), $trial ) . '</small>'; 307 325 $formatted_price .= $trial_html; 308 326 } -
subscription/tags/1.8.12/includes/Illuminate/Subscription/Subscription.php
r3419216 r3424485 33 33 switch ( strtolower( $view ) ) { 34 34 case 'view_subs': 35 $default_endpoint = ' view-subscription';35 $default_endpoint = 'subscription'; 36 36 $endpoint = $is_pro ? get_option( 'wpsubs_custom_view_subscription_endpoint', $default_endpoint ) : $default_endpoint; 37 37 break; -
subscription/tags/1.8.12/includes/Illuminate/views/subscription-table.php
r3320126 r3424485 71 71 </th> 72 72 <td class="td" 73 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $next_date ) ? esc_html( gmdate( 'F d, Y', $next_date ) ) : '-'; ?></td>73 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $next_date ) ? esc_html( wp_date( 'F d, Y', $next_date ) ) : '-'; ?></td> 74 74 </tr> 75 75 <?php } else { ?> … … 88 88 </th> 89 89 <td class="td" 90 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $start_date ) ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-'; ?></td>90 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $start_date ) ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; ?></td> 91 91 </tr> 92 92 <?php } ?> -
subscription/tags/1.8.12/languages/wp_subscription.pot
r3419216 r3424485 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2025-12- 14T05:43:22+00:00\n"12 "POT-Creation-Date: 2025-12-21T06:59:21+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.12.0\n" … … 562 562 #: includes/Admin/views/integrations.php:46 563 563 #: includes/Admin/views/subscription-list.php:25 564 #: includes/Illuminate/Helper.php: 48564 #: includes/Illuminate/Helper.php:65 565 565 msgid "Active" 566 566 msgstr "" … … 835 835 836 836 #: includes/Admin/views/subscription-list.php:26 837 #: includes/Illuminate/Helper.php: 47837 #: includes/Illuminate/Helper.php:64 838 838 msgid "Pending" 839 839 msgstr "" 840 840 841 841 #: includes/Admin/views/subscription-list.php:27 842 #: includes/Illuminate/Helper.php: 52842 #: includes/Illuminate/Helper.php:69 843 843 msgid "Cancelled" 844 844 msgstr "" 845 845 846 846 #: includes/Admin/views/subscription-list.php:28 847 #: includes/Illuminate/Helper.php: 50847 #: includes/Illuminate/Helper.php:67 848 848 msgid "Expired" 849 849 msgstr "" 850 850 851 851 #: includes/Admin/views/subscription-list.php:29 852 #: includes/Illuminate/Helper.php: 53852 #: includes/Illuminate/Helper.php:70 853 853 msgid "Draft" 854 854 msgstr "" 855 855 856 856 #: includes/Admin/views/subscription-list.php:30 857 #: includes/Illuminate/Helper.php: 54857 #: includes/Illuminate/Helper.php:71 858 858 msgid "Trash" 859 859 msgstr "" … … 1085 1085 1086 1086 #: includes/functions.php:46 1087 #: includes/Illuminate/Helper.php: 281087 #: includes/Illuminate/Helper.php:31 1088 1088 msgid "day" 1089 msgstr "" 1089 msgid_plural "days" 1090 msgstr[0] "" 1091 msgstr[1] "" 1090 1092 1091 1093 #: includes/functions.php:48 1092 #: includes/Illuminate/Helper.php:3 01094 #: includes/Illuminate/Helper.php:37 1093 1095 msgid "week" 1094 msgstr "" 1096 msgid_plural "weeks" 1097 msgstr[0] "" 1098 msgstr[1] "" 1095 1099 1096 1100 #: includes/functions.php:50 1097 #: includes/Illuminate/Helper.php: 321101 #: includes/Illuminate/Helper.php:43 1098 1102 msgid "month" 1099 msgstr "" 1103 msgid_plural "months" 1104 msgstr[0] "" 1105 msgstr[1] "" 1100 1106 1101 1107 #: includes/functions.php:52 1102 #: includes/Illuminate/Helper.php: 341108 #: includes/Illuminate/Helper.php:49 1103 1109 msgid "year" 1104 msgstr "" 1110 msgid_plural "years" 1111 msgstr[0] "" 1112 msgstr[1] "" 1105 1113 1106 1114 #: includes/functions.php:414 … … 1109 1117 1110 1118 #: includes/functions.php:415 1111 #: includes/Illuminate/Helper.php:3 761119 #: includes/Illuminate/Helper.php:394 1112 1120 msgid "Renewal Order" 1113 1121 msgstr "" … … 1324 1332 1325 1333 #. translators: %1$s: alert name; %2$s: order id. 1326 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 5001334 #: includes/Illuminate/Gateways/Paypal/Paypal.php:491 1327 1335 #, php-format 1328 1336 msgid "PayPal webhook received [%s]. Order not found." … … 1330 1338 1331 1339 #. translators: %1$s: alert name; %2$s: order id. 1332 #: includes/Illuminate/Gateways/Paypal/Paypal.php:5 161340 #: includes/Illuminate/Gateways/Paypal/Paypal.php:507 1333 1341 #, php-format 1334 1342 msgid "PayPal webhook received [%s]. No actions taken." … … 1336 1344 1337 1345 #. translators: %1$s: alert name; %2$s: subscription id. 1338 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8071346 #: includes/Illuminate/Gateways/Paypal/Paypal.php:907 1339 1347 #, php-format 1340 1348 msgid "Transaction webhook received [%1$s]. No order found for subscription ID [%2$s]." 1341 1349 msgstr "" 1342 1350 1343 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8201351 #: includes/Illuminate/Gateways/Paypal/Paypal.php:920 1344 1352 msgid "Payment completed by paypal webhook." 1345 1353 msgstr "" 1346 1354 1347 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8251355 #: includes/Illuminate/Gateways/Paypal/Paypal.php:925 1348 1356 msgid "Failed to complete payment. Requested by paypal webhook." 1349 1357 msgstr "" 1350 1358 1351 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8341359 #: includes/Illuminate/Gateways/Paypal/Paypal.php:934 1352 1360 msgid "Payment refunded by paypal webhook." 1353 1361 msgstr "" 1354 1362 1355 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8391363 #: includes/Illuminate/Gateways/Paypal/Paypal.php:939 1356 1364 msgid "Failed to refund payment. Requested by paypal webhook." 1357 1365 msgstr "" 1358 1366 1359 1367 #. translators: %s: alert name. 1360 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8491368 #: includes/Illuminate/Gateways/Paypal/Paypal.php:949 1361 1369 #, php-format 1362 1370 msgid "Transaction webhook received [%s]. No actions taken." 1363 1371 msgstr "" 1364 1372 1365 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8751373 #: includes/Illuminate/Gateways/Paypal/Paypal.php:975 1366 1374 msgid "Subscription not found. Attempting to get from order item." 1367 1375 msgstr "" 1368 1376 1369 1377 #. translators: %s: alert name. 1370 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8941378 #: includes/Illuminate/Gateways/Paypal/Paypal.php:994 1371 1379 #, php-format 1372 1380 msgid "Subscription webhook received [%s]. Subscription not found." 1373 1381 msgstr "" 1374 1382 1375 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9071383 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1007 1376 1384 msgid "Subscription activated by PayPal webhook." 1377 1385 msgstr "" 1378 1386 1379 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9131380 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9261381 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9391387 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1013 1388 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1026 1389 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1039 1382 1390 msgid "Subscription webhook received. No actions taken." 1383 1391 msgstr "" 1384 1392 1385 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9201393 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1020 1386 1394 msgid "Subscription expired by PayPal webhook." 1387 1395 msgstr "" 1388 1396 1389 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9331397 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1033 1390 1398 msgid "Subscription cancelled by PayPal webhook." 1391 1399 msgstr "" 1392 1400 1393 1401 #. translators: %s: alert name. 1394 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9451402 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1045 1395 1403 #, php-format 1396 1404 msgid "Subscription webhook received [%s]. No actions taken." 1397 1405 msgstr "" 1398 1406 1399 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1 2571407 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1357 1400 1408 msgid "PayPal Product Creation Error: Product data is incomplete. Name and type are required." 1401 1409 msgstr "" … … 1443 1451 msgstr "" 1444 1452 1445 #: includes/Illuminate/Helper.php: 491453 #: includes/Illuminate/Helper.php:66 1446 1454 msgid "On Hold" 1447 1455 msgstr "" 1448 1456 1449 #: includes/Illuminate/Helper.php: 511457 #: includes/Illuminate/Helper.php:68 1450 1458 msgid "Pending Cancellation" 1451 1459 msgstr "" 1452 1460 1461 #. translators: %s: trial period. 1462 #: includes/Illuminate/Helper.php:324 1463 #, php-format 1464 msgid "+ %s free trial!" 1465 msgstr "" 1466 1453 1467 #. translators: %1$s: order id, %2$d: payment number, %3$d: total payments 1454 #: includes/Illuminate/Helper.php:3 641468 #: includes/Illuminate/Helper.php:382 1455 1469 #, php-format 1456 1470 msgid "Split payment installment %2$d of %3$d. Order %1$s created for subscription." 1457 1471 msgstr "" 1458 1472 1459 #: includes/Illuminate/Helper.php:3 691473 #: includes/Illuminate/Helper.php:387 1460 1474 msgid "Split Payment - Renewal" 1461 1475 msgstr "" 1462 1476 1463 1477 #. translators: order id. 1464 #: includes/Illuminate/Helper.php:3 731478 #: includes/Illuminate/Helper.php:391 1465 1479 #, php-format 1466 1480 msgid "The order %s has been created for the subscription" … … 1468 1482 1469 1483 #. translators: %1$s: order id, %2$d: max payments 1470 #: includes/Illuminate/Helper.php:4 541484 #: includes/Illuminate/Helper.php:472 1471 1485 #, php-format 1472 1486 msgid "Split payment subscription created successfully. Order: %1$s. Total installments: %2$d." 1473 1487 msgstr "" 1474 1488 1475 #: includes/Illuminate/Helper.php:4 581489 #: includes/Illuminate/Helper.php:476 1476 1490 msgid "Split Payment - New Subscription" 1477 1491 msgstr "" 1478 1492 1479 1493 #. translators: Order Id. 1480 #: includes/Illuminate/Helper.php:4 621494 #: includes/Illuminate/Helper.php:480 1481 1495 #, php-format 1482 1496 msgid "Subscription successfully created. Order is %s" 1483 1497 msgstr "" 1484 1498 1485 #: includes/Illuminate/Helper.php:4 651499 #: includes/Illuminate/Helper.php:483 1486 1500 #: includes/Illuminate/Post.php:67 1487 1501 msgid "New Subscription" 1488 1502 msgstr "" 1489 1503 1490 #: includes/Illuminate/Helper.php:1 0961504 #: includes/Illuminate/Helper.php:1114 1491 1505 msgid "Subscription renewal isn't possible due to previous order not completed or deletion." 1492 1506 msgstr "" -
subscription/tags/1.8.12/subscription.php
r3419216 r3424485 7 7 * Description: WPSubscription allow WooCommerce to enables recurring payments, subscriptions, and auto-renewals for digital and physical products. Supports Stripe, PayPal, Paddle, and more. 8 8 * 9 * Version: 1.8.1 19 * Version: 1.8.12 10 10 * 11 11 * Author: ConversWP … … 18 18 * 19 19 * Requires at least: 6.0 20 * Tested up to: 6. 820 * Tested up to: 6.9 21 21 * 22 22 * WC requires at least: 6.0 … … 51 51 * @var string 52 52 */ 53 const version = '1.8.1 1';53 const version = '1.8.12'; 54 54 55 55 /** -
subscription/tags/1.8.12/templates/myaccount/subscriptions.php
r3419216 r3424485 50 50 51 51 $start_date = $subscription_data['start_date'] ?? ''; 52 $start_date = ! empty( $start_date ) ? gmdate( 'F j, Y', strtotime( $start_date ) ) : '-';52 $start_date = ! empty( $start_date ) ? wp_date( 'F j, Y', strtotime( $start_date ) ) : '-'; 53 53 54 54 $next_date = $subscription_data['next_date'] ?? ''; 55 $next_date = ! empty( $next_date ) ? gmdate( 'F j, Y', strtotime( $next_date ) ) : '-';55 $next_date = ! empty( $next_date ) ? wp_date( 'F j, Y', strtotime( $next_date ) ) : '-'; 56 56 57 57 $trial = get_post_meta( get_the_ID(), '_subscrpt_trial', true ); -
subscription/tags/1.8.12/vendor/composer/installed.php
r3419216 r3424485 2 2 'root' => array( 3 3 'name' => 'converswp/subscription', 4 'pretty_version' => '1.8.1 1',5 'version' => '1.8.1 1.0',6 'reference' => ' cdc6fcf8aa53e23284845046caf19ef6649b6df0',4 'pretty_version' => '1.8.12', 5 'version' => '1.8.12.0', 6 'reference' => 'a9d0d2372826303a8c2a6a7ed051f99168ccbcdb', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'converswp/subscription' => array( 14 'pretty_version' => '1.8.1 1',15 'version' => '1.8.1 1.0',16 'reference' => ' cdc6fcf8aa53e23284845046caf19ef6649b6df0',14 'pretty_version' => '1.8.12', 15 'version' => '1.8.12.0', 16 'reference' => 'a9d0d2372826303a8c2a6a7ed051f99168ccbcdb', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', -
subscription/trunk/changelog.txt
r3419216 r3424485 1 1 *** WPSubscription Changelog *** 2 3 2025-12-21 - version 1.8.12 4 * fix: Subscription details default endpoint. 5 * fix: Proper subscription timings. 6 * fix: WordPress test up to version. 7 * fix: Other minor bugs. 2 8 3 9 2025-12-14 - version 1.8.11 -
subscription/trunk/includes/Admin/Subscriptions.php
r3392314 r3424485 137 137 if ( 'subscrpt_start_date' === $column ) { 138 138 $start_date = get_post_meta( $post_id, '_subscrpt_start_date', true ); 139 echo ! empty( $start_date ) ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-';139 echo ! empty( $start_date ) ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; 140 140 } elseif ( 'subscrpt_customer' === $column ) { 141 141 ?> … … 151 151 } elseif ( 'subscrpt_next_date' === $column ) { 152 152 $next_date = get_post_meta( $post_id, '_subscrpt_next_date', true ); 153 echo ! empty( $next_date ) ? esc_html( gmdate( 'F d, Y', $next_date ) ) : '-';153 echo ! empty( $next_date ) ? esc_html( wp_date( 'F d, Y', $next_date ) ) : '-'; 154 154 } elseif ( 'subscrpt_status' === $column ) { 155 155 $status_obj = get_post_status_object( get_post_status( $post_id ) ); … … 377 377 'start_date' => array( 378 378 'label' => __( 'Started date', 'wp_subscription' ), 379 'value' => ! empty( $start_date ) ? gmdate( 'F d, Y', $trial && $trial_start_date ? $trial_start_date : $start_date ) : '-',379 'value' => ! empty( $start_date ) ? wp_date( 'F d, Y', $trial && $trial_start_date ? $trial_start_date : $start_date ) : '-', 380 380 ), 381 381 'next_date' => array( 382 382 'label' => __( 'Payment due date', 'wp_subscription' ), 383 'value' => ! empty( $next_date ) ? gmdate( 'F d, Y', $trial && $trial_end_date && 'on' === $trial_mode ? $trial_end_date : ( $next_date ?? '-' ) ) : '-',383 'value' => ! empty( $next_date ) ? wp_date( 'F d, Y', $trial && $trial_end_date && 'on' === $trial_mode ? $trial_end_date : ( $next_date ?? '-' ) ) : '-', 384 384 ), 385 385 'status' => array( … … 408 408 'trial_period' => array( 409 409 'label' => __( 'Trial Period', 'wp_subscription' ), 410 'value' => ( $trial_start_date && $trial_end_date ? ' [ ' . gmdate( 'F d, Y', $trial_start_date ) . ' - ' . gmdate( 'F d, Y', $trial_end_date ) . ' ] ' : __( 'Trial isn\'t activated yet! ', 'wp_subscription' ) ),410 'value' => ( $trial_start_date && $trial_end_date ? ' [ ' . wp_date( 'F d, Y', $trial_start_date ) . ' - ' . wp_date( 'F d, Y', $trial_end_date ) . ' ] ' : __( 'Trial isn\'t activated yet! ', 'wp_subscription' ) ), 411 411 ), 412 412 ) + array_slice( $rows, 3, count( $rows ) - 1, true ); … … 488 488 489 489 $started_date = $subscription_data['start_date'] ?? ''; 490 $started_date = ! empty( $started_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $started_date ) ) : '-';490 $started_date = ! empty( $started_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $started_date ) ) : '-'; 491 491 492 492 $next_payment_date = $subscription_data['next_date'] ?? ''; 493 $next_payment_date = ! empty( $next_payment_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $next_payment_date ) ) : '-';493 $next_payment_date = ! empty( $next_payment_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $next_payment_date ) ) : '-'; 494 494 495 495 $is_grace_period = isset( $subscription_data['grace_period'] ); 496 496 $grace_remaining = $subscription_data['grace_period']['remaining_days'] ?? 0; 497 497 $grace_end_date = $subscription_data['grace_period']['end_date'] ?? ''; 498 $grace_end_date = ! empty( $grace_end_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $grace_end_date ) ) : '';498 $grace_end_date = ! empty( $grace_end_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $grace_end_date ) ) : ''; 499 499 500 500 ?> -
subscription/trunk/includes/Admin/views/related-subscriptions.php
r3381229 r3424485 41 41 42 42 $start_date = $subscription_data['start_date'] ?? ''; 43 $start_date = ! empty( $start_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $start_date ) ) : '-';43 $start_date = ! empty( $start_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $start_date ) ) : '-'; 44 44 45 45 $next_date = $subscription_data['next_date'] ?? ''; 46 $next_date = ! empty( $next_date ) ? gmdate( 'F j, Y - g:i A', strtotime( $next_date ) ) : '-';46 $next_date = ! empty( $next_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $next_date ) ) : '-'; 47 47 48 48 $price = $subscription_data['price'] ?? 0; -
subscription/trunk/includes/Admin/views/subscription-info.php
r3413403 r3424485 220 220 <tr> 221 221 <th style="padding:8px 10px;">Started date</th> 222 <td style="padding:8px 10px;"><?php echo $start_date ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-'; ?></td>222 <td style="padding:8px 10px;"><?php echo $start_date ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; ?></td> 223 223 </tr> 224 224 <tr> 225 225 <th style="padding:8px 10px;">Payment due date</th> 226 <td style="padding:8px 10px;"><?php echo $renewal_date ? esc_html( gmdate( 'F d, Y', $renewal_date ) ) : '-'; ?></td>226 <td style="padding:8px 10px;"><?php echo $renewal_date ? esc_html( wp_date( 'F d, Y', $renewal_date ) ) : '-'; ?></td> 227 227 </tr> 228 228 <tr> -
subscription/trunk/includes/Admin/views/subscription-list.php
r3381229 r3424485 150 150 <?php endif; ?> 151 151 </td> 152 <td><?php echo $start_date ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-'; ?></td>153 <td><?php echo $renewal_date ? esc_html( gmdate( 'F d, Y', $renewal_date ) ) : '-'; ?></td>152 <td><?php echo $start_date ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; ?></td> 153 <td><?php echo $renewal_date ? esc_html( wp_date( 'F d, Y', $renewal_date ) ) : '-'; ?></td> 154 154 <td> 155 155 <?php if ( $is_grace_period && $grace_remaining > 0 ) : ?> -
subscription/trunk/includes/Frontend/MyAccount.php
r3419216 r3424485 100 100 101 101 $start_date = $subscription_data['start_date'] ?? ''; 102 $start_date = ! empty( $start_date ) ? gmdate( 'F j, Y', strtotime( $start_date ) ) : '-';102 $start_date = ! empty( $start_date ) ? wp_date( 'F j, Y', strtotime( $start_date ) ) : '-'; 103 103 104 104 $next_date = $subscription_data['next_date'] ?? ''; 105 $next_date = ! empty( $next_date ) ? gmdate( 'F j, Y', strtotime( $next_date ) ) : '-';105 $next_date = ! empty( $next_date ) ? wp_date( 'F j, Y', strtotime( $next_date ) ) : '-'; 106 106 107 107 $trial = get_post_meta( $id, '_subscrpt_trial', true ); … … 122 122 $grace_remaining = $subscription_data['grace_period']['remaining_days'] ?? 0; 123 123 $grace_end_date = $subscription_data['grace_period']['end_date'] ?? ''; 124 $grace_end_date = ! empty( $grace_end_date ) ? gmdate( 'F j, Y', strtotime( $grace_end_date ) ) : '';124 $grace_end_date = ! empty( $grace_end_date ) ? wp_date( 'F j, Y', strtotime( $grace_end_date ) ) : ''; 125 125 126 126 $subscrpt_nonce = wp_create_nonce( 'subscrpt_nonce' ); -
subscription/trunk/includes/Frontend/Order.php
r3406135 r3424485 47 47 48 48 $start_date_string = $subscription_data['start_date'] ?? ''; 49 $start_date = ! empty( $start_date_string ) ? gmdate( 'F d, Y', strtotime( $start_date_string ) ) : '-';49 $start_date = ! empty( $start_date_string ) ? wp_date( 'F d, Y', strtotime( $start_date_string ) ) : '-'; 50 50 51 51 $next_date_string = $subscription_data['next_date'] ?? ''; 52 $next_date = ! empty( $next_date_string ) ? gmdate( 'F d, Y', strtotime( $next_date_string ) ) : '-';52 $next_date = ! empty( $next_date_string ) ? wp_date( 'F d, Y', strtotime( $next_date_string ) ) : '-'; 53 53 54 54 $cost = $subscription_data['price'] ?? '0.00'; -
subscription/trunk/includes/Illuminate/Gateways/Paypal/Paypal.php
r3349190 r3424485 416 416 */ 417 417 public function process_webhook() { 418 if ( ! isset( $_GET['wc-api'] ) || $this->id !== $_GET['wc-api'] ) { 419 wp_subscrpt_write_log( 'PayPal webhook called without valid API endpoint.' ); 420 return; 421 } 422 423 // Get Webhook Data. 424 $webhook_data = stripslashes_deep( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification 425 $headers = getallheaders(); 426 427 if ( empty( $webhook_data ) || ! count( $webhook_data ) ) { 428 $post_data = file_get_contents( 'php://input' ); 429 // Sanitize the raw input before decoding. 430 $post_data = sanitize_text_field( $post_data ); 431 $webhook_data = json_decode( $post_data, true ); 432 433 if ( ! $webhook_data ) { 434 wp_subscrpt_write_log( 'Webhook data is empty.' ); 435 wp_subscrpt_write_debug_log( "process_webhook EMPTY \n" . file_get_contents( 'php://input' ) ); 436 exit( 'Webhook data is empty.' ); 437 } 418 // Get raw webhook data. 419 $raw_body = file_get_contents( 'php://input' ); 420 $headers = function_exists( 'getallheaders' ) ? getallheaders() : []; 421 422 if ( empty( $raw_body ) ) { 423 wp_subscrpt_write_log( 'PayPal webhook data is empty.' ); 424 wp_subscrpt_write_debug_log( "PayPal - process_webhook EMPTY \n" . $raw_body ); 425 wp_die( 'PayPal webhook data is empty.', '400 Bad Request', [ 'response' => 400 ] ); 438 426 } 439 427 440 428 // Verify webhook. 441 $this->verify_webhook( $headers, $webhook_data ); 429 $this->verify_webhook( $headers, $raw_body ); 430 431 // Decode webhook data. 432 $webhook_data = json_decode( $raw_body, true ); 442 433 443 434 // Get event type from webhook data. … … 526 517 * Verify webhook data from PayPal. 527 518 * 528 * @param array $headers Headers from the request.529 * @param array $webhook_data Webhook datafrom PayPal.530 */ 531 public function verify_webhook( array $headers, array $webhook_data) {519 * @param array $headers Headers from the request. 520 * @param string $raw_body Webhook raw body from PayPal. 521 */ 522 public function verify_webhook( array $headers, string $raw_body ) { 532 523 // Get PayPal Access Token. 533 524 $access_token = $this->get_paypal_access_token(); … … 537 528 } 538 529 539 // Prepare the request to verify the webhook.530 // Prepare the request data to verify the webhook. 540 531 $payload = [ 541 'auth_algo' => $headers['P aypal-Auth-Algo'] ?? '',542 'cert_url' => $headers['P aypal-Cert-Url'] ?? '',543 'transmission_id' => $headers['P aypal-Transmission-Id'] ?? '',544 'transmission_sig' => $headers['P aypal-Transmission-Sig'] ?? '',545 'transmission_time' => $headers['P aypal-Transmission-Time'] ?? '',532 'auth_algo' => $headers['PAYPAL-AUTH-ALGO'] ?? $headers['Paypal-Auth-Algo'] ?? '', 533 'cert_url' => $headers['PAYPAL-CERT-URL'] ?? $headers['Paypal-Cert-Url'] ?? '', 534 'transmission_id' => $headers['PAYPAL-TRANSMISSION-ID'] ?? $headers['Paypal-Transmission-Id'] ?? '', 535 'transmission_sig' => $headers['PAYPAL-TRANSMISSION-SIG'] ?? $headers['Paypal-Transmission-Sig'] ?? '', 536 'transmission_time' => $headers['PAYPAL-TRANSMISSION-TIME'] ?? $headers['Paypal-Transmission-Time'] ?? '', 546 537 'webhook_id' => $this->webhook_id ?? '', 547 'webhook_event' => $ webhook_data,538 'webhook_event' => $raw_body, 548 539 ]; 549 540 550 $verified = $this->verify_paypal_webhook( $payload, $access_token ); 541 // Verify webhook via REST API. 542 $verified = $this->verify_paypal_webhook_rest_api( $payload, $raw_body, $access_token ); 543 544 if ( ! $verified ) { 545 // Fallback to manual method if REST API verification fails. 546 wp_subscrpt_write_log( 'PayPal webhook REST API verification failed. Retrying with manual verification.' ); 547 548 $verified = $this->verify_paypal_webhook_manual( $payload, $raw_body ); 549 } 551 550 552 551 if ( ! $verified ) { 553 552 wp_subscrpt_write_log( 'PayPal webhook verification failed.' ); 554 wp_subscrpt_write_debug_log( 'Webhook verification failed for data: ' . wp_json_encode( $webhook_data ));553 wp_subscrpt_write_debug_log( 'Webhook verification failed for data: ' . $raw_body ); 555 554 wp_die( 'Error: PayPal webhook verification failed.', '403 Forbidden', array( 'response' => 403 ) ); 556 555 } 556 } 557 558 /** 559 * Verify PayPal webhook with REST API. 560 * 561 * @param array $payload Payload data for verification. 562 * @param string $raw_body Webhook raw body from PayPal. 563 * @param string $access_token PayPal Access Token. 564 */ 565 protected function verify_paypal_webhook_rest_api( array $payload, string $raw_body, string $access_token ): bool { 566 // Fix the webhook_event to be an array. 567 $payload['webhook_event'] = json_decode( $raw_body, true ); 568 569 // Verify webhook signature via PayPal REST API. 570 try { 571 $url = $this->api_endpoint . '/v1/notifications/verify-webhook-signature'; 572 $args = [ 573 'method' => 'POST', 574 'headers' => [ 575 'Authorization' => 'Bearer ' . $access_token, 576 'Content-Type' => 'application/json', 577 ], 578 'body' => wp_json_encode( $payload ), 579 ]; 580 581 $response = wp_remote_post( $url, $args ); 582 $response_data = json_decode( wp_remote_retrieve_body( $response ), true ); 583 $verification_status = $response_data['verification_status'] ?? null; 584 585 if ( empty( $verification_status ) || 'success' !== strtolower( $verification_status ) ) { 586 wp_subscrpt_write_debug_log( 'PayPal Webhook Verification: ' . wp_json_encode( $response_data ) ); 587 return false; 588 } 589 590 return ( 'success' === strtolower( $verification_status ) ) ? true : false; 591 592 } catch ( Exception $e ) { 593 $log_message = 'PayPal Webhook Verification Failed: ' . $e->getMessage(); 594 wp_subscrpt_write_log( $log_message ); 595 wp_subscrpt_write_debug_log( $log_message ); 596 return false; 597 } 598 } 599 600 /** 601 * Verify PayPal webhook manually (self verification). 602 * 603 * @param array $payload Payload data for verification. 604 * @param string $raw_body Webhook raw body from PayPal. 605 */ 606 protected function verify_paypal_webhook_manual( array $payload, string $raw_body ): bool { 607 // Enforce CRC32 for 32-bit systems (edge case) 608 $crc = sprintf( '%u', crc32( $raw_body ) ); 609 610 // Build Message 611 $message = implode( 612 '|', 613 [ 614 $payload['transmission_id'], 615 $payload['transmission_time'], 616 $payload['webhook_id'], 617 $crc, 618 ] 619 ); 620 621 // Fetch & cache cert 622 $cert_url = esc_url_raw( $payload['cert_url'] ); 623 $cache_key = 'paypal_cert_' . md5( $cert_url ); 624 625 $cert_pem = get_transient( $cache_key ); 626 627 if ( ! $cert_pem ) { 628 $response = wp_remote_get( $cert_url, [ 'timeout' => 20 ] ); 629 if ( is_wp_error( $response ) ) { 630 return false; 631 } 632 633 $cert_pem = wp_remote_retrieve_body( $response ); 634 set_transient( $cache_key, $cert_pem, DAY_IN_SECONDS ); 635 } 636 637 if ( empty( $cert_pem ) ) { 638 return false; 639 } 640 641 // Signature 642 $signature = base64_decode( $payload['transmission_sig'], true ); 643 644 if ( false === $signature ) { 645 return false; 646 } 647 648 // Final verification 649 $verified = openssl_verify( 650 $message, 651 $signature, 652 $cert_pem, 653 OPENSSL_ALGO_SHA256 654 ); 655 656 return ( 1 === $verified ); 557 657 } 558 658 … … 1454 1554 1455 1555 /** 1456 * Verify PayPal webhook.1457 *1458 * @param array $verification_data Verification data to verify.1459 * @param string $access_token PayPal Access Token.1460 */1461 public function verify_paypal_webhook( array $verification_data, string $access_token ): bool {1462 try {1463 $url = $this->api_endpoint . '/v1/notifications/verify-webhook-signature';1464 $args = [1465 'method' => 'POST',1466 'headers' => [1467 'Authorization' => 'Bearer ' . $access_token,1468 'Content-Type' => 'application/json',1469 ],1470 'body' => wp_json_encode( $verification_data ),1471 ];1472 1473 $response = wp_remote_post( $url, $args );1474 $response_data = json_decode( wp_remote_retrieve_body( $response ) );1475 1476 if ( empty( $response_data->verification_status ?? null ) || 'SUCCESS' !== $response_data->verification_status ) {1477 wp_subscrpt_write_debug_log( 'PayPal Webhook Verification: ' . wp_json_encode( $response_data ) );1478 return false;1479 }1480 1481 if ( 'SUCCESS' === $response_data->verification_status ) {1482 return true;1483 } else {1484 return false;1485 }1486 } catch ( Exception $e ) {1487 $log_message = 'PayPal Webhook Verification Failed: ' . $e->getMessage();1488 wp_subscrpt_write_log( $log_message );1489 wp_subscrpt_write_debug_log( $log_message );1490 return false;1491 }1492 }1493 1494 /**1495 1556 * Get PayPal order details. 1496 1557 * -
subscription/trunk/includes/Illuminate/Helper.php
r3415062 r3424485 25 25 */ 26 26 public static function get_typos( $number, $typo, $translate = false ) { 27 if ( 1 === (int) $number && 'days' === $typo ) { 28 return $translate ? __( 'day', 'wp_subscription' ) : 'day'; 29 } elseif ( 1 === (int) $number && 'weeks' === $typo ) { 30 return $translate ? __( 'week', 'wp_subscription' ) : 'week'; 31 } elseif ( 1 === (int) $number && 'months' === $typo ) { 32 return $translate ? __( 'month', 'wp_subscription' ) : 'month'; 33 } elseif ( 1 === (int) $number && 'years' === $typo ) { 34 return $translate ? __( 'year', 'wp_subscription' ) : 'year'; 35 } else { 36 return $typo; 27 switch ( strtolower( $typo ) ) { 28 case 'day': 29 case 'days': 30 return $translate 31 ? _n( 'day', 'days', $number, 'wp_subscription' ) 32 : ( (int) $number === 1 ? 'day' : 'days' ); 33 34 case 'week': 35 case 'weeks': 36 return $translate 37 ? _n( 'week', 'weeks', $number, 'wp_subscription' ) 38 : ( (int) $number === 1 ? 'week' : 'weeks' ); 39 40 case 'month': 41 case 'months': 42 return $translate 43 ? _n( 'month', 'months', $number, 'wp_subscription' ) 44 : ( (int) $number === 1 ? 'month' : 'months' ); 45 46 case 'year': 47 case 'years': 48 return $translate 49 ? _n( 'year', 'years', $number, 'wp_subscription' ) 50 : ( (int) $number === 1 ? 'year' : 'years' ); 51 52 default: 53 return $typo; 37 54 } 38 55 } … … 290 307 291 308 $time = 1 === (int) $item_meta['time'] ? null : $item_meta['time'] . '-'; 292 $type = self::get_typos( $item_meta['time'], $item_meta['type'] );309 $type = self::get_typos( $item_meta['time'], $item_meta['type'], true ); 293 310 294 311 $formatted_price = wc_price( … … 297 314 'currency' => $order->get_currency(), 298 315 ) 299 ) . ' / ' . $time . $type;316 ) . ' / ' . $time . ucfirst( $type ); 300 317 301 318 if ( $display_trial ) { 302 $trial = $item_meta['trial'];303 319 $has_trial = isset( $item_meta['trial'] ) && strlen( $item_meta['trial'] ) > 2; 320 $trial = $item_meta['trial'] ?? ''; 304 321 305 322 if ( $has_trial ) { 306 $trial_html = '<br/><small> + Got ' . $trial . ' free trial!</small>'; 323 // translators: %s: trial period. 324 $trial_html = '<br/><small> ' . sprintf( __( '+ %s free trial!', 'wp_subscription' ), $trial ) . '</small>'; 307 325 $formatted_price .= $trial_html; 308 326 } -
subscription/trunk/includes/Illuminate/Subscription/Subscription.php
r3419216 r3424485 33 33 switch ( strtolower( $view ) ) { 34 34 case 'view_subs': 35 $default_endpoint = ' view-subscription';35 $default_endpoint = 'subscription'; 36 36 $endpoint = $is_pro ? get_option( 'wpsubs_custom_view_subscription_endpoint', $default_endpoint ) : $default_endpoint; 37 37 break; -
subscription/trunk/includes/Illuminate/views/subscription-table.php
r3320126 r3424485 71 71 </th> 72 72 <td class="td" 73 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $next_date ) ? esc_html( gmdate( 'F d, Y', $next_date ) ) : '-'; ?></td>73 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $next_date ) ? esc_html( wp_date( 'F d, Y', $next_date ) ) : '-'; ?></td> 74 74 </tr> 75 75 <?php } else { ?> … … 88 88 </th> 89 89 <td class="td" 90 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $start_date ) ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-'; ?></td>90 style="color: #636363; border: 1px solid #e5e5e5; vertical-align: middle; padding: 12px; text-align: left;"><?php echo ! empty( $start_date ) ? esc_html( wp_date( 'F d, Y', $start_date ) ) : '-'; ?></td> 91 91 </tr> 92 92 <?php } ?> -
subscription/trunk/languages/wp_subscription.pot
r3419216 r3424485 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2025-12- 14T05:43:22+00:00\n"12 "POT-Creation-Date: 2025-12-21T06:59:21+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.12.0\n" … … 562 562 #: includes/Admin/views/integrations.php:46 563 563 #: includes/Admin/views/subscription-list.php:25 564 #: includes/Illuminate/Helper.php: 48564 #: includes/Illuminate/Helper.php:65 565 565 msgid "Active" 566 566 msgstr "" … … 835 835 836 836 #: includes/Admin/views/subscription-list.php:26 837 #: includes/Illuminate/Helper.php: 47837 #: includes/Illuminate/Helper.php:64 838 838 msgid "Pending" 839 839 msgstr "" 840 840 841 841 #: includes/Admin/views/subscription-list.php:27 842 #: includes/Illuminate/Helper.php: 52842 #: includes/Illuminate/Helper.php:69 843 843 msgid "Cancelled" 844 844 msgstr "" 845 845 846 846 #: includes/Admin/views/subscription-list.php:28 847 #: includes/Illuminate/Helper.php: 50847 #: includes/Illuminate/Helper.php:67 848 848 msgid "Expired" 849 849 msgstr "" 850 850 851 851 #: includes/Admin/views/subscription-list.php:29 852 #: includes/Illuminate/Helper.php: 53852 #: includes/Illuminate/Helper.php:70 853 853 msgid "Draft" 854 854 msgstr "" 855 855 856 856 #: includes/Admin/views/subscription-list.php:30 857 #: includes/Illuminate/Helper.php: 54857 #: includes/Illuminate/Helper.php:71 858 858 msgid "Trash" 859 859 msgstr "" … … 1085 1085 1086 1086 #: includes/functions.php:46 1087 #: includes/Illuminate/Helper.php: 281087 #: includes/Illuminate/Helper.php:31 1088 1088 msgid "day" 1089 msgstr "" 1089 msgid_plural "days" 1090 msgstr[0] "" 1091 msgstr[1] "" 1090 1092 1091 1093 #: includes/functions.php:48 1092 #: includes/Illuminate/Helper.php:3 01094 #: includes/Illuminate/Helper.php:37 1093 1095 msgid "week" 1094 msgstr "" 1096 msgid_plural "weeks" 1097 msgstr[0] "" 1098 msgstr[1] "" 1095 1099 1096 1100 #: includes/functions.php:50 1097 #: includes/Illuminate/Helper.php: 321101 #: includes/Illuminate/Helper.php:43 1098 1102 msgid "month" 1099 msgstr "" 1103 msgid_plural "months" 1104 msgstr[0] "" 1105 msgstr[1] "" 1100 1106 1101 1107 #: includes/functions.php:52 1102 #: includes/Illuminate/Helper.php: 341108 #: includes/Illuminate/Helper.php:49 1103 1109 msgid "year" 1104 msgstr "" 1110 msgid_plural "years" 1111 msgstr[0] "" 1112 msgstr[1] "" 1105 1113 1106 1114 #: includes/functions.php:414 … … 1109 1117 1110 1118 #: includes/functions.php:415 1111 #: includes/Illuminate/Helper.php:3 761119 #: includes/Illuminate/Helper.php:394 1112 1120 msgid "Renewal Order" 1113 1121 msgstr "" … … 1324 1332 1325 1333 #. translators: %1$s: alert name; %2$s: order id. 1326 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 5001334 #: includes/Illuminate/Gateways/Paypal/Paypal.php:491 1327 1335 #, php-format 1328 1336 msgid "PayPal webhook received [%s]. Order not found." … … 1330 1338 1331 1339 #. translators: %1$s: alert name; %2$s: order id. 1332 #: includes/Illuminate/Gateways/Paypal/Paypal.php:5 161340 #: includes/Illuminate/Gateways/Paypal/Paypal.php:507 1333 1341 #, php-format 1334 1342 msgid "PayPal webhook received [%s]. No actions taken." … … 1336 1344 1337 1345 #. translators: %1$s: alert name; %2$s: subscription id. 1338 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8071346 #: includes/Illuminate/Gateways/Paypal/Paypal.php:907 1339 1347 #, php-format 1340 1348 msgid "Transaction webhook received [%1$s]. No order found for subscription ID [%2$s]." 1341 1349 msgstr "" 1342 1350 1343 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8201351 #: includes/Illuminate/Gateways/Paypal/Paypal.php:920 1344 1352 msgid "Payment completed by paypal webhook." 1345 1353 msgstr "" 1346 1354 1347 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8251355 #: includes/Illuminate/Gateways/Paypal/Paypal.php:925 1348 1356 msgid "Failed to complete payment. Requested by paypal webhook." 1349 1357 msgstr "" 1350 1358 1351 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8341359 #: includes/Illuminate/Gateways/Paypal/Paypal.php:934 1352 1360 msgid "Payment refunded by paypal webhook." 1353 1361 msgstr "" 1354 1362 1355 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8391363 #: includes/Illuminate/Gateways/Paypal/Paypal.php:939 1356 1364 msgid "Failed to refund payment. Requested by paypal webhook." 1357 1365 msgstr "" 1358 1366 1359 1367 #. translators: %s: alert name. 1360 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8491368 #: includes/Illuminate/Gateways/Paypal/Paypal.php:949 1361 1369 #, php-format 1362 1370 msgid "Transaction webhook received [%s]. No actions taken." 1363 1371 msgstr "" 1364 1372 1365 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8751373 #: includes/Illuminate/Gateways/Paypal/Paypal.php:975 1366 1374 msgid "Subscription not found. Attempting to get from order item." 1367 1375 msgstr "" 1368 1376 1369 1377 #. translators: %s: alert name. 1370 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 8941378 #: includes/Illuminate/Gateways/Paypal/Paypal.php:994 1371 1379 #, php-format 1372 1380 msgid "Subscription webhook received [%s]. Subscription not found." 1373 1381 msgstr "" 1374 1382 1375 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9071383 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1007 1376 1384 msgid "Subscription activated by PayPal webhook." 1377 1385 msgstr "" 1378 1386 1379 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9131380 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9261381 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9391387 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1013 1388 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1026 1389 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1039 1382 1390 msgid "Subscription webhook received. No actions taken." 1383 1391 msgstr "" 1384 1392 1385 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9201393 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1020 1386 1394 msgid "Subscription expired by PayPal webhook." 1387 1395 msgstr "" 1388 1396 1389 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9331397 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1033 1390 1398 msgid "Subscription cancelled by PayPal webhook." 1391 1399 msgstr "" 1392 1400 1393 1401 #. translators: %s: alert name. 1394 #: includes/Illuminate/Gateways/Paypal/Paypal.php: 9451402 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1045 1395 1403 #, php-format 1396 1404 msgid "Subscription webhook received [%s]. No actions taken." 1397 1405 msgstr "" 1398 1406 1399 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1 2571407 #: includes/Illuminate/Gateways/Paypal/Paypal.php:1357 1400 1408 msgid "PayPal Product Creation Error: Product data is incomplete. Name and type are required." 1401 1409 msgstr "" … … 1443 1451 msgstr "" 1444 1452 1445 #: includes/Illuminate/Helper.php: 491453 #: includes/Illuminate/Helper.php:66 1446 1454 msgid "On Hold" 1447 1455 msgstr "" 1448 1456 1449 #: includes/Illuminate/Helper.php: 511457 #: includes/Illuminate/Helper.php:68 1450 1458 msgid "Pending Cancellation" 1451 1459 msgstr "" 1452 1460 1461 #. translators: %s: trial period. 1462 #: includes/Illuminate/Helper.php:324 1463 #, php-format 1464 msgid "+ %s free trial!" 1465 msgstr "" 1466 1453 1467 #. translators: %1$s: order id, %2$d: payment number, %3$d: total payments 1454 #: includes/Illuminate/Helper.php:3 641468 #: includes/Illuminate/Helper.php:382 1455 1469 #, php-format 1456 1470 msgid "Split payment installment %2$d of %3$d. Order %1$s created for subscription." 1457 1471 msgstr "" 1458 1472 1459 #: includes/Illuminate/Helper.php:3 691473 #: includes/Illuminate/Helper.php:387 1460 1474 msgid "Split Payment - Renewal" 1461 1475 msgstr "" 1462 1476 1463 1477 #. translators: order id. 1464 #: includes/Illuminate/Helper.php:3 731478 #: includes/Illuminate/Helper.php:391 1465 1479 #, php-format 1466 1480 msgid "The order %s has been created for the subscription" … … 1468 1482 1469 1483 #. translators: %1$s: order id, %2$d: max payments 1470 #: includes/Illuminate/Helper.php:4 541484 #: includes/Illuminate/Helper.php:472 1471 1485 #, php-format 1472 1486 msgid "Split payment subscription created successfully. Order: %1$s. Total installments: %2$d." 1473 1487 msgstr "" 1474 1488 1475 #: includes/Illuminate/Helper.php:4 581489 #: includes/Illuminate/Helper.php:476 1476 1490 msgid "Split Payment - New Subscription" 1477 1491 msgstr "" 1478 1492 1479 1493 #. translators: Order Id. 1480 #: includes/Illuminate/Helper.php:4 621494 #: includes/Illuminate/Helper.php:480 1481 1495 #, php-format 1482 1496 msgid "Subscription successfully created. Order is %s" 1483 1497 msgstr "" 1484 1498 1485 #: includes/Illuminate/Helper.php:4 651499 #: includes/Illuminate/Helper.php:483 1486 1500 #: includes/Illuminate/Post.php:67 1487 1501 msgid "New Subscription" 1488 1502 msgstr "" 1489 1503 1490 #: includes/Illuminate/Helper.php:1 0961504 #: includes/Illuminate/Helper.php:1114 1491 1505 msgid "Subscription renewal isn't possible due to previous order not completed or deletion." 1492 1506 msgstr "" -
subscription/trunk/subscription.php
r3419216 r3424485 7 7 * Description: WPSubscription allow WooCommerce to enables recurring payments, subscriptions, and auto-renewals for digital and physical products. Supports Stripe, PayPal, Paddle, and more. 8 8 * 9 * Version: 1.8.1 19 * Version: 1.8.12 10 10 * 11 11 * Author: ConversWP … … 18 18 * 19 19 * Requires at least: 6.0 20 * Tested up to: 6. 820 * Tested up to: 6.9 21 21 * 22 22 * WC requires at least: 6.0 … … 51 51 * @var string 52 52 */ 53 const version = '1.8.1 1';53 const version = '1.8.12'; 54 54 55 55 /** -
subscription/trunk/templates/myaccount/subscriptions.php
r3419216 r3424485 50 50 51 51 $start_date = $subscription_data['start_date'] ?? ''; 52 $start_date = ! empty( $start_date ) ? gmdate( 'F j, Y', strtotime( $start_date ) ) : '-';52 $start_date = ! empty( $start_date ) ? wp_date( 'F j, Y', strtotime( $start_date ) ) : '-'; 53 53 54 54 $next_date = $subscription_data['next_date'] ?? ''; 55 $next_date = ! empty( $next_date ) ? gmdate( 'F j, Y', strtotime( $next_date ) ) : '-';55 $next_date = ! empty( $next_date ) ? wp_date( 'F j, Y', strtotime( $next_date ) ) : '-'; 56 56 57 57 $trial = get_post_meta( get_the_ID(), '_subscrpt_trial', true ); -
subscription/trunk/vendor/composer/installed.php
r3419216 r3424485 2 2 'root' => array( 3 3 'name' => 'converswp/subscription', 4 'pretty_version' => '1.8.1 1',5 'version' => '1.8.1 1.0',6 'reference' => ' cdc6fcf8aa53e23284845046caf19ef6649b6df0',4 'pretty_version' => '1.8.12', 5 'version' => '1.8.12.0', 6 'reference' => 'a9d0d2372826303a8c2a6a7ed051f99168ccbcdb', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'converswp/subscription' => array( 14 'pretty_version' => '1.8.1 1',15 'version' => '1.8.1 1.0',16 'reference' => ' cdc6fcf8aa53e23284845046caf19ef6649b6df0',14 'pretty_version' => '1.8.12', 15 'version' => '1.8.12.0', 16 'reference' => 'a9d0d2372826303a8c2a6a7ed051f99168ccbcdb', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../',
Note: See TracChangeset
for help on using the changeset viewer.