$value ) { $txn->update_meta( $key, $value ); } } /** * @inheritdoc */ public function do_conversion_checks() { if ( isset( $_GET['trans_num'] ) ) { return true; } if ( isset( $_GET['action'] ) && $_GET['action'] === 'gifts' && isset( $_GET['txn'] ) ) { $txn = new MeprTransaction( (int) $_GET['txn'] ); if ( $txn->id ) { $_REQUEST['trans_num'] = $txn->trans_num; return true; } } return false; } /** * @inheritdoc */ public function is_active() { return defined( 'MEPR_VERSION' ) && version_compare( MEPR_VERSION, '1.3.43', '>' ) && apply_filters( 'monsterinsights_ppc_tracking_track_conversion_memberpress', true ); } /** * @inheritdoc */ public function try_to_get_order() { if ( empty( $_REQUEST['trans_num'] ) ) { return false; } if ( empty( $_REQUEST['subscr_id'] ) ) { $txn = new MeprTransaction(); $data = MeprTransaction::get_one_by_trans_num( sanitize_key( $_REQUEST['trans_num'] ) ); $txn->load_data( $data ); if ( ! $txn->id || ! $txn->product_id ) { return false; } $this->order = $txn; $this->order_id = 'charge_' . $txn->id; return true; } $sub = MeprSubscription::get_one_by_subscr_id( sanitize_key( $_REQUEST['subscr_id'] ) ); if ( $sub === false || ! $sub->id || ! $sub->product_id ) { return false; } $this->order = $sub; $this->order_id = 'sub_' . $sub->id; return true; } /** * @inheritDoc */ public function get_order_total() { if ( empty( $this->order ) ) { return null; } if ( $this->order instanceof MeprSubscription ) { return $this->order->trial ? $this->order->trial_total : $this->order->total; } else { return $this->order->total; } } /** * @inheritDoc */ public function get_order_currency() { $mepr_options = MeprOptions::fetch(); return $mepr_options->currency_code; } /** * @inheritDoc */ public function get_order_number() { return empty( $this->order_id ) ? null : $this->order_id; } /** * @inheritDoc */ public function already_tracked_frontend( $provider_id ) { if ( empty( $this->order ) ) { return true; } $tracked = $this->order->get_meta( "_monsterinsights_ppc_tracking_conversion_tracked_{$provider_id}", true ); return ! empty( $tracked ) && 'yes' === $tracked; } /** * @inheritDoc */ public function mark_order_tracked_frontend( $provider_id ) { if ( empty( $this->order ) ) { return; } $this->order->update_meta( "_monsterinsights_ppc_tracking_conversion_tracked_{$provider_id}", 'yes' ); } /** * Send a server event when the checkout page is viewed. * * @param MeprProduct $product The product for which the checkout is being viewed. * * @return void * @throws Exception */ public function server_event_begin_checkout( $product ) { $data = $this->get_checkout_data(); $user_data = [ 'user_ip' => $this->get_user_ip(), 'user_agent' => $this->get_user_agent(), ]; $data = array_merge( $data, $user_data ); $data = array_merge( $data, $this->get_server_user_data() ); $this->send_event_to_ad_providers( 'begin_checkout', $data, $this ); } /** * Track a server purchase event specific to MemberPress. * * @param MeprTransaction $txn The transaction object. * * @return void */ public function server_event_purchase( $txn ) { if ( ! is_object( $txn ) ) { return; } // Don't report transactions that are not payments. if ( ! empty( $txn->txn_type ) && MeprTransaction::$payment_str !== $txn->txn_type ) { return; } $skip_renewals = apply_filters( 'monsterinsights_ppc_tracking_skip_renewals', true ); if ( $skip_renewals && $txn->is_rebill() ) { return; } $user = $txn->user(); // Build purchase event data from order. $data = [ 'order_id' => $txn->id, 'num_items' => 1, 'currency' => $this->get_currency(), 'total' => $txn->total, 'products' => [], 'user_id' => $user->ID, 'user_ip' => $txn->get_meta( '_monsterinsights_ppc_tracking_user_ip', true ), 'email' => $user->user_email, 'zip' => get_user_meta( $user->ID, 'mepr-address-zip', true ), 'city' => get_user_meta( $user->ID, 'mepr-address-city', true ), 'state' => get_user_meta( $user->ID, 'mepr-address-state', true ), 'country' => get_user_meta( $user->ID, 'mepr-address-country', true ), 'user_agent' => $txn->get_meta( '_monsterinsights_ppc_tracking_user_agent', true ), 'first_name' => $user->first_name, 'last_name' => $user->last_name, ]; if ( ! empty( $txn->coupon_id ) ) { $data['coupon'] = get_the_title( $txn->coupon_id ); } $product = new MeprProduct( $txn->product_id ); $data['products'][] = [ 'id' => $txn->product_id, 'quantity' => 1, 'name' => $product->post_title, 'discount' => $product->price - $txn->amount, 'price' => $txn->amount, ]; $this->send_event_to_ad_providers( 'purchase', $data, $this ); } /** * Get checkout data specific to MemberPress. * * @return array */ public function get_checkout_data() { if ( ! class_exists( 'MeprProduct' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return []; } $current_post = MeprUtils::get_current_post(); $product = $this->get_product( $current_post->ID ); // Let's check if the current user already has a subscription. $user = MeprUtils::get_currentuserinfo(); if ( false !== $user ) { $enabled_prd_ids = $user->get_enabled_product_ids( $product->ID ); if ( ! empty( $enabled_prd_ids ) && ! $product->simultaneous_subscriptions ) { // User already has a subscription for this product and the checkout form will be hidden don't track this. return []; } } $data = [ 'num_items' => 1, 'currency' => $this->get_currency(), 'total' => $product->price, 'products' => [ [ 'id' => $product->ID, 'quantity' => 1, 'name' => $product->post_title, 'price' => $product->price, 'discount' => 0, 'categories' => [], ], ], ]; return $data; } /** * Get the user data for a logged-in user, if available. * * @return array * @throws Exception */ public function get_server_user_data() { $data = []; if ( is_user_logged_in() ) { $user = new MeprUser( get_current_user_id() ); $data['user_id'] = get_current_user_id(); $data['email'] = $user->user_email; $data['city'] = get_user_meta( $user->ID, 'mepr-address-city', true ); $data['state'] = get_user_meta( $user->ID, 'mepr-address-state', true ); $data['country'] = get_user_meta( $user->ID, 'mepr-address-country', true ); $data['zip'] = get_user_meta( $user->ID, 'mepr-address-zip', true ); $data['first_name'] = $user->first_name; $data['last_name'] = $user->last_name; } return $data; } /** * @inheritdoc */ public function get_name() { return 'MemberPress'; } /** * @inheritDoc */ public function get_product( $product_id ) { return new MeprProduct( $product_id ); } /** * @inheritDoc */ public function get_currency() { $mepr_options = MeprOptions::fetch(); return ! empty( $mepr_options->currency_code ) ? $mepr_options->currency_code : 'USD'; } /** * @inheritDoc */ function get_order_customer_info( $order_id ) { if ( empty( $this->order ) && !$this->try_to_get_order() ) { return []; } // Order was loaded, or we were able to load just above. $user = $this->order->user(); $email = $user->user_email; if ( empty( $email ) ) { return []; } $data = [ 'email' => $email, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'address' => [ 'street' => $user->address('one'), 'city' => $user->address('city'), 'region' => $user->address('state'), 'postal_code' => $user->address('zip'), 'country' => $user->address('country'), ] ]; return $data; } }