extra_information ); ?>
id . '_date_of_birth_day' ] ) ) { wc_add_notice( __( 'Birthday is a required field', 'afterpay' ), 'error' ); return false; } // Check if birthday month is set. if ( ! isset( $_POST[ $this->id . '_date_of_birth_month' ] ) ) { wc_add_notice( __( 'Birthday is a required field', 'afterpay' ), 'error' ); return false; } // Check if birthday year is set. if ( ! isset( $_POST[ $this->id . '_date_of_birth_year' ] ) ) { wc_add_notice( __( 'Birthday is a required field', 'afterpay' ), 'error' ); return false; } // Check if bankaccount is set, if this option is enabled. if ( $this->show_bankaccount && ! isset( $_POST[ $this->id . '_bankaccount' ] ) ) { wc_add_notice( __( 'Bankaccount is a required field', 'afterpay' ), 'error' ); return false; } // Check if phonenumber is set, if this option is enabled. if ( 'yes' === $this->show_phone && ! isset( $_POST[ $this->id . '_phone' ] ) ) { wc_add_notice( __( 'Phone number is a required field', 'afterpay' ), 'error' ); return false; } // Check if terms and conditions are set, if this option is enabled. if ( 'yes' === $this->show_termsandconditions && ! isset( $_POST[ $this->id . '_terms' ] ) ) { wc_add_notice( __( 'Please accept the AfterPay terms.', 'afterpay' ), 'error' ); return false; } return true; } /** * Process the payment and return the result * * @access public * @param int $order_id Order ID. * @return array **/ public function process_payment( $order_id ) { global $woocommerce; $_tax = new WC_Tax(); $order = wc_get_order( $order_id ); require_once __DIR__ . '/vendor/autoload.php'; // Create AfterPay object. $afterpay = new \Afterpay\Afterpay(); // Get values from afterpay form on checkout page. // Set form fields per payment option. // Collect the dob. $afterpay_pno_day = isset( $_POST[ $this->id . '_date_of_birth_day' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_date_of_birth_day' ] ) ) ) : ''; if ( '' === $afterpay_pno_day && 'B2B' !== $this->order_type ) { wc_add_notice( __( 'Please enter a birthday' ), 'error' ); } $afterpay_pno_month = isset( $_POST[ $this->id . '_date_of_birth_month' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_date_of_birth_month' ] ) ) ) : ''; $afterpay_pno_year = isset( $_POST[ $this->id . '_date_of_birth_year' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_date_of_birth_year' ] ) ) ) : ''; if ( 'B2B' === $this->order_type ) { $afterpay_pno = '1970-01-01T00:00:00'; } else { $afterpay_pno = $afterpay_pno_year . '-' . $afterpay_pno_month . '-' . $afterpay_pno_day . 'T00:00:00'; } $afterpay_bankacount = isset( $_POST[ $this->id . '_bankaccount' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_bankaccount' ] ) ) ) : ''; $afterpay_phone = isset( $_POST[ $this->id . '_phone' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_phone' ] ) ) ) : $order->get_billing_phone(); if ( 'B2B' === $this->order_type ) { $afterpay_cocnumber = isset( $_POST[ $this->id . '_cocnumber' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_cocnumber' ] ) ) ) : ''; $afterpay_companyname = isset( $_POST[ $this->id . '_companyname' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_companyname' ] ) ) ) : ''; } // Split address into House number and House extension for NL customers. $afterpay_billing_address_1 = $order->get_billing_address_1(); $afterpay_billing_address_2 = $order->get_billing_address_2(); $afterpay_billing_address = trim( $afterpay_billing_address_1 . ' ' . $afterpay_billing_address_2 ); $splitted_address = $this->split_afterpay_address( $afterpay_billing_address ); $afterpay_billing_address = $splitted_address[0]; $afterpay_billing_house_number = $splitted_address[1]; $afterpay_billing_house_extension = $splitted_address[2]; $afterpay_shipping_address_1 = $order->get_shipping_address_1(); $afterpay_shipping_address_2 = $order->get_shipping_address_2(); $afterpay_shipping_address = trim( $afterpay_shipping_address_1 . ' ' . $afterpay_shipping_address_2 ); $splitted_address = $this->split_afterpay_address( $afterpay_shipping_address ); $afterpay_shipping_address = $splitted_address[0]; $afterpay_shipping_house_number = $splitted_address[1]; $afterpay_shipping_house_extension = $splitted_address[2]; // If special field is being used for housenumber then use that field. if ( '' !== $this->settings['use_custom_housenumber_field'] ) { $afterpay_billing_house_number = isset( $_POST[ 'billing_' . $this->settings['use_custom_housenumber_field'] ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ 'billing_' . $this->settings['use_custom_housenumber_field'] ] ) ) ) : $afterpay_billing_house_number; $afterpay_shipping_house_number = isset( $_POST[ 'shipping_' . $this->settings['use_custom_housenumber_field'] ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ 'shipping_' . $this->settings['use_custom_housenumber_field'] ] ) ) ) : $afterpay_shipping_house_number; } // If special field is being used for housenumber addition then use that field. if ( '' !== $this->settings['use_custom_housenumber_addition_field'] ) { $afterpay_billing_house_extension = isset( $_POST[ 'billing_' . $this->settings['use_custom_housenumber_addition_field'] ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ 'billing_' . $this->settings['use_custom_housenumber_addition_field'] ] ) ) ) : $afterpay_billing_house_extension; $afterpay_shipping_house_extension = isset( $_POST[ 'shipping_' . $this->settings['use_custom_housenumber_addition_field'] ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ 'shipping_' . $this->settings['use_custom_housenumber_addition_field'] ] ) ) ) : $afterpay_shipping_house_extension; } // Store afterpay specific form values in order as post meta. update_post_meta( $order_id, 'afterpay_pno', $afterpay_pno ); // Get connection mode. $afterpay_mode = $this->get_connection_mode(); $authorisation['merchantid'] = $this->settings['merchantid']; $authorisation['portfolioid'] = $this->settings['portfolioid']; $authorisation['password'] = $this->settings['password']; // Create the order. // Cart Contents. if ( count( $order->get_items() ) > 0 ) { foreach ( $order->get_items() as $item ) { // Get product to retrieve sku or product id. $_product = $item->get_product(); // Get SKU or product id. if ( $_product->get_sku() ) { $sku = $_product->get_sku(); } else { $sku = $_product->get_id(); } $item_tax_category = $this->get_afterpay_tax_class( $order->get_line_total( $item, false ), $order->get_line_tax( $item ) ); // apply_filters to item price so we can filter this if needed. $afterpay_item_price_including_tax = $order->get_item_total( $item, true ); $item_price = apply_filters( 'afterpay_item_price_including_tax', $afterpay_item_price_including_tax ); $item_price = round( $item_price * 100, 0 ); $afterpay->create_order_line( $sku, $item['name'], $item['qty'], $item_price, $item_tax_category ); } } // Set the shipping data. if ( $order->get_shipping_total() > 0 ) { // We manually calculate the shipping tax percentage here. $calculated_shipping_tax_percentage = ( $order->get_shipping_tax() / $order->get_shipping_total() ) * 100; $calculated_shipping_tax_decimal = ( $order->get_shipping_tax() / $order->get_shipping_total() ) + 1; $shipping_tax_rate = $this->get_afterpay_tax_class( $order->get_total_shipping(), $order->get_shipping_tax() ); // apply_filters to Shipping so we can filter this if needed. $afterpay_shipping_price_including_tax = $order->get_shipping_total() * $calculated_shipping_tax_decimal; $shipping_price = apply_filters( 'afterpay_shipping_price_including_tax', $afterpay_shipping_price_including_tax ); $shipping_sku = __( 'Shipping', 'afterpay' ); $shipping_description = __( 'Shipping on order', 'afterpay' ); $shipping_price = round( $shipping_price * 100, 0 ); $afterpay->create_order_line( $shipping_sku, $shipping_description, 1, $shipping_price, $shipping_tax_rate ); } $fees = $woocommerce->cart->get_fees(); if ( count( $fees ) > 0 ) { foreach ( $fees as $fee ) { $fee_sku = __( 'Service Fee', 'afterpay' ); $fee_description = $fee->name; $fee_price = round( ( $fee->amount + $fee->tax ) * 100 ); $afterpay->create_order_line( $fee_sku, $fee_description, 1, $fee_price, 1 ); } } // Check value for gender. $afterpay_gender = ''; $payment_methods_with_gender = array( 'afterpay_openinvoice', 'afterpay_directdebit', 'afterpay_belgium', ); if ( in_array( $this->id, $payment_methods_with_gender, true ) ) { $afterpay_gender = isset( $_POST[ $this->id . '_gender' ] ) ? wc_clean( sanitize_text_field( wp_unslash( $_POST[ $this->id . '_gender' ] ) ) ) : ''; } $aporder['billtoaddress']['city'] = utf8_decode( $order->get_billing_city() ); $aporder['billtoaddress']['housenumber'] = utf8_decode( $afterpay_billing_house_number ); $aporder['billtoaddress']['housenumberaddition'] = utf8_decode( $afterpay_billing_house_extension ); $aporder['billtoaddress']['isocountrycode'] = $order->get_billing_country(); $aporder['billtoaddress']['postalcode'] = utf8_decode( $order->get_billing_postcode() ); $aporder['billtoaddress']['referenceperson']['dob'] = $afterpay_pno; $aporder['billtoaddress']['referenceperson']['email'] = $order->get_billing_email(); $aporder['billtoaddress']['referenceperson']['gender'] = $afterpay_gender; $aporder['billtoaddress']['referenceperson']['initials'] = utf8_decode( substr( $order->get_billing_first_name(), 0, 1 ) ); $aporder['billtoaddress']['referenceperson']['isolanguage'] = 'NL'; $aporder['billtoaddress']['referenceperson']['lastname'] = utf8_decode( $order->get_billing_last_name() ); $aporder['billtoaddress']['referenceperson']['phonenumber'] = $afterpay_phone; $aporder['billtoaddress']['streetname'] = utf8_decode( $afterpay_billing_address ); // Shipping address. if ( $order->get_shipping_method() === '' ) { // Use billing address if Shipping is disabled in Woocommerce. $aporder['shiptoaddress'] = $aporder['billtoaddress']; } else { $aporder['shiptoaddress']['city'] = utf8_decode( $order->get_shipping_city() ); $aporder['shiptoaddress']['housenumber'] = utf8_decode( $afterpay_shipping_house_number ); $aporder['shiptoaddress']['housenumberaddition'] = utf8_decode( $afterpay_shipping_house_extension ); $aporder['shiptoaddress']['isocountrycode'] = $order->get_shipping_country(); $aporder['shiptoaddress']['postalcode'] = utf8_decode( $order->get_shipping_postcode() ); $aporder['shiptoaddress']['referenceperson']['dob'] = $afterpay_pno; $aporder['shiptoaddress']['referenceperson']['email'] = $order->get_billing_email(); $aporder['shiptoaddress']['referenceperson']['gender'] = $afterpay_gender; $aporder['shiptoaddress']['referenceperson']['initials'] = utf8_decode( substr( $order->get_shipping_first_name(), 0, 1 ) ); $aporder['shiptoaddress']['referenceperson']['isolanguage'] = 'NL'; $aporder['shiptoaddress']['referenceperson']['lastname'] = utf8_decode( $order->get_shipping_last_name() ); $aporder['shiptoaddress']['referenceperson']['phonenumber'] = $afterpay_phone; $aporder['shiptoaddress']['streetname'] = utf8_decode( $afterpay_shipping_address ); } // Start compatibility with SendCloud. $shipping_items = $order->get_items( 'shipping' ); $order_shipping = reset( $shipping_items ); if ( is_object( $order_shipping ) ) { $shipping_method = $order_shipping->get_method_id(); if ( strpos( $shipping_method, 'service_point_shipping_method' ) !== false && $order->meta_exists( 'sendcloudshipping_service_point_meta' ) ) { $sendcloud_meta_data = $order->get_meta( 'sendcloudshipping_service_point_meta' ); if ( isset( $sendcloud_meta_data['extra'] ) ) { $sendcloud_shipping_data = explode( '|', $sendcloud_meta_data['extra'] ); $sendcloud_shipping_name = isset( $sendcloud_shipping_data[0] ) ? $sendcloud_shipping_data[0] : ''; $aporder['shiptoaddress']['referenceperson']['initials'] = 'S'; $aporder['shiptoaddress']['referenceperson']['lastname'] = utf8_decode( $sendcloud_shipping_name ); $sendcloud_address = $this->split_afterpay_address( $sendcloud_shipping_data[1] ); $sendcloud_shipping_street = isset( $sendcloud_address[0] ) ? $sendcloud_address[0] : ''; $aporder['shiptoaddress']['streetname'] = utf8_decode( $sendcloud_shipping_street ); $sendcloud_shipping_house_number = isset( $sendcloud_address[1] ) ? $sendcloud_address[1] : ''; $aporder['shiptoaddress']['housenumber'] = $sendcloud_shipping_house_number; $sendcloud_shipping_house_extension = isset( $sendcloud_address[2] ) ? $sendcloud_address[2] : ''; $aporder['shiptoaddress']['housenumberaddition'] = utf8_decode( $afterpay_shipping_house_extension ); $sendcloud_shipping_pcandcity = explode( ' ', $sendcloud_shipping_data['2'] ); $sendcloud_shipping_postalcode = isset( $sendcloud_shipping_pcandcity[0] ) ? $sendcloud_shipping_pcandcity[0] : ''; $aporder['shiptoaddress']['postalcode'] = utf8_decode( $sendcloud_shipping_postalcode ); $sendcloud_shipping_city = isset( $sendcloud_shipping_pcandcity[1] ) ? $sendcloud_shipping_pcandcity[1] : ''; $aporder['shiptoaddress']['city'] = utf8_decode( $sendcloud_shipping_city ); } } } // End compatibility with SendCloud. // Start compatibility with PostNL. // Check if the order is sent with postnl. if ( $order->meta_exists( '_postnl_delivery_options' ) ) { // Get the PostNL meta data. $postnl_meta_data = $order->get_meta( '_postnl_delivery_options' ); // Check if the pickup points of PostNL are used. if ( isset( $postnl_meta_data['location'] ) ) { $aporder['shiptoaddress']['referenceperson']['initials'] = 'P'; $location_name = 'POSTNL ' . $postnl_meta_data['location']; $aporder['shiptoaddress']['referenceperson']['lastname'] = utf8_decode( $location_name ); $postnl_shipping_street = isset( $postnl_meta_data['street'] ) ? $postnl_meta_data['street'] : ''; $aporder['shiptoaddress']['streetname'] = utf8_decode( $postnl_shipping_street ); $postnl_shipping_house_number = isset( $postnl_meta_data['number'] ) ? $postnl_meta_data['number'] : ''; $aporder['shiptoaddress']['housenumber'] = $postnl_shipping_house_number; $postnl_shipping_postalcode = isset( $postnl_meta_data['postal_code'] ) ? $postnl_meta_data['postal_code'] : ''; $aporder['shiptoaddress']['postalcode'] = utf8_decode( $postnl_shipping_postalcode ); $postnl_shipping_city = isset( $postnl_meta_data['city'] ) ? $postnl_meta_data['city'] : ''; $aporder['shiptoaddress']['city'] = utf8_decode( $postnl_shipping_city ); } } // End compatibility with PostNL. // Start compatibility with MyParcel. MyParcel uses different fields for shipping address data. if ( $order->meta_exists( '_shipping_street_name' ) ) { if ( '' !== $order->get_meta( '_shipping_street_name' ) ) { $aporder['shiptoaddress']['streetname'] = $order->get_meta( '_shipping_street_name' ); } if ( $order->meta_exists( '_shipping_house_number' ) ) { if ( '' !== $order->get_meta( '_shipping_house_number' ) ) { $aporder['shiptoaddress']['housenumber'] = $order->get_meta( '_shipping_house_number' ); } } if ( $order->meta_exists( '_shipping_house_number_suffix' ) ) { if ( '' !== $order->get_meta( '_shipping_house_number_suffix' ) ) { $aporder['shiptoaddress']['housenumberaddition'] = $order->get_meta( '_shipping_house_number_suffix' ); } } } // If PostNL Pickup points are used, use location from pickup point as address data. if ( $order->meta_exists( '_myparcel_delivery_options' ) ) { // Get the MyParcel meta data. $myparcel_meta_data = $order->get_meta( '_myparcel_delivery_options' ); // Check if the pickup points of MyParcel are used. if ( isset( $myparcel_meta_data['location'] ) ) { $aporder['shiptoaddress']['referenceperson']['initials'] = 'P'; $location_name = 'AFHAAL ' . $myparcel_meta_data['location']; $aporder['shiptoaddress']['referenceperson']['lastname'] = utf8_decode( $location_name ); $myparcel_shipping_street = isset( $myparcel_meta_data['street'] ) ? $myparcel_meta_data['street'] : ''; $aporder['shiptoaddress']['streetname'] = utf8_decode( $myparcel_shipping_street ); $myparcel_shipping_house_number = isset( $myparcel_meta_data['number'] ) ? $myparcel_meta_data['number'] : ''; $aporder['shiptoaddress']['housenumber'] = $myparcel_shipping_house_number; $myparcel_shipping_postalcode = isset( $myparcel_meta_data['postal_code'] ) ? $myparcel_meta_data['postal_code'] : ''; $aporder['shiptoaddress']['postalcode'] = utf8_decode( $myparcel_shipping_postalcode ); $myparcel_shipping_city = isset( $myparcel_meta_data['city'] ) ? $myparcel_meta_data['city'] : ''; $aporder['shiptoaddress']['city'] = utf8_decode( $myparcel_shipping_city ); } } // End compatibility with MyParcel. // Check if housenumber field is filled for shipping, else use housenumber of billing. if ( '' === $aporder['shiptoaddress']['housenumber'] ) { $aporder['shiptoaddress']['housenumber'] = $aporder['billtoaddress']['housenumber']; $aporder['shiptoaddress']['housenumberaddition'] = $aporder['billtoaddress']['housenumberaddition']; } $aporder['ordernumber'] = filter_var( $order->get_order_number(), FILTER_SANITIZE_NUMBER_INT ); $aporder['bankaccountnumber'] = $afterpay_bankacount; $aporder['currency'] = 'EUR'; $aporder['ipaddress'] = $this->get_afterpay_client_ip(); if ( 'B2B' === $this->order_type ) { $aporder['company']['cocnumber'] = $afterpay_cocnumber; $aporder['company']['companyname'] = $afterpay_companyname; $aporder['person']['dob'] = $afterpay_pno; $aporder['person']['emailaddress'] = $order->get_billing_email(); $aporder['person']['initials'] = utf8_decode( substr( $order->get_billing_first_name(), 0, 1 ) ); $aporder['person']['isolanguage'] = 'NL'; $aporder['person']['lastname'] = utf8_decode( $order->get_billing_last_name() ); $aporder['person']['phonenumber1'] = $afterpay_phone; $aporder['billtoaddress']['isolanguage'] = 'NL'; $aporder['shiptoaddress']['isolanguage'] = 'NL'; } try { // Transmit all the specified data, from the steps above, to afterpay. $afterpay->set_order( $aporder, $this->order_type ); $afterpay->do_request( $authorisation, $afterpay_mode ); $this->send_afterpay_debug_mail( $afterpay ); // Retreive response. if ( isset( $afterpay->order_result->return->statusCode ) ) { switch ( $afterpay->order_result->return->statusCode ) { case 'A': // If capturing is enabled, and way of capture is set. // to automatically after authorization, then capture the full order. if ( isset( $this->settings['captures'] ) && 'yes' === $this->settings['captures'] && isset( $this->settings['captures_way'] ) && 'auto_after_authorization' === $this->settings['captures_way'] ) { $order->add_order_note( __( 'AfterPay payment completed.', 'afterpay' ) ); // Capture payment. $this->capture_afterpay_payment( null, $order ); } if ( isset( $this->settings['captures'] ) && 'yes' === $this->settings['captures'] && isset( $this->settings['captures_way'] ) && 'auto_after_authorization' !== $this->settings['captures_way'] ) { // Add note that the order is not captured yet. $order->add_order_note( __( 'AfterPay capture needed, since the Capture mode was set to(Based on Woocommerce Status) when the order was placed.', 'afterpay' ) ); } // Payment complete. $order->payment_complete(); // Remove cart. $woocommerce->cart->empty_cart(); // Return thank you redirect. return array( 'result' => 'success', 'redirect' => $this->get_return_url( $order ), ); case 'P': $order->add_order_note( __( 'AfterPay payment pending.', 'afterpay' ) ); // Payment complete. $order->update_status( 'on-hold', __( 'Awaiting AfterPay payment', 'afterpay' ) ); // Remove cart. $woocommerce->cart->empty_cart(); // Return thank you redirect. return array( 'result' => 'success', 'redirect' => $afterpay->order_result->return->extrafields->valueField, ); case 'W': // Order is denied, store it in a database. $order->add_order_note( esc_html__( 'AfterPay payment denied.', 'afterpay' ) ); $order->add_order_note( esc_html__( $afterpay->order_result->return->messages->message, 'afterpay' ) ); wc_add_notice( esc_html__( $afterpay->order_result->return->messages->description, 'afterpay' ), 'error' ); // Cancel order to make new order possible. $order->cancel_order(); return; } } else { // Check for validation errors. if ( 2 === $afterpay->order_result->return->resultId ) { // Unknown response, store it in a database. $order->add_order_note( esc_html__( 'There is a problem with submitting this order to AfterPay.', 'afterpay' ) ); $validationmsg = esc_html__( 'There is a problem with submitting this order to AfterPay, please check the following issues: ', 'afterpay' ); $validationmsg .= '' . esc_html__( 'Thank you for your order, you will receive a payment invoice for your order from AfterPay.', 'afterpay' ) . '
'; } /** * Function to send AfterPay debug email using the AfterPay Library debuglog function * * @access public * @param resource $afterpay The afterpay object. * @return void **/ public function send_afterpay_debug_mail( $afterpay ) { if ( '' !== $this->debug_mail ) { wp_mail( $this->debug_mail, 'DEBUG MAIL WOOCOMMERCE AFTERPAY', $afterpay->client->getDebugLog() ); } } /** * Function to get the the IP address of the client * * @access public * @return string $ipaddress **/ public function get_afterpay_client_ip() { if ( array_key_exists( 'HTTP_X_FORWARDED_FOR', $_SERVER ) && isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { $ipaddress = explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ); return trim( $ipaddress[0] ); } elseif ( array_key_exists( 'REMOTE_ADDR', $_SERVER ) && isset( $_SERVER['REMOTE_ADDR'] ) ) { return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); } elseif ( array_key_exists( 'HTTP_CLIENT_IP', $_SERVER ) && isset( $_SERVER['HTTP_CLIENT_IP'] ) ) { return sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) ); } return ''; } /** * Function to get the AfterPay NL Tax Category based on full amount and tax amount * * @access public * @param float $total_amount Total amount. * @param float $tax_amount Tax amount. * @return int $item_tax_category **/ public function get_afterpay_tax_class( $total_amount, $tax_amount ) { // We manually calculate the tax percentage here. if ( $tax_amount > 0 ) { // Calculate tax percentage. $item_tax_percentage = number_format( ( $tax_amount / $total_amount ) * 100, 2, '.', '' ); } else { $item_tax_percentage = 0.00; } if ( $item_tax_percentage > 10 ) { $item_tax_category = 1; } elseif ( $item_tax_percentage > 0 ) { $item_tax_category = 2; } else { $item_tax_category = 3; } return $item_tax_category; } /** * Function to spit the address in array containing address, house number and house number extension * * @access public * @param string $address Address in one string. * @param bool $attach_single_extension Set to yes if an extension of one character should be attached to the housenumber. * @return array $address **/ public function split_afterpay_address( $address, $attach_single_extension = false ) { // Get everything up to the first number with a regex. $has_match = preg_match( '/^[^0-9]*/', $address, $match ); // If no matching is possible, return the supplied string as the street. if ( ! $has_match ) { return array( $address, '', '' ); } // Remove the street from the address. $address = str_replace( $match[0], '', $address ); $street = trim( $match[0] ); // Nothing left to split, return. if ( strlen( 0 === $address ) ) { return array( $street, '', '' ); } // Split the address to an array. $address_array = preg_split( '/([\s,--,\/,\\,|,,,+,_]+)|(?<=\d)(?=[a-z])|(?<=[a-z])(?=\d)/', $address ); // Shift the first element off the array, that is the house number. $housenumber = array_shift( $address_array ); // If the array is empty now, there is no extension. if ( count( $address_array ) === 0 ) { return array( $street, $housenumber, '' ); } // Join together the remaining pieces as the extension. $extension = implode( ' ', $address_array ); // If single character extension needs to be attached to the housenumber. if ( $attach_single_extension && strlen( $extension ) === 1 ) { $housenumber = $housenumber . $extension; $extension = ''; } return array( $street, $housenumber, $extension ); } /** * Process refunds. * WooCommerce 2.2 or later. * * @param int $order_id Woocommerce order ID. * @param float $amount Amount of the refund. * @param string $reason Optional reason for the refund. * @return bool|WP_Error */ public function process_refund( $order_id, $amount = null, $reason = '' ) { try { global $woocommerce; $order = wc_get_order( $order_id ); // Load AfterPay Library. require_once __DIR__ . '/vendor/autoload.php'; // Create AfterPay object. $afterpay = new \Afterpay\Afterpay(); // Set order management action to partial refund. $afterpay->set_ordermanagement( 'refund_partial' ); // Check the refund id. if ( metadata_exists( 'post', $order_id, '_afterpay_refund_id' ) ) { $refund_id = get_post_meta( $order_id, '_afterpay_refund_id', true ) + 1; } else { $refund_id = 1; } // Set up the additional information. $aporder['invoicenumber'] = filter_var( $order->get_order_number(), FILTER_SANITIZE_NUMBER_INT ); $aporder['ordernumber'] = filter_var( $order->get_order_number(), FILTER_SANITIZE_NUMBER_INT ); $aporder['creditinvoicenumber'] = 'REFUND-' . filter_var( $order->get_order_number(), FILTER_SANITIZE_NUMBER_INT ) . '-' . $refund_id; // Set the country. $aporder['billtoaddress']['isocountrycode'] = $this->afterpay_country; // Set refund line. $sku = 'REFUND'; $name = 'REFUND'; // If a reason has been set, use it in the name/description. if ( '' !== $reason ) { $name = $name . ': ' . $reason; } $qty = 1; $price = round( $amount * 100, 0 ) * -1; $tax_category = 1; // 1 = high, 2 = low, 3, zero, 4 no tax $afterpay->create_order_line( $sku, $name, $qty, $price, $tax_category ); // Create the order object for order management (OM). $afterpay->set_order( $aporder, 'OM' ); // Get connection mode. $afterpay_mode = $this->get_connection_mode(); // Set up the AfterPay credentials and sent the request. $authorisation['merchantid'] = $this->settings['merchantid']; $authorisation['portfolioid'] = $this->settings['portfolioid']; $authorisation['password'] = $this->settings['password']; $afterpay->do_request( $authorisation, $afterpay_mode ); $this->send_afterpay_debug_mail( $afterpay ); if ( 'A' === $afterpay->order_result->return->statusCode ) { if ( 1 === $refund_id ) { add_post_meta( $order_id, '_afterpay_refund_id', 1, true ); } else { update_post_meta( $order_id, '_afterpay_refund_id', $refund_id ); } return true; } else { return new WP_Error( 'afterpay_refund_error', $afterpay->order_result->return->messages[0]->description ); } } catch ( Exception $e ) { return new WP_Error( 'afterpay_refund_error', $e->getMessage() ); } return false; } /** * Calculate vat amount based on totalamount and vat percentage * * @param int $price_incl_vat Price including taxes. * @param int $vat_percentage Tax percentage. * * @return float $vat_amount */ public function calculate_afterpay_vat_amount( $price_incl_vat, $vat_percentage ) { $vat_amount = 0; $price_excl_vat = ( $price_incl_vat / ( $vat_percentage + 100 ) ) * 100; $vat_amount = $price_incl_vat - $price_excl_vat; return round( $vat_amount, 2 ); } /** * Returns all the possible order statuses * * @return array The possible order statuses */ public function get_all_possible_order_statuses() { $temporary_statuses = wc_get_order_statuses(); $result_statuses = array(); foreach ( $temporary_statuses as $key => $value ) { $key = str_replace( 'wc-', '', $key ); $result_statuses[ $key ] = $value; } return $result_statuses; } /** * Validates an IBAN bankaccount * * @param string $bank_code The BIC bank code. * @param string $bank_account The IBAN bank account. * @return bool */ public function validate_afterpay_bankaccount( $bank_code, $bank_account ) { try { // Load the AfterPay Library. require_once __DIR__ . '/vendor/autoload.php'; // Create the AfterPay Object. $afterpay_bankvalidation = new \Afterpay\Afterpay(); $afterpay_bankvalidation->setRest(); $afterpay_bankvalidation->set_ordermanagement( 'validate_bankaccount' ); // Set up the additional bank information. $bankdetails['bankCode'] = $bank_code; $bankdetails['bankAccount'] = $bank_account; // Create the order object for order management (OM). $afterpay_bankvalidation->set_order( $bankdetails, 'OM' ); $authorisation['apiKey'] = $this->settings['api_key']; // Get connection mode. $afterpay_mode = $this->get_connection_mode(); // Sent the request to do the bank validation. $afterpay_bankvalidation->do_request( $authorisation, $afterpay_mode ); // If there was a return and it was false, set the message as notice and return false. if ( isset( $afterpay_bankvalidation->order_result->return ) && ! isset( $afterpay_bankvalidation->order_result->return->isValid ) ) { wc_add_notice( __( 'There is a problem with your bank data:', 'afterpay' ), 'error' ); if ( is_object( $afterpay_bankvalidation->order_result->return ) ) { foreach ( $afterpay_bankvalidation->order_result->return as $message ) { if ( isset( $message->fieldReference ) && isset( $message->message ) ) { wc_add_notice( __( $message->fieldReference . ': ' . $message->message, 'afterpay' ), 'error' ); } } } return false; } } catch ( Exception $e ) { // Something went wrong, print the message. // translators: %1$s: error message, %2$s: error code. wc_add_notice( sprintf( __( '%1$s (Error code: %2$s)', 'afterpay' ), $e->getMessage(), $e->getCode() ), 'error' ); return false; } // All went well, bankaccount was valid return true. return true; } /** * Returns the connection mode * * @return string The connection modus (live, test, sandbox). */ public function get_connection_mode() { $afterpay_mode = ''; // Test mode or Live mode. if ( 'yes' === $this->testmode ) { $afterpay_mode = 'test'; } elseif ( 'sandbox' === $this->testmode ) { $afterpay_mode = 'sandbox'; } else { $afterpay_mode = 'live'; } return $afterpay_mode; } }