| @@ -191,10 +191,11 @@ | ||
| 191 | 191 | * |
| 192 | 192 | * @param LP_Order $order |
| 193 | 193 | * |
| 194 | 194 | * @return bool |
| 195 | + * @deprecated 4.3.8 Use is_data_for_payment_subscription() instead. | |
| 195 | 196 | */ |
| 196 | - public function is_subscription_order( LP_Order $order ): bool { | |
| 197 | + /*public function is_subscription_order( LP_Order $order ): bool { | |
| 197 | 198 | |
| 198 | 199 | $order_id = $order->get_id(); |
| 199 | 200 | $saved_price_id = sanitize_text_field( (string) get_post_meta( $order_id, self::META_SUBSCRIPTION_PLAN_ID, true ) ); |
| 200 | 201 | if ( ! empty( $saved_price_id ) ) { |
| @@ -207,9 +208,9 @@ | ||
| 207 | 208 | $this |
| 208 | 209 | ); |
| 209 | 210 | |
| 210 | 211 | return $is_subscription; |
| 211 | - } | |
| 212 | + }*/ | |
| 212 | 213 | |
| 213 | 214 | /** |
| 214 | 215 | * Get subscription context for provider APIs. |
| 215 | 216 | * |
| @@ -218,10 +219,11 @@ | ||
| 218 | 219 | * |
| 219 | 220 | * @param LP_Order $order |
| 220 | 221 | * |
| 221 | 222 | * @return array |
| 223 | + * @deprecated 4.3.8 | |
| 222 | 224 | */ |
| 223 | - public function get_subscription_context( LP_Order $order ): array { | |
| 225 | + /*public function get_subscription_context( LP_Order $order ): array { | |
| 224 | 226 | $order_id = $order->get_id(); |
| 225 | 227 | |
| 226 | 228 | $context = array( |
| 227 | 229 | 'price_id' => get_post_meta( $order_id, self::META_SUBSCRIPTION_PLAN_ID, true ), |
| @@ -241,9 +243,9 @@ | ||
| 241 | 243 | $context['quantity'] = 1; |
| 242 | 244 | } |
| 243 | 245 | |
| 244 | 246 | return (array) apply_filters( 'learn-press/gateway/subscription-context', $context, $order, $this ); |
| 245 | - } | |
| 247 | + }*/ | |
| 246 | 248 | |
| 247 | 249 | /** |
| 248 | 250 | * Persist subscription identifiers to order before payment execution. |
| 249 | 251 | * |
| @@ -253,16 +255,17 @@ | ||
| 253 | 255 | * @param LP_Order $order |
| 254 | 256 | * @param array $data |
| 255 | 257 | * |
| 256 | 258 | * @return void |
| 259 | + * @deprecated 4.3.8 | |
| 257 | 260 | */ |
| 258 | - protected function persist_subscription_payment_identifiers( LP_Order $order, array $data ) { | |
| 261 | + /*protected function persist_subscription_payment_identifiers( LP_Order $order, array $data ) { | |
| 259 | 262 | |
| 260 | 263 | $order_id = $order->get_id(); |
| 261 | 264 | |
| 262 | 265 | update_post_meta( $order_id, self::META_SUBSCRIPTION_PLAN_ID, sanitize_text_field( (string) ( $data['price_id'] ?? '' ) ) ); |
| 263 | 266 | update_post_meta( $order_id, self::META_SUBSCRIPTION_QUANTITY, max( 1, absint( $data['quantity'] ?? 1 ) ) ); |
| 264 | - } | |
| 267 | + }*/ | |
| 265 | 268 | /** |
| 266 | 269 | * Resolve normalized subscription payment params from order context. |
| 267 | 270 | * |
| 268 | 271 | * Behavior: |
| @@ -275,10 +278,11 @@ | ||
| 275 | 278 | * @param LP_Order $order |
| 276 | 279 | * |
| 277 | 280 | * @return array |
| 278 | 281 | * @throws Exception |
| 282 | + * @deprecated 4.3.8 Use is_data_for_payment_subscription() instead. | |
| 279 | 283 | */ |
| 280 | - public function resolve_subscription_payment_data( LP_Order $order ): array { | |
| 284 | + /*public function resolve_subscription_payment_data( LP_Order $order ): array { | |
| 281 | 285 | $context = $this->get_subscription_context( $order ); |
| 282 | 286 | $context = wp_parse_args( |
| 283 | 287 | $context, |
| 284 | 288 | array( |
| @@ -303,8 +307,39 @@ | ||
| 303 | 307 | throw new Exception( __( 'Missing subscription price id.', 'learnpress' ) ); |
| 304 | 308 | } |
| 305 | 309 | |
| 306 | 310 | return array(); |
| 311 | + }*/ | |
| 312 | + | |
| 313 | + /** | |
| 314 | + * Check data is type payment for subscription | |
| 315 | + * If LP order has data plan id, return data subscription | |
| 316 | + * | |
| 317 | + * @return false|array | |
| 318 | + * @since 4.3.8 | |
| 319 | + * @version 1.0.0 | |
| 320 | + */ | |
| 321 | + public function is_data_for_payment_subscription( LP_Order $lp_order ) { | |
| 322 | + $data_subscription = [ | |
| 323 | + 'plan_id' => '', | |
| 324 | + 'success_url' => $this->get_return_url( $lp_order ), | |
| 325 | + 'cancel_url' => LP_Helper::get_link_no_cache( learn_press_get_page_link( 'checkout' ) ), | |
| 326 | + ]; | |
| 327 | + | |
| 328 | + // Check LP order has data plan id | |
| 329 | + $plan_id = get_post_meta( $lp_order->get_id(), self::META_SUBSCRIPTION_PLAN_ID, true ); | |
| 330 | + if ( empty( $plan_id ) ) { | |
| 331 | + return false; | |
| 332 | + } | |
| 333 | + | |
| 334 | + $data_subscription['plan_id'] = $plan_id; | |
| 335 | + | |
| 336 | + return apply_filters( | |
| 337 | + 'learn-press/gateway/subscription-payment-data', | |
| 338 | + $data_subscription, | |
| 339 | + $lp_order, | |
| 340 | + $this | |
| 341 | + ); | |
| 307 | 342 | } |
| 308 | 343 | |
| 309 | 344 | /** |
| 310 | 345 | * Normalize and validate the shared subscription checkout payload. |
| @@ -321,10 +356,11 @@ | ||
| 321 | 356 | * @param array $data |
| 322 | 357 | * |
| 323 | 358 | * @return array Normalized payload array. |
| 324 | 359 | * @throws Exception |
| 360 | + * @deprecated 4.3.8 | |
| 325 | 361 | */ |
| 326 | - protected function validate_subscription_payload( array $data ): array { | |
| 362 | + /*protected function validate_subscription_payload( array $data ): array { | |
| 327 | 363 | // Apply safe defaults to guarantee a stable input shape. |
| 328 | 364 | $data = wp_parse_args( |
| 329 | 365 | $data, |
| 330 | 366 | array( |
| @@ -360,9 +396,9 @@ | ||
| 360 | 396 | throw new Exception( __( 'Missing subscription return URLs.', 'learnpress' ) ); |
| 361 | 397 | } |
| 362 | 398 | |
| 363 | 399 | return $data; |
| 364 | - } | |
| 400 | + }*/ | |
| 365 | 401 | |
| 366 | 402 | /** |
| 367 | 403 | * Generic subscription checkout flow. |
| 368 | 404 | * |
| @@ -373,10 +409,29 @@ | ||
| 373 | 409 | * |
| 374 | 410 | * @return array |
| 375 | 411 | * @throws Exception |
| 376 | 412 | */ |
| 377 | - public function pay_subscription( array $data ): array { | |
| 413 | + /*public function pay_subscription( array $data ): array { | |
| 378 | 414 | throw new Exception( sprintf( __( 'Gateway %s does not support subscription payment.', 'learnpress' ), $this->get_id() ) ); |
| 415 | + }*/ | |
| 416 | + | |
| 417 | + /** | |
| 418 | + * Generic subscription checkout flow. | |
| 419 | + * | |
| 420 | + * Child gateways should override this method and return a payload with at | |
| 421 | + * least `status` and `redirect_url` on success. | |
| 422 | + * $data required key: plan_id | |
| 423 | + * | |
| 424 | + * @param LP_Order $lp_order | |
| 425 | + * @param array $data | |
| 426 | + * | |
| 427 | + * @return array | |
| 428 | + * @throws Exception | |
| 429 | + * @since 4.3.8 | |
| 430 | + * @version 1.0.0 | |
| 431 | + */ | |
| 432 | + public function pay_via_subscription( LP_Order $lp_order, array $data ): array { | |
| 433 | + throw new Exception( sprintf( __( 'Gateway %s does not support subscription payment.', 'learnpress' ), $this->get_id() ) ); | |
| 379 | 434 | } |
| 380 | 435 | |
| 381 | 436 | /** |
| 382 | 437 | * Normalize and validate shared plan-creation payload. |
| @@ -394,32 +449,35 @@ | ||
| 394 | 449 | * @param array $data |
| 395 | 450 | * |
| 396 | 451 | * @return array |
| 397 | 452 | * @throws Exception |
| 453 | + * @since 4.3.7 | |
| 454 | + * @version 1.0.1 | |
| 398 | 455 | */ |
| 399 | 456 | protected function validate_data_plan_payload( array $data ): array { |
| 400 | 457 | $data = wp_parse_args( |
| 401 | 458 | $data, |
| 402 | 459 | array( |
| 403 | - 'name' => '', | |
| 460 | + 'name' => '', // Name of plan and product (if product_id is empty) | |
| 404 | 461 | 'amount' => 0, |
| 405 | 462 | 'currency' => learn_press_get_currency(), |
| 406 | 463 | 'interval' => 'month', |
| 407 | 464 | 'interval_count' => 1, |
| 408 | 465 | 'setup_fee' => 0, |
| 409 | - 'product_id' => '', | |
| 466 | + 'product_id' => '', // if empty, will create product, then create plan with product created | |
| 410 | 467 | 'metadata' => array(), |
| 411 | 468 | ) |
| 412 | 469 | ); |
| 413 | - $data['name'] = sanitize_text_field( wp_unslash( (string) $data['name'] ) ); | |
| 470 | + $data['name'] = LP_Helper::sanitize_params_submitted( $data['name'] ); | |
| 414 | 471 | $data['amount'] = (float) $data['amount']; |
| 415 | - $data['currency'] = strtoupper( sanitize_text_field( wp_unslash( (string) $data['currency'] ) ) ); | |
| 416 | - $data['interval'] = strtolower( sanitize_key( (string) $data['interval'] ) ); | |
| 472 | + $data['currency'] = LP_Helper::sanitize_params_submitted( $data['currency'], 'key' ); | |
| 473 | + $data['interval'] = LP_Helper::sanitize_params_submitted( $data['interval'], 'key' ); | |
| 417 | 474 | $data['interval_count'] = max( 1, absint( $data['interval_count'] ) ); |
| 418 | 475 | $data['setup_fee'] = (float) $data['setup_fee']; |
| 419 | - $data['product_id'] = sanitize_text_field( wp_unslash( (string) $data['product_id'] ) ); | |
| 476 | + $data['product_id'] = LP_Helper::sanitize_params_submitted( $data['product_id'] ); | |
| 420 | 477 | $data['metadata'] = is_array( $data['metadata'] ) ? $data['metadata'] : array(); |
| 421 | - if ( empty( $data['product_id'] ) && empty( $data['name'] ) ) { | |
| 478 | + | |
| 479 | + if ( empty( $data['name'] ) ) { | |
| 422 | 480 | throw new Exception( __( 'Missing subscription plan name.', 'learnpress' ) ); |
| 423 | 481 | } |
| 424 | 482 | |
| 425 | 483 | if ( $data['amount'] <= 0 ) { |
| @@ -432,8 +490,9 @@ | ||
| 432 | 490 | |
| 433 | 491 | if ( empty( $data['currency'] ) ) { |
| 434 | 492 | throw new Exception( __( 'Missing subscription currency.', 'learnpress' ) ); |
| 435 | 493 | } |
| 494 | + | |
| 436 | 495 | $allowed_intervals = array( 'day', 'week', 'month', 'year' ); |
| 437 | 496 | if ( ! in_array( $data['interval'], $allowed_intervals, true ) ) { |
| 438 | 497 | throw new Exception( __( 'Invalid subscription interval.', 'learnpress' ) ); |
| 439 | 498 | } |
| @@ -441,13 +500,10 @@ | ||
| 441 | 500 | return $data; |
| 442 | 501 | } |
| 443 | 502 | |
| 444 | 503 | /** |
| 445 | - * Generic provider plan/price creation flow. | |
| 504 | + * Create plan of Payment provider. | |
| 446 | 505 | * |
| 447 | - * Child gateways should override and return created provider identifiers, | |
| 448 | - * typically a `price_id`/`plan_id` to be used later by `pay_subscription()`. | |
| 449 | - * | |
| 450 | 506 | * @param array $data |
| 451 | 507 | * |
| 452 | 508 | * @return array |
| 453 | 509 | * @throws Exception |
| @@ -452,9 +508,8 @@ | ||
| 452 | 508 | * @return array |
| 453 | 509 | * @throws Exception |
| 454 | 510 | */ |
| 455 | 511 | public function create_plan( array $data ): array { |
| 456 | - | |
| 457 | 512 | throw new Exception( sprintf( __( 'Gateway %s does not support subscription plan creation.', 'learnpress' ), $this->get_id() ) ); |
| 458 | 513 | } |
| 459 | 514 | |
| 460 | 515 | /** |
| @@ -483,9 +538,8 @@ | ||
| 483 | 538 | * @return array |
| 484 | 539 | * @throws Exception |
| 485 | 540 | */ |
| 486 | 541 | public function get_plan( string $plan_id ): array { |
| 487 | - | |
| 488 | 542 | throw new Exception( sprintf( __( 'Gateway %s does not support fetching subscription plan.', 'learnpress' ), $this->get_id() ) ); |
| 489 | 543 | } |
| 490 | 544 | |
| 491 | 545 | /** |
| @@ -490,8 +544,10 @@ | ||
| 490 | 544 | |
| 491 | 545 | /** |
| 492 | 546 | * Update provider plan details by plan id. |
| 493 | 547 | * |
| 548 | + * @uses LP_Gateway_Paypal::update_plan | |
| 549 | + * | |
| 494 | 550 | * @param string $plan_id |
| 495 | 551 | * @param array $data |
| 496 | 552 | * |
| 497 | 553 | * @return array |
| @@ -497,9 +553,8 @@ | ||
| 497 | 553 | * @return array |
| 498 | 554 | * @throws Exception |
| 499 | 555 | */ |
| 500 | 556 | public function update_plan( string $plan_id, array $data ): array { |
| 501 | - | |
| 502 | 557 | throw new Exception( sprintf( __( 'Gateway %s does not support updating subscription plan.', 'learnpress' ), $this->get_id() ) ); |
| 503 | 558 | } |
| 504 | 559 | |
| 505 | 560 | /** |
| @@ -510,11 +565,11 @@ | ||
| 510 | 565 | * @return array |
| 511 | 566 | * @throws Exception |
| 512 | 567 | */ |
| 513 | 568 | public function delete_plan( string $plan_id ): array { |
| 514 | - | |
| 515 | 569 | throw new Exception( sprintf( __( 'Gateway %s does not support deleting subscription plan.', 'learnpress' ), $this->get_id() ) ); |
| 516 | 570 | } |
| 571 | + | |
| 517 | 572 | /** |
| 518 | 573 | * Generic subscription webhook listener. |
| 519 | 574 | * |
| 520 | 575 | * Child gateways should override and orchestrate: |
| @@ -523,12 +578,13 @@ | ||
| 523 | 578 | * @param WP_REST_Request $request |
| 524 | 579 | * |
| 525 | 580 | * @return array |
| 526 | 581 | * @throws Exception |
| 582 | + * @deprecated 4.3.8 Use capture_subscription_webhook instead. | |
| 527 | 583 | */ |
| 528 | - public function listen_webhook_subscription( WP_REST_Request $request ): array { | |
| 584 | + /*public function listen_webhook_subscription( WP_REST_Request $request ): array { | |
| 529 | 585 | throw new Exception( sprintf( __( 'Gateway %s does not support subscription webhook.', 'learnpress' ), $this->get_id() ) ); |
| 530 | - } | |
| 586 | + }*/ | |
| 531 | 587 | |
| 532 | 588 | /** |
| 533 | 589 | * Receive subscription webhook from provider. |
| 534 | 590 | * |
| @@ -554,13 +610,14 @@ | ||
| 554 | 610 | * @param array $webhook_data Generic webhook data extracted from transport layer. |
| 555 | 611 | * |
| 556 | 612 | * @return array|object |
| 557 | 613 | * @throws Exception |
| 614 | + * @deprecated 4.3.8 | |
| 558 | 615 | */ |
| 559 | - public function verify_subscription_webhook( array $webhook_data ) { | |
| 616 | + /*public function verify_subscription_webhook( array $webhook_data ) { | |
| 560 | 617 | |
| 561 | 618 | throw new Exception( sprintf( __( 'Gateway %s does not support subscription webhook verification.', 'learnpress' ), $this->get_id() ) ); |
| 562 | - } | |
| 619 | + }*/ | |
| 563 | 620 | |
| 564 | 621 | /** |
| 565 | 622 | * Build normalized webhook data array from transport-specific REST request. |
| 566 | 623 | * |
| @@ -573,10 +630,11 @@ | ||
| 573 | 630 | * @param array $required_headers |
| 574 | 631 | * @param bool $decode_body |
| 575 | 632 | * |
| 576 | 633 | * @return array |
| 634 | + * @deprecated 4.3.8 | |
| 577 | 635 | */ |
| 578 | - protected function build_webhook_data_from_request( WP_REST_Request $request, array $required_headers = array(), bool $decode_body = true ): array { | |
| 636 | + /*protected function build_webhook_data_from_request( WP_REST_Request $request, array $required_headers = array(), bool $decode_body = true ): array { | |
| 579 | 637 | |
| 580 | 638 | $raw_body = (string) $request->get_body(); |
| 581 | 639 | $headers = array(); |
| 582 | 640 | |
| @@ -594,9 +652,9 @@ | ||
| 594 | 652 | 'raw_body' => $raw_body, |
| 595 | 653 | 'body' => is_array( $body ) ? $body : null, |
| 596 | 654 | 'headers' => $headers, |
| 597 | 655 | ); |
| 598 | - } | |
| 656 | + }*/ | |
| 599 | 657 | |
| 600 | 658 | /** |
| 601 | 659 | * Validate normalized webhook payload contract before provider verification. |
| 602 | 660 | * |
| @@ -608,56 +666,57 @@ | ||
| 608 | 666 | * @param array $required_headers |
| 609 | 667 | * |
| 610 | 668 | * @return void |
| 611 | 669 | * @throws Exception |
| 670 | + * @deprecated 4.3.8 | |
| 612 | 671 | */ |
| 613 | - protected function validate_webhook_data_contract( array $webhook_data, array $required_top_level_keys = array(), array $required_headers = array() ) { | |
| 672 | + // protected function validate_webhook_data_contract( array $webhook_data, array $required_top_level_keys = array(), array $required_headers = array() ) { | |
| 673 | + // | |
| 674 | + // $missing = array(); | |
| 675 | + // | |
| 676 | + // foreach ( $required_top_level_keys as $required_key ) { | |
| 677 | + // $required_key = sanitize_key( (string) $required_key ); | |
| 678 | + // | |
| 679 | + // switch ( $required_key ) { | |
| 680 | + // case 'raw_body': | |
| 681 | + // if ( empty( $webhook_data['raw_body'] ) || ! is_string( $webhook_data['raw_body'] ) ) { | |
| 682 | + // $missing[] = 'raw_body'; | |
| 683 | + // } | |
| 684 | + // break; | |
| 685 | + // case 'body': | |
| 686 | + // if ( empty( $webhook_data['body'] ) || ! is_array( $webhook_data['body'] ) ) { | |
| 687 | + // $missing[] = 'body'; | |
| 688 | + // } | |
| 689 | + // break; | |
| 690 | + // case 'headers': | |
| 691 | + // if ( ! isset( $webhook_data['headers'] ) || ! is_array( $webhook_data['headers'] ) ) { | |
| 692 | + // $missing[] = 'headers'; | |
| 693 | + // } | |
| 694 | + // break; | |
| 695 | + // } | |
| 696 | + // } | |
| 697 | + // | |
| 698 | + // $headers_map = is_array( $webhook_data['headers'] ?? null ) ? $webhook_data['headers'] : array(); | |
| 699 | + // foreach ( $required_headers as $required_header ) { | |
| 700 | + // $required_header = strtolower( sanitize_key( (string) $required_header ) ); | |
| 701 | + // $header_value = sanitize_text_field( (string) ( $headers_map[ $required_header ] ?? '' ) ); | |
| 702 | + // if ( '' === $header_value ) { | |
| 703 | + // $missing[] = 'headers.' . $required_header; | |
| 704 | + // } | |
| 705 | + // } | |
| 706 | + // | |
| 707 | + // if ( ! empty( $missing ) ) { | |
| 708 | + // throw new Exception( | |
| 709 | + // sprintf( | |
| 710 | + // /* translators: %s: comma separated required webhook fields. */ | |
| 711 | + // __( 'Invalid webhook request data: missing %s.', 'learnpress' ), | |
| 712 | + // implode( ', ', array_unique( $missing ) ) | |
| 713 | + // ), | |
| 714 | + // 400 | |
| 715 | + // ); | |
| 716 | + // } | |
| 717 | + // } | |
| 614 | 718 | |
| 615 | - $missing = array(); | |
| 616 | - | |
| 617 | - foreach ( $required_top_level_keys as $required_key ) { | |
| 618 | - $required_key = sanitize_key( (string) $required_key ); | |
| 619 | - | |
| 620 | - switch ( $required_key ) { | |
| 621 | - case 'raw_body': | |
| 622 | - if ( empty( $webhook_data['raw_body'] ) || ! is_string( $webhook_data['raw_body'] ) ) { | |
| 623 | - $missing[] = 'raw_body'; | |
| 624 | - } | |
| 625 | - break; | |
| 626 | - case 'body': | |
| 627 | - if ( empty( $webhook_data['body'] ) || ! is_array( $webhook_data['body'] ) ) { | |
| 628 | - $missing[] = 'body'; | |
| 629 | - } | |
| 630 | - break; | |
| 631 | - case 'headers': | |
| 632 | - if ( ! isset( $webhook_data['headers'] ) || ! is_array( $webhook_data['headers'] ) ) { | |
| 633 | - $missing[] = 'headers'; | |
| 634 | - } | |
| 635 | - break; | |
| 636 | - } | |
| 637 | - } | |
| 638 | - | |
| 639 | - $headers_map = is_array( $webhook_data['headers'] ?? null ) ? $webhook_data['headers'] : array(); | |
| 640 | - foreach ( $required_headers as $required_header ) { | |
| 641 | - $required_header = strtolower( sanitize_key( (string) $required_header ) ); | |
| 642 | - $header_value = sanitize_text_field( (string) ( $headers_map[ $required_header ] ?? '' ) ); | |
| 643 | - if ( '' === $header_value ) { | |
| 644 | - $missing[] = 'headers.' . $required_header; | |
| 645 | - } | |
| 646 | - } | |
| 647 | - | |
| 648 | - if ( ! empty( $missing ) ) { | |
| 649 | - throw new Exception( | |
| 650 | - sprintf( | |
| 651 | - /* translators: %s: comma separated required webhook fields. */ | |
| 652 | - __( 'Invalid webhook request data: missing %s.', 'learnpress' ), | |
| 653 | - implode( ', ', array_unique( $missing ) ) | |
| 654 | - ), | |
| 655 | - 400 | |
| 656 | - ); | |
| 657 | - } | |
| 658 | - } | |
| 659 | - | |
| 660 | 719 | /** |
| 661 | 720 | * Normalize provider webhook event to LP event payload. |
| 662 | 721 | * |
| 663 | 722 | * Child gateways should map provider-specific event types/fields into this |
| @@ -665,10 +724,11 @@ | ||
| 665 | 724 | * |
| 666 | 725 | * @param array|object $provider_event |
| 667 | 726 | * |
| 668 | 727 | * @return array |
| 728 | + * @deprecated 4.3.8 Use normalize_subscription_data instead. | |
| 669 | 729 | */ |
| 670 | - public function normalize_subscription_event( $provider_event ): array { | |
| 730 | + /*public function normalize_subscription_event( $provider_event ): array { | |
| 671 | 731 | $event = array( |
| 672 | 732 | 'event_id' => '', |
| 673 | 733 | 'event_type' => '', |
| 674 | 734 | 'subscription_id' => '', |
| @@ -683,26 +743,24 @@ | ||
| 683 | 743 | 'raw' => $provider_event, |
| 684 | 744 | ); |
| 685 | 745 | |
| 686 | 746 | return (array) apply_filters( 'learn-press/gateway/subscription/event', $event, $provider_event, $this ); |
| 687 | - } | |
| 747 | + }*/ | |
| 688 | 748 | |
| 689 | 749 | /** |
| 690 | - * Normalize provider webhook event to LP event payload. | |
| 750 | + * Define key of system LearnPress for webhook data. | |
| 691 | 751 | * |
| 692 | - * Merge data from provider webhook event to LP event payload. | |
| 693 | - * | |
| 694 | 752 | * @param array $webhook_data [lp_order_id, plan_id, subscription_id, subscription_status] |
| 695 | 753 | * |
| 696 | 754 | * @return void |
| 697 | 755 | */ |
| 698 | - public function normalize_subscription_data( array &$webhook_data = [] ) { | |
| 756 | + final public function normalize_subscription_data( array &$webhook_data = [] ) { | |
| 699 | 757 | $webhook_data = array_merge( |
| 700 | 758 | array( |
| 701 | 759 | 'lp_order_id' => 0, |
| 702 | - 'lp_plan_id' => '', | |
| 703 | - 'lp_subscription_id' => '', | |
| 704 | - 'lp_subscription_status' => '', | |
| 760 | + 'lp_plan_id' => '', // Plan id of payment, not membership plan id. | |
| 761 | + 'lp_subscription_id' => '', // Subscription id of payment plan id. | |
| 762 | + 'lp_subscription_status' => '', // Subscription status of payment plan id. | |
| 705 | 763 | ), |
| 706 | 764 | $webhook_data |
| 707 | 765 | ); |
| 708 | 766 | } |
| @@ -723,9 +781,9 @@ | ||
| 723 | 781 | * @throws Exception |
| 724 | 782 | * @since 4.3.7 |
| 725 | 783 | * @version 1.0.0 |
| 726 | 784 | */ |
| 727 | - public function process_subscription_by_status( | |
| 785 | + final public function process_subscription_by_status( | |
| 728 | 786 | $lp_order, |
| 729 | 787 | string $lp_subscription_status_set_to_handle, |
| 730 | 788 | array $webhook_data = [] |
| 731 | 789 | ) { |
| @@ -733,8 +791,17 @@ | ||
| 733 | 791 | |
| 734 | 792 | switch ( $lp_subscription_status_set_to_handle ) { |
| 735 | 793 | case LP_Subscription_Manager::STATUS_TRIAL: |
| 736 | 794 | // For trial, update LP order to complete, set subscription status to trial |
| 795 | + $this->process_subscription_when_payment_first( $lp_order, LP_Subscription_Manager::STATUS_TRIAL, $webhook_data ); | |
| 796 | + | |
| 797 | + // Set user is using plan trial | |
| 798 | + $order_user_ids = $lp_order->get_users(); | |
| 799 | + $plan_id = get_post_meta( $lp_order->get_id(), self::META_SUBSCRIPTION_PLAN_ID, true ); | |
| 800 | + foreach ( $order_user_ids as $user_id ) { | |
| 801 | + update_user_meta( $user_id, 'user_plan_trial', $plan_id ); | |
| 802 | + } | |
| 803 | + | |
| 737 | 804 | $lp_order->add_note( |
| 738 | 805 | sprintf( |
| 739 | 806 | 'LP Order: %s %s: %s. %s. %s, %s', |
| 740 | 807 | sprintf( |
| @@ -754,9 +821,8 @@ | ||
| 754 | 821 | $webhook_data['lp_plan_id'] |
| 755 | 822 | ) |
| 756 | 823 | ) |
| 757 | 824 | ); |
| 758 | - $this->process_subscription_when_payment_first( $lp_order, LP_Subscription_Manager::STATUS_TRIAL, $webhook_data ); | |
| 759 | 825 | do_action( 'learn-press/subscription/trial', $this, $lp_order, $webhook_data ); |
| 760 | 826 | break; |
| 761 | 827 | case LP_Subscription_Manager::STATUS_ACTIVATED: |
| 762 | 828 | // For payment plan first success, update LP order to complete, set subscription status to activated |
| @@ -888,47 +954,56 @@ | ||
| 888 | 954 | } |
| 889 | 955 | |
| 890 | 956 | /** |
| 891 | 957 | * Process order when subscription payment first. |
| 958 | + * Update status of order parent to completed | |
| 959 | + * Save META_SUBSCRIPTION_STATUS, lp_subscription_amount, lp_subscription_currency | |
| 892 | 960 | * |
| 893 | 961 | * @since 4.3.7 |
| 894 | - * @version 1.0.0 | |
| 962 | + * @version 1.0.1 | |
| 895 | 963 | */ |
| 896 | - public function process_subscription_when_payment_first( | |
| 897 | - LP_Order $order, | |
| 964 | + private function process_subscription_when_payment_first( | |
| 965 | + LP_Order $lp_order, | |
| 898 | 966 | string $lp_subscription_status_set_to_handle, |
| 899 | 967 | $webhook_data |
| 900 | 968 | ) { |
| 901 | 969 | $lp_subscription_amount = $webhook_data['lp_subscription_amount'] ?? 0; |
| 902 | 970 | $lp_subscription_currency = $webhook_data['lp_subscription_currency'] ?? ''; |
| 903 | - $order->update_status( LP_ORDER_COMPLETED ); | |
| 971 | + $lp_order->update_status( LP_ORDER_COMPLETED ); | |
| 904 | 972 | update_post_meta( |
| 905 | - $order->get_id(), | |
| 973 | + $lp_order->get_id(), | |
| 906 | 974 | self::META_SUBSCRIPTION_STATUS, |
| 907 | 975 | $lp_subscription_status_set_to_handle |
| 908 | 976 | ); |
| 909 | 977 | update_post_meta( |
| 910 | - $order->get_id(), | |
| 978 | + $lp_order->get_id(), | |
| 911 | 979 | 'lp_subscription_amount', |
| 912 | 980 | $lp_subscription_amount |
| 913 | 981 | ); |
| 914 | 982 | update_post_meta( |
| 915 | - $order->get_id(), | |
| 983 | + $lp_order->get_id(), | |
| 916 | 984 | 'lp_subscription_currency', |
| 917 | 985 | $lp_subscription_currency |
| 918 | 986 | ); |
| 987 | + update_post_meta( | |
| 988 | + $lp_order->get_id(), | |
| 989 | + self::META_SUBSCRIPTION_DATA_RECEIVER, | |
| 990 | + wp_json_encode( $webhook_data, JSON_UNESCAPED_UNICODE ) | |
| 991 | + ); | |
| 992 | + | |
| 993 | + do_action( 'learn-press/subscription/order/success', $lp_order, $webhook_data ); | |
| 919 | 994 | } |
| 920 | 995 | |
| 921 | 996 | /** |
| 922 | 997 | * Process order when payment recurring success. |
| 998 | + * Create new order child | |
| 999 | + * Save META_SUBSCRIPTION_DATA_RECEIVER, lp_subscription_amount, lp_subscription_currency | |
| 923 | 1000 | * |
| 924 | 1001 | * @throws Exception |
| 925 | 1002 | * @since 4.3.7 |
| 926 | - * @version 1.0.0 | |
| 1003 | + * @version 1.0.1 | |
| 927 | 1004 | */ |
| 928 | - public function process_subscription_when_payment_renew_success( LP_Order $lp_order_parent, $webhook_data ) { | |
| 929 | - error_log( 'renew pay' ); | |
| 930 | - | |
| 1005 | + private function process_subscription_when_payment_renew_success( LP_Order $lp_order_parent, $webhook_data ) { | |
| 931 | 1006 | $lp_subscription_amount = $webhook_data['lp_subscription_amount'] ?? 0; |
| 932 | 1007 | $lp_subscription_currency = $webhook_data['lp_subscription_currency'] ?? ''; |
| 933 | 1008 | |
| 934 | 1009 | // Create new Order child |
| @@ -944,9 +1019,15 @@ | ||
| 944 | 1019 | $order_renew->set_data( 'payment_method', $lp_order_parent->get_data( 'payment_method' ) ); |
| 945 | 1020 | $order_renew->set_data( 'payment_method_title', $lp_order_parent->get_payment_method_title() ); |
| 946 | 1021 | $order_renew->save(); |
| 947 | 1022 | |
| 948 | - error_log( 'renew ' . json_encode( $webhook_data, JSON_UNESCAPED_UNICODE ) ); | |
| 1023 | + //error_log( 'renew ' . json_encode( $webhook_data, JSON_UNESCAPED_UNICODE ) ); | |
| 1024 | + // Add item to order renew | |
| 1025 | + foreach ( $lp_order_parent->get_all_items() as $item ) { | |
| 1026 | + $item['subtotal'] = $lp_subscription_amount; | |
| 1027 | + $item['total'] = $lp_subscription_amount; | |
| 1028 | + $order_renew->add_item( $item ); | |
| 1029 | + } | |
| 949 | 1030 | |
| 950 | 1031 | update_post_meta( |
| 951 | 1032 | $order_renew->get_id(), |
| 952 | 1033 | self::META_SUBSCRIPTION_DATA_RECEIVER, |
| @@ -961,8 +1042,10 @@ | ||
| 961 | 1042 | $order_renew->get_id(), |
| 962 | 1043 | 'lp_subscription_currency', |
| 963 | 1044 | $lp_subscription_currency |
| 964 | 1045 | ); |
| 1046 | + | |
| 1047 | + do_action( 'learn-press/subscription/order/renew-success', $order_renew, $webhook_data ); | |
| 965 | 1048 | } |
| 966 | 1049 | |
| 967 | 1050 | /** |
| 968 | 1051 | * Get provider manage subscription URL for order. |
| @@ -1006,9 +1089,9 @@ | ||
| 1006 | 1089 | * |
| 1007 | 1090 | * @return string |
| 1008 | 1091 | */ |
| 1009 | 1092 | public function get_payment_form() { |
| 1010 | - return ''; | |
| 1093 | + return apply_filters( 'learn_press_gateway_payment_form', '', $this ); | |
| 1011 | 1094 | } |
| 1012 | 1095 | |
| 1013 | 1096 | /** |
| 1014 | 1097 | * Validate required field before submitting fields. |
| @@ -1034,9 +1117,16 @@ | ||
| 1034 | 1117 | |
| 1035 | 1118 | return apply_filters( 'learn_press_get_return_url', $return_url, $order ); |
| 1036 | 1119 | } |
| 1037 | 1120 | |
| 1121 | + /** | |
| 1122 | + * @param string $prop | |
| 1123 | + * | |
| 1124 | + * @deprecated 4.3.9 | |
| 1125 | + */ | |
| 1038 | 1126 | public function __get( $prop ) { |
| 1127 | + _deprecated_function( __METHOD__, '4.3.9' ); | |
| 1128 | + return false; | |
| 1039 | 1129 | switch ( $prop ) { |
| 1040 | 1130 | case 'method_title': |
| 1041 | 1131 | case 'method_description': |
| 1042 | 1132 | case 'id': |
| @@ -1048,27 +1138,23 @@ | ||
| 1048 | 1138 | } |
| 1049 | 1139 | } |
| 1050 | 1140 | |
| 1051 | 1141 | /** |
| 1052 | - * @since 3.0.0 | |
| 1053 | - * | |
| 1054 | - * return bool | |
| 1055 | - * @deprecated 4.2.3.5 | |
| 1142 | + * @return string | |
| 1056 | 1143 | */ |
| 1057 | - public function is_display() { | |
| 1058 | - _deprecated_function( __METHOD__, '4.2.3.5' ); | |
| 1059 | - $display = apply_filters( 'learn-press/payment-method/display', true, $this->id ); | |
| 1060 | - $display = apply_filters( 'learn-press/payment-method-' . $this->id . '/display', $display ); | |
| 1061 | - | |
| 1062 | - // @deprecated | |
| 1063 | - $display = apply_filters( 'learn_press_display_payment_method', $display, $this->id ); | |
| 1064 | - | |
| 1065 | - return $display; | |
| 1144 | + public function __toString() { | |
| 1145 | + return $this->method_title; | |
| 1066 | 1146 | } |
| 1067 | 1147 | |
| 1068 | 1148 | /** |
| 1069 | - * @return string | |
| 1149 | + * Refund payment | |
| 1150 | + * | |
| 1151 | + * | |
| 1152 | + * @since 4.4.0 | |
| 1153 | + * @version 1.0.0 | |
| 1154 | + * @return void | |
| 1155 | + * @throws Exception | |
| 1070 | 1156 | */ |
| 1071 | - public function __toString() { | |
| 1072 | - return $this->method_title; | |
| 1157 | + public function refund( $lp_order, float $amount = 0, string $note = '' ) { | |
| 1158 | + throw new Exception( __( 'This gateway does not support refund.', 'learnpress' ) ); | |
| 1073 | 1159 | } |
| 1074 | 1160 | } |