get_id() ); add_action( 'woocommerce_thankyou', array( __CLASS__, 'render' ), 20, 1 ); } /** * The flat query the signed GET route takes. * * PURE. The pixel route takes a flat query with its own parameter names, * not the nested conversion payload. Keeping the mapping in its own * static method is what lets a test sign it and verify the result against * the platform's own verifier rather than against a copy of the * algorithm. * * @param array $payload A conversion payload from Affiliatant_Payload. * @return array */ public static function params( array $payload ) { $params = array( 'program_id' => isset( $payload['program_id'] ) ? (int) $payload['program_id'] : 0, 'order' => isset( $payload['external_order_id'] ) ? (string) $payload['external_order_id'] : '', 'event_id' => isset( $payload['event_id'] ) ? (string) $payload['event_id'] : '', 'kind' => isset( $payload['kind'] ) ? (string) $payload['kind'] : 'sale', 'amount_minor' => isset( $payload['amount_minor'] ) ? (int) $payload['amount_minor'] : 0, 'tax_minor' => isset( $payload['tax_minor'] ) ? (int) $payload['tax_minor'] : 0, 'shipping_minor' => isset( $payload['shipping_minor'] ) ? (int) $payload['shipping_minor'] : 0, 'currency' => isset( $payload['currency'] ) ? (string) $payload['currency'] : '', 'channel' => 'woocommerce', 'occurred_at' => isset( $payload['occurred_at'] ) ? (string) $payload['occurred_at'] : '', ); if ( isset( $payload['store_id'] ) ) { $params['store_id'] = (int) $payload['store_id']; } if ( ! empty( $payload['click_id'] ) ) { $params['aftid'] = (string) $payload['click_id']; } if ( ! empty( $payload['coupon_code'] ) ) { $params['coupon'] = (string) $payload['coupon_code']; } if ( ! empty( $payload['external_customer_id'] ) ) { $params['customer'] = (string) $payload['external_customer_id']; } if ( ! empty( $payload['is_test'] ) ) { $params['test'] = 1; } return $params; } /** * Print the pixel on the receipt page. * * Prints nothing when it cannot be signed, which is the correct answer: * an unsigned pixel is refused at the other end, and a broken image on a * receipt page is a support ticket. * * @param int $order_id Order id. * @return void */ public static function render( $order_id ) { try { if ( ! Affiliatant_Settings::active() || (int) Affiliatant_Settings::get( 'pixel' ) !== 1 ) { return; } $prefix = (string) Affiliatant_Settings::get( 'key_prefix' ); $secret = (string) Affiliatant_Settings::get( 'signing_secret' ); $endpoint = (string) Affiliatant_Settings::get( 'pixel_url' ); if ( '' === $prefix || '' === $secret || '' === $endpoint ) { return; } $order = wc_get_order( $order_id ); if ( ! is_a( $order, 'WC_Order' ) || 'shop_order' !== $order->get_type() ) { return; } $context = Affiliatant_Order::context( $order ); $payload = Affiliatant_Payload::conversion( Affiliatant_Order::snapshot( $order ), array() !== $context ? $context : Affiliatant_Subscriptions::context_for_renewal( $order ), array( 'program_id' => (int) Affiliatant_Settings::get( 'program_id' ), 'store_ref' => (string) Affiliatant_Settings::get( 'store_ref' ), 'kind' => Affiliatant_Subscriptions::kind_for_order( $order ), 'is_test' => Affiliatant_Settings::test_mode(), ) ); $url = AffiliatantClient::signedUrl( $endpoint, $prefix, $secret, self::params( $payload ) ); echo ''; } catch ( \Throwable $e ) { // Never out of the receipt page. Affiliatant_Sender::log( 'The receipt pixel could not be rendered: ' . $e->getMessage() ); } } }