Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
wp-content
/
plugins
/
swedbank-pay-checkout
/
includes
:
class-wc-swedbank-subscriptions.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace SwedbankPay\Checkout\WooCommerce; defined( 'ABSPATH' ) || exit; use WC_Payment_Gateway; use WC_Subscription; use WC_Order; use Exception; use WC_Gateway_Swedbank_Pay_Checkout; class WC_Swedbank_Subscriptions { const PAYMENT_ID = 'payex_checkout'; public function __construct() { // Add payment token when subscription was created add_action( 'woocommerce_payment_complete', __CLASS__ . '::add_subscription_card_id', 10, 1 ); add_action( 'woocommerce_payment_complete_order_status_on-hold', __CLASS__ . '::add_subscription_card_id', 10, 1 ); // Update failing payment method add_action( 'woocommerce_subscription_failing_payment_method_updated_' . self::PAYMENT_ID, __CLASS__ . '::update_failing_payment_method', 10, 1 ); // Don't transfer customer meta to resubscribe orders add_action( 'wcs_resubscribe_order_created', __CLASS__ . '::delete_resubscribe_meta', 10 ); // Allow store managers to manually set card id as the payment method on a subscription add_filter( 'woocommerce_subscription_payment_meta', __CLASS__ . '::add_subscription_payment_meta', 10, 2 ); // Customize credit cards in admin add_action( 'woocommerce_subscription_payment_meta_input_' . self::PAYMENT_ID . '_swedbankpay_meta_token_id', __CLASS__ . '::payment_meta_input', 10, 4 ); // Validate the payment meta data add_action( 'woocommerce_subscription_validate_payment_meta', __CLASS__ . '::validate_subscription_payment_meta', 10, 3 ); // Save payment method meta data for the Subscription add_action( 'wcs_save_other_payment_meta', __CLASS__ . '::save_subscription_payment_meta', 10, 4 ); // Charge the payment when a subscription payment is due add_action( 'woocommerce_scheduled_subscription_payment_' . self::PAYMENT_ID, __CLASS__ . '::scheduled_subscription_payment', 10, 2 ); // Display the credit card used for a subscription in the "My Subscriptions" table add_filter( 'woocommerce_my_subscriptions_payment_method', __CLASS__ . '::maybe_render_subscription_payment_method', 10, 2 ); // Lock "Save card" if needs add_filter( 'woocommerce_payment_gateway_save_new_payment_method_option_html', __CLASS__ . '::save_new_payment_method_option_html', 10, 2 ); add_action( 'woocommerce_get_customer_payment_tokens', array( $this, 'filter_tokens' ), 3, 10 ); } /** * Add Card ID when Subscription was created * * @param $order_id */ public static function add_subscription_card_id( $order_id ) { if ( ! function_exists( 'wcs_get_subscriptions_for_order' ) ) { return; } $order = wc_get_order( $order_id ); $subscriptions = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'parent' ) ); foreach ( $subscriptions as $subscription ) { /** @var WC_Subscription $subscription */ // Add payment meta $paymentId = $order->get_meta( '_payex_payment_id' ); $paymentOrderId = $order->get_meta( '_payex_paymentorder_id' ); /** @var \WC_Subscription $subscription */ if ( ! empty( $paymentId ) ) { $subscription->update_meta_data( '_payex_payment_id', $paymentId ); } if ( ! empty( $paymentOrderId ) ) { $subscription->update_meta_data( '_payex_paymentorder_id', $paymentOrderId ); } // Add payment token $tokens = $order->get_payment_tokens(); if ( count( $tokens ) > 0 ) { foreach ( $tokens as $token_id ) { $token = new WC_Payment_Token_Swedbank_Pay( $token_id ); if ( self::PAYMENT_ID !== $token->get_gateway_id() ) { continue; } $subscription->add_payment_token( $token ); $subscription->add_order_note( sprintf( __( 'Card: %s', 'swedbank-pay-woocommerce-checkout' ), strip_tags( $token->get_display_name() ) ) ); break; } } $subscription->save_meta_data(); $subscription->save(); } } /** * Update the card meta for a subscription after using this payment method * to complete a payment to make up for an automatic renewal payment which previously failed. * * @access public * * @param WC_Subscription $subscription The subscription for which the failing payment method relates. * @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment). * * @return void */ public static function update_failing_payment_method( $subscription, $renewal_order ) { // Delete tokens //$subscription->delete_meta_data( '_payment_tokens' ); //$subscription->save(); } /** * Don't transfer customer meta to resubscribe orders. * * @access public * * @param WC_Order $resubscribe_order The order created for the customer to resubscribe to the old expired/cancelled subscription * * @return void */ public static function delete_resubscribe_meta( $resubscribe_order ) { // Delete tokens $resubscribe_order->delete_meta_data( '_payment_tokens' ); $resubscribe_order->save(); } /** * Include the payment meta data required to process automatic recurring payments so that store managers can * manually set up automatic recurring payments for a customer via the Edit Subscription screen in Subscriptions v2.0+. * * @param array $payment_meta associative array of meta data required for automatic payments * @param WC_Subscription $subscription An instance of a subscription object * * @return array */ public static function add_subscription_payment_meta( $payment_meta, $subscription ) { $payment_meta[ self::PAYMENT_ID ] = array( 'swedbankpay_meta' => array( 'token_id' => array( 'value' => implode( ',', $subscription->get_payment_tokens() ), 'label' => __( 'Card Token ID', 'swedbank-pay-woocommerce-checkout' ), ), ), ); return $payment_meta; } /** * @param WC_Subscription $subscription * @param $field_id * @param $field_value * @param $meta_data */ public static function payment_meta_input( $subscription, $field_id, $field_value, $meta_data ) { $tokens = \WC_Payment_Tokens::get_tokens( array( 'gateway_id' => self::PAYMENT_ID, 'user_id' => $subscription->get_user_id() ) ); echo '<select class="short" name="' . esc_attr( $field_id ) . '" id="' . esc_attr( $field_id ) . '">'; echo '<option value="">' . __( 'Please select', 'swedbank-pay-woocommerce-checkout' ) . '</option>'; foreach ($tokens as $token): /** @var WC_Payment_Token_Swedbank_Pay $token */ $selected = $field_value == $token->get_id() ? ' selected ' : ''; echo '<option value="' . esc_attr( $token->get_id() ) . '" ' . $selected . ' >' . esc_html( $token->get_meta( 'masked_pan' ) . '(' . $token->get_expiry_month() . '/' . substr( $token->get_expiry_year(), 2 ) . ')' ) . '</option>' ?> <?php endforeach; echo '</select>'; } /** * Validate the payment meta data required to process automatic recurring payments so that store managers can * manually set up automatic recurring payments for a customer via the Edit Subscription screen in Subscriptions 2.0+. * * @param string $payment_method_id The ID of the payment method to validate * @param array $payment_meta associative array of meta data required for automatic payments * @param WC_Subscription $subscription * * @throws Exception */ public static function validate_subscription_payment_meta( $payment_method_id, $payment_meta, $subscription ) { if ( $payment_method_id === self::PAYMENT_ID ) { if ( empty( $payment_meta['swedbankpay_meta']['token_id']['value'] ) ) { throw new Exception( 'A "Card Token ID" value is required.' ); } $tokens = explode( ',', $payment_meta['swedbankpay_meta']['token_id']['value'] ); foreach ( $tokens as $token_id ) { $token = new WC_Payment_Token_Swedbank_Pay( $token_id ); if ( ! $token->get_id() ) { throw new Exception( 'This "Card Token ID" value not found.' ); } if ( $token->get_gateway_id() !== self::PAYMENT_ID ) { throw new Exception( 'This "Card Token ID" value should related to Swedbank Pay.' ); } if ( $token->get_user_id() !== $subscription->get_user_id() ) { throw new Exception( 'Access denied for this "Card Token ID" value.' ); } } } } /** * Save payment method meta data for the Subscription * * @param WC_Subscription $subscription * @param string $meta_table * @param string $meta_key * @param string $meta_value */ public static function save_subscription_payment_meta( $subscription, $meta_table, $meta_key, $meta_value ) { if ( $subscription->get_payment_method() !== self::PAYMENT_ID ) { return; } if ( 'swedbankpay_meta' === $meta_table && 'token_id' === $meta_key ) { // Delete tokens $subscription->delete_meta_data( '_payment_tokens' ); $subscription->save(); // Add tokens $tokens = explode( ',', $meta_value ); foreach ( $tokens as $token_id ) { $token = new WC_Payment_Token_Swedbank_Pay( $token_id ); if ( $token->get_id() ) { $subscription->add_payment_token( $token ); } } } } /** * When a subscription payment is due. * * @param $amount_to_charge * @param WC_Order $renewal_order */ public static function scheduled_subscription_payment( $amount_to_charge, $renewal_order ) { $user_agent = $renewal_order->get_customer_user_agent(); if ( empty( $user_agent ) ) { $renewal_order->set_customer_user_agent( 'WooCommerce/' . WC()->version ); $renewal_order->save(); } try { $tokens = $renewal_order->get_payment_tokens(); foreach ( $tokens as $token_id ) { $token = new WC_Payment_Token_Swedbank_Pay( $token_id ); if ( $token->get_gateway_id() !== self::PAYMENT_ID ) { continue; } if ( ! $token->get_id() ) { throw new Exception( 'Invalid Token Id' ); } $gateway = self::get_payment_gateway(); $gateway->process_recurring_payment( $renewal_order, $token->get_recurrence_token() ); break; } } catch ( \Exception $e ) { $renewal_order->update_status( 'failed' ); $renewal_order->add_order_note( sprintf( /* translators: 1: amount 2: error */ __( 'Failed to charge "%1$s". %2$s.', 'woocommerce' ), wc_price( $amount_to_charge ), $e->getMessage() ) ); } } /** * Render the payment method used for a subscription in the "My Subscriptions" table * * @param string $payment_method_to_display the default payment method text to display * @param WC_Subscription $subscription the subscription details * * @return string the subscription payment method */ public static function maybe_render_subscription_payment_method( $payment_method_to_display, $subscription ) { if ( self::PAYMENT_ID !== $subscription->get_payment_method() || ! $subscription->get_user_id() ) { return $payment_method_to_display; } $tokens = $subscription->get_payment_tokens(); foreach ( $tokens as $token_id ) { try { $token = new WC_Payment_Token_Swedbank_Pay( $token_id ); } catch ( \Exception $e ) { continue; } if ( $token->get_gateway_id() !== self::PAYMENT_ID ) { continue; } return sprintf( /* translators: 1: pan 2: month 3: year */ __( 'Via %1$s card ending in %2$s/%3$s', 'swedbank-pay-woocommerce-checkout' ), $token->get_masked_pan(), $token->get_expiry_month(), $token->get_expiry_year() ); } return $payment_method_to_display; } /** * Modify "Save to account" to lock that if needs. * * @param string $html * @param WC_Payment_Gateway $gateway * * @return string */ public static function save_new_payment_method_option_html( $html, $gateway ) { if ( self::PAYMENT_ID !== $gateway->id ) { return $html; } // Lock "Save to Account" for Recurring Payments / Payment Change if ( self::wcs_cart_has_subscription() || self::wcs_is_payment_change() ) { // Load XML libxml_use_internal_errors( true ); $doc = new \DOMDocument(); $status = @$doc->loadXML( $html ); if ( false !== $status ) { $item = $doc->getElementsByTagName('input')->item( 0 ); $item->setAttribute( 'checked','checked' ); $item->setAttribute( 'readonly','readonly' ); $item->setAttribute( 'onclick', 'return false;'); $html = $doc->saveHTML($doc->documentElement); } } return $html; } /** * Filter tokens. * * @param $tokens * @param $customer_id * @param $gateway_id * * @return array|mixed */ public function filter_tokens( $tokens, $customer_id, $gateway_id ) { if ( self::PAYMENT_ID !== $gateway_id ) { return $tokens; } $result = []; foreach ( $tokens as $token ) { /** @var \WC_Payment_Token $token */ if ( self::PAYMENT_ID !== $token->get_gateway_id() ) { $result[] = $token; continue; } /** @var WC_Payment_Token_Swedbank_Pay $token */ $recurrence_token = $token->get_recurrence_token(); if ( self::wcs_cart_has_subscription() && empty( $recurrence_token ) ) { // Don't show token continue; } $unscheduled_token = $token->get_unscheduled_token(); if ( self::wcs_is_payment_change() && empty( $unscheduled_token ) ) { // Don't show token continue; } $result[] = $token; } return $result; } /** * Get Payment Method Instance. * * @return WC_Gateway_Swedbank_Pay_Checkout * @throws Exception */ private static function get_payment_gateway() { $gateways = WC()->payment_gateways()->payment_gateways(); if ( isset( $gateways[ self::PAYMENT_ID ] ) ) { return $gateways[ self::PAYMENT_ID ]; } throw new \Exception( 'The checkout payment gateway is unavailable.' ); } /** * Check is Cart have Subscription Products. * * @return bool */ private static function wcs_cart_has_subscription() { if ( ! class_exists( 'WC_Subscriptions_Product' ) ) { return false; } // Check is Recurring Payment $cart = WC()->cart->get_cart(); foreach ( $cart as $item ) { if ( is_object( $item['data'] ) && \WC_Subscriptions_Product::is_subscription( $item['data'] ) ) { return true; } } return false; } /** * WC Subscriptions: Is Payment Change. * * @return bool */ private static function wcs_is_payment_change() { return class_exists( '\\WC_Subscriptions_Change_Payment_Gateway', false ) && \WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment; } } new WC_Swedbank_Subscriptions();