| 1 |
<?php |
| 2 |
|
| 3 |
namespace MakeCommerce\Payment\Gateway; |
| 4 |
|
| 5 |
/** |
| 6 |
* Simplecheckout payment method |
| 7 |
* handles admin settings and overrules default woocommerce checkout |
| 8 |
* |
| 9 |
* @since 3.0.0 |
| 10 |
*/ |
| 11 |
|
| 12 |
class Simplecheckout extends \MakeCommerce\Payment\Gateway { |
| 13 |
|
| 14 |
public $id = 'makecommerce_sc'; |
| 15 |
public $method_title = "Simple Checkout (MC)"; |
| 16 |
|
| 17 |
/** |
| 18 |
* Set gateway specific hooks/filters |
| 19 |
* |
| 20 |
* @since 3.0.0 |
| 21 |
*/ |
| 22 |
public function set_gateway_hooks() { |
| 23 |
|
| 24 |
add_action( 'woocommerce_before_checkout_form', array( $this, 'take_over_checkout' ), 10, 1 ); |
| 25 |
add_action( 'query_vars', array( $this, 'return_triggers' ) ); |
| 26 |
add_action( 'template_redirect', array( $this, 'return_trigger_check' ) ); |
| 27 |
add_action( 'woocommerce_before_cart', array( $this, 'cart_scripts' ) ); |
| 28 |
} |
| 29 |
|
| 30 |
/** |
| 31 |
* Variables that trigger return check |
| 32 |
* |
| 33 |
* @since 3.0.0 |
| 34 |
*/ |
| 35 |
public function return_triggers( $vars ) { |
| 36 |
|
| 37 |
$vars[] = 'mc_cart_to_order'; |
| 38 |
$vars[] = 'mc_calculate_shipment'; |
| 39 |
$vars[] = 'mc_cart_update'; |
| 40 |
|
| 41 |
$vars[] = 'mc_cart_id'; |
| 42 |
$vars[] = 'mc_nonce'; |
| 43 |
$vars[] = 'lang1'; |
| 44 |
|
| 45 |
return $vars; |
| 46 |
} |
| 47 |
|
| 48 |
/** |
| 49 |
* Process return from payment, also handles cart updates among other things |
| 50 |
* |
| 51 |
* @since 3.0.0 |
| 52 |
*/ |
| 53 |
public function return_trigger_check() { |
| 54 |
|
| 55 |
if (intval(get_query_var('mc_cart_to_order')) === 1) { |
| 56 |
$this->cart_to_order(); |
| 57 |
} |
| 58 |
|
| 59 |
//calculate shipment cost |
| 60 |
if (intval(get_query_var('mc_calculate_shipment')) === 1) { |
| 61 |
$this->calculate_shipment_cost(); |
| 62 |
} |
| 63 |
|
| 64 |
//cart update |
| 65 |
if ( intval( get_query_var( 'mc_cart_update' ) ) > 0 ) { |
| 66 |
$this->update_cart(); |
| 67 |
} |
| 68 |
} |
| 69 |
|
| 70 |
/** |
| 71 |
* Returns cart |
| 72 |
* |
| 73 |
* @since 3.0.0 |
| 74 |
*/ |
| 75 |
private function get_cart( $cart_info ) { |
| 76 |
|
| 77 |
global $wpdb; |
| 78 |
|
| 79 |
$cart = $wpdb->get_row( " |
| 80 |
SELECT |
| 81 |
`content`, |
| 82 |
`order_id` |
| 83 |
FROM |
| 84 |
`" . $wpdb->prefix . MAKECOMMERCE_SCO_TABLENAME . "` |
| 85 |
WHERE |
| 86 |
`cart_id` = '".$cart_info->cartId."' |
| 87 |
" ); |
| 88 |
|
| 89 |
if ( !$cart ) { |
| 90 |
error_log( 'no such cart' ); |
| 91 |
echo json_encode( array( 'code' => -1 ) ); |
| 92 |
|
| 93 |
exit; |
| 94 |
} |
| 95 |
|
| 96 |
return $cart; |
| 97 |
} |
| 98 |
|
| 99 |
/** |
| 100 |
* Check for MITM manipulations |
| 101 |
* |
| 102 |
* @since 3.0.0 |
| 103 |
*/ |
| 104 |
private function check_mitm( $cart_info ) { |
| 105 |
|
| 106 |
global $wpdb; |
| 107 |
|
| 108 |
$tmp_order_sco_data = $wpdb->get_row( " |
| 109 |
SELECT |
| 110 |
`content`, |
| 111 |
`order_id` |
| 112 |
FROM |
| 113 |
`" . $wpdb->prefix . MAKECOMMERCE_SCO_TABLENAME . "` |
| 114 |
WHERE |
| 115 |
`cart_id` = '".$cart_info->cartId . "_provided_sco_data' |
| 116 |
" ); |
| 117 |
|
| 118 |
if ( !$tmp_order_sco_data ) { |
| 119 |
|
| 120 |
error_log( 'Missing sco provided data for cart' ); |
| 121 |
echo json_encode( array( 'code' => -1 ) ); |
| 122 |
|
| 123 |
exit; |
| 124 |
} else { |
| 125 |
|
| 126 |
$matching_shipment_method_found = false; |
| 127 |
$provided_cart_data = json_decode( $tmp_order_sco_data->content ); |
| 128 |
|
| 129 |
if ( !empty( $provided_cart_data->shipmentMethods ) ) { |
| 130 |
foreach ( $provided_cart_data->shipmentMethods as $p_shipment_method ) { |
| 131 |
|
| 132 |
//check to see if the selected shipment has a matching cart id and amount. |
| 133 |
if ( $p_shipment_method->methodId == $cart_info->shipmentMethod->methodId && $p_shipment_method->amount == $cart_info->shipmentMethod->amount ) { |
| 134 |
$matching_shipment_method_found = true; |
| 135 |
} |
| 136 |
} |
| 137 |
} else { //no shipment methods. Most likely a virtual product |
| 138 |
$matching_shipment_method_found = true; |
| 139 |
} |
| 140 |
|
| 141 |
//response option does not match with provided sco data options. Either something went terribly wrong or someone manipulated with the data. Cancel payment |
| 142 |
if ( !$matching_shipment_method_found ) { |
| 143 |
|
| 144 |
error_log( 'Cart shipping method with matching price not found in sco_provided_data' ); |
| 145 |
header( "HTTP/1.1 400 Bad Request" ); |
| 146 |
|
| 147 |
exit; |
| 148 |
} |
| 149 |
} |
| 150 |
|
| 151 |
//cleanup sco mitm table. Delete all rows older than 24 hours |
| 152 |
$wpdb->query( " |
| 153 |
DELETE |
| 154 |
FROM |
| 155 |
`" . $wpdb->prefix . MAKECOMMERCE_SCO_TABLENAME . "` |
| 156 |
WHERE |
| 157 |
`modified` < '" . (time() - 86400) . "' |
| 158 |
"); |
| 159 |
} |
| 160 |
|
| 161 |
/** |
| 162 |
* Turns cart into order |
| 163 |
* |
| 164 |
* @since 3.0.0 |
| 165 |
*/ |
| 166 |
private function cart_to_order() { |
| 167 |
|
| 168 |
$cart_info = json_decode( file_get_contents( 'php://input' ) ); |
| 169 |
|
| 170 |
//change language if it is set. |
| 171 |
if ( isset( $_GET["lang1"] ) ) { |
| 172 |
\MakeCommerce\i18n::switch_language( $_GET["lang1"] ); |
| 173 |
} |
| 174 |
|
| 175 |
$this->tmp_order = $this->get_cart( $cart_info ); |
| 176 |
|
| 177 |
//check for mitm manipulations |
| 178 |
$this->check_mitm( $cart_info ); |
| 179 |
|
| 180 |
$free_shipping = false; |
| 181 |
|
| 182 |
$tmp_cart = new \WC_Cart(); |
| 183 |
|
| 184 |
$this->tmp_order->content = json_decode($this->tmp_order->content); |
| 185 |
|
| 186 |
$content = !empty( $this->tmp_order->content->order ) ? $this->tmp_order->content->order : $this->tmp_order->content; |
| 187 |
|
| 188 |
//add all items to cart |
| 189 |
foreach ( $content as $item_row ) { |
| 190 |
$tmp_cart->add_to_cart( $item_row->id, $item_row->qty ); |
| 191 |
} |
| 192 |
|
| 193 |
//order already created. |
| 194 |
if ( $this->tmp_order->order_id ) { |
| 195 |
|
| 196 |
$this->order = new \WC_Order( $this->tmp_order->order_id ); |
| 197 |
} else { //create new order |
| 198 |
|
| 199 |
$this->order = wc_create_order(); |
| 200 |
|
| 201 |
$this->add_products_to_order( $content ); |
| 202 |
|
| 203 |
$this->order->calculate_totals(); |
| 204 |
|
| 205 |
$free_shipping = $this->free_shipping(); |
| 206 |
} |
| 207 |
|
| 208 |
$this->order->set_payment_method( new WooCommerce() ); |
| 209 |
|
| 210 |
$billing_address = array( |
| 211 |
'first_name' => $cart_info->customer->firstname, |
| 212 |
'last_name' => $cart_info->customer->lastname, |
| 213 |
'email' => $cart_info->customer->email, |
| 214 |
'phone' => $cart_info->customer->phone, |
| 215 |
'company' => '' |
| 216 |
); |
| 217 |
|
| 218 |
if ( !empty( $cart_info->invoiceAddress ) ) { |
| 219 |
$billing_address = $this->set_billing_address( $billing_address, $cart_info->invoiceAddress ); |
| 220 |
} |
| 221 |
|
| 222 |
$shipment_address = array(); |
| 223 |
if ( !empty( $cart_info->shipmentAddress ) ) { |
| 224 |
|
| 225 |
$shipment = $cart_info->shipmentAddress; |
| 226 |
$shipment_address = $this->set_shipment_address( $shipment ); |
| 227 |
} |
| 228 |
|
| 229 |
$this->order->set_address( $billing_address, 'billing' ); |
| 230 |
|
| 231 |
if ( empty( $shipment_address ) ) { |
| 232 |
$this->order->set_address( $billing_address, 'shipping' ); |
| 233 |
} else { |
| 234 |
$this->order->set_address( $shipment_address, 'shipping' ); |
| 235 |
} |
| 236 |
|
| 237 |
$shipment_method = $this->get_shipment_method( $cart_info, $shipment ); |
| 238 |
|
| 239 |
$this->order->remove_order_items('shipping'); |
| 240 |
|
| 241 |
if ( $shipment_method ) { |
| 242 |
|
| 243 |
$package = $tmp_cart->get_shipping_packages(); |
| 244 |
|
| 245 |
if ( !empty( $package ) ) { |
| 246 |
$package = $package[0]; |
| 247 |
} |
| 248 |
|
| 249 |
$price_int = $shipment_method->get_rates_for_package( $package ); |
| 250 |
$price_int = \MakeCommerce\Payment::get_rate_without_taxes( $shipment_method->id.':'.$shipment_method->instance_id, $price_int ); |
| 251 |
$price = !empty( $cart_info->shipmentMethod->amount ) ? ( double )$cart_info->shipmentMethod->amount : 0; |
| 252 |
|
| 253 |
if ( $free_shipping ) { |
| 254 |
$price = $price_int = 0; |
| 255 |
} |
| 256 |
|
| 257 |
$rate = new \WC_Shipping_Rate( |
| 258 |
$shipment_method->id.':'.$shipment_method->instance_id, |
| 259 |
!empty( $shipment_method->name_ext ) ? $shipment_method->name_ext : $shipment_method->title, |
| 260 |
$price_int, |
| 261 |
array(), |
| 262 |
$shipment_method->id.':'.$shipment_method->instance_id |
| 263 |
); |
| 264 |
|
| 265 |
if ( class_exists( '\WC_Order_Item_Shipping' ) ) { |
| 266 |
|
| 267 |
$item = new \WC_Order_Item_Shipping(); |
| 268 |
$item->set_order_id( $this->order->get_id() ); |
| 269 |
$item->set_shipping_rate( $rate ); |
| 270 |
$shipping_id = $item->save(); |
| 271 |
} else { |
| 272 |
$this->order->add_shipping( $rate ); |
| 273 |
} |
| 274 |
|
| 275 |
if ( !empty( $shipment_method->type ) && $shipment_method->type === 'apt' ) { |
| 276 |
|
| 277 |
$machine = \MakeCommerce\Shipping::mk_get_machine( strtolower( $shipment_method->carrier ), $shipment->destinationId ); |
| 278 |
if ( $machine ) { |
| 279 |
|
| 280 |
update_post_meta( $this->order->get_id(), '_shipping_first_name', get_post_meta( $this->order->get_id(), '_billing_first_name', true ) ); |
| 281 |
update_post_meta( $this->order->get_id(), '_shipping_last_name', get_post_meta( $this->order->get_id(), '_billing_last_name', true ) ); |
| 282 |
update_post_meta( $this->order->get_id(), '_shipping_address_1', sanitize_text_field( $machine['name'] ) ); |
| 283 |
update_post_meta( $this->order->get_id(), '_shipping_address_2', sanitize_text_field( $machine['address'] ) ); |
| 284 |
update_post_meta( $this->order->get_id(), '_shipping_city', sanitize_text_field( $machine['city'] ) ); |
| 285 |
update_post_meta( $this->order->get_id(), '_shipping_postcode', '' ); |
| 286 |
update_post_meta( $this->order->get_id(), '_parcel_machine', strtolower( $shipment_method->carrier ).'||'.$shipment->destinationId ); |
| 287 |
} |
| 288 |
} |
| 289 |
} |
| 290 |
|
| 291 |
update_post_meta( $this->order->get_id(), '_makecommerce_sc_cart_id', $cart_info->cartId ); |
| 292 |
|
| 293 |
$this->order->calculate_totals(); |
| 294 |
|
| 295 |
if ( !empty( $this->tmp_order->content->discount ) ) { |
| 296 |
$this->order->set_discount_total( $this->tmp_order->content->discount ); |
| 297 |
} |
| 298 |
|
| 299 |
if ( !empty( $this->tmp_order->content->discount_tax ) ) { |
| 300 |
$this->order->set_discount_tax( $this->tmp_order->content->discount_tax ); |
| 301 |
} |
| 302 |
|
| 303 |
$this->order->set_total( $this->order->get_total() - ( $this->order->get_discount_total() + $this->order->get_discount_tax() ) ); |
| 304 |
$this->order->save(); |
| 305 |
|
| 306 |
global $wpdb; |
| 307 |
$wpdb->update( $wpdb->prefix . MAKECOMMERCE_SCO_TABLENAME, array( 'status' => 1, 'order_id' => $this->order->get_id(), 'modified' => time() ), array( 'cart_id' => $cart_info->cartId ) ); |
| 308 |
|
| 309 |
header( 'Content-type: application/json' ); |
| 310 |
echo $this->create_json_response( $cart_info->cartId, ( string )$this->order->get_order_number() ); |
| 311 |
|
| 312 |
exit; |
| 313 |
} |
| 314 |
|
| 315 |
/** |
| 316 |
* Returns shipment method |
| 317 |
* |
| 318 |
* @since 3.0.0 |
| 319 |
*/ |
| 320 |
private function get_shipment_method( $cart_info, $shipment ) { |
| 321 |
|
| 322 |
if ( !empty( $cart_info->shipmentMethod ) ) { |
| 323 |
|
| 324 |
$shipment_details = $cart_info->shipmentMethod; |
| 325 |
$zones = \WC_Shipping_Zones::get_zones(); |
| 326 |
$continents = WC()->countries->get_continents(); |
| 327 |
|
| 328 |
$supported_methods = array( |
| 329 |
'parcelmachine_omniva' => 'APT', |
| 330 |
'parcelmachine_smartpost' => 'APT', |
| 331 |
'parcelmachine_dpd' => 'APT', |
| 332 |
'courier_omniva' => 'COU', |
| 333 |
'courier_smartpost' => 'COU', |
| 334 |
'local_pickup' => 'OTH', |
| 335 |
'flat_rate' => 'COU' |
| 336 |
); |
| 337 |
|
| 338 |
foreach ( $zones as $zone ) { |
| 339 |
foreach ( $zone['shipping_methods'] as $method ) { |
| 340 |
|
| 341 |
//skip if not one of the supported methods |
| 342 |
if ( empty( $supported_methods[$method->id] ) ) { |
| 343 |
continue; |
| 344 |
} |
| 345 |
|
| 346 |
if ( $supported_methods[$method->id] === $shipment_details->type && ( empty( $shipment_details->carrier ) || strtoupper( $method->carrier ) === $shipment_details->carrier ) ) { |
| 347 |
foreach ( $zone['zone_locations'] as $location ) { |
| 348 |
if ( $location->type === 'continent' && !empty( $continents[$location->code] ) ) { |
| 349 |
|
| 350 |
if ( in_array( $shipment->country, $continents[$location->code]['countries'] ) ) { |
| 351 |
return $method; |
| 352 |
} |
| 353 |
} else if ( $location->type === 'state' ) { |
| 354 |
|
| 355 |
list( $country, $state ) = explode( ':', $location->code ); |
| 356 |
if ( $country === $shipment->country ) { |
| 357 |
return $method; |
| 358 |
} |
| 359 |
} else if ( $shipment->country === $location->code ) { |
| 360 |
return $method; |
| 361 |
} |
| 362 |
} |
| 363 |
} |
| 364 |
} |
| 365 |
} |
| 366 |
} |
| 367 |
|
| 368 |
return false; |
| 369 |
} |
| 370 |
|
| 371 |
/** |
| 372 |
* Set shipment address |
| 373 |
* |
| 374 |
* @since 3.0.0 |
| 375 |
*/ |
| 376 |
private function set_shipment_address( $shipment ) { |
| 377 |
|
| 378 |
if ( !empty( $shipment->country ) ) { |
| 379 |
$shipment_address['country'] = $shipment->country; |
| 380 |
} |
| 381 |
|
| 382 |
if ( !empty( $shipment->county ) ) { |
| 383 |
$shipment_address['state'] = $shipment->county; |
| 384 |
} |
| 385 |
|
| 386 |
if ( !empty( $shipment->city ) ) { |
| 387 |
$shipment_address['city'] = $shipment->city; |
| 388 |
} |
| 389 |
|
| 390 |
if ( !empty( $shipment->street1 ) ) { |
| 391 |
$shipment_address['address_1'] = $shipment->street1; |
| 392 |
} |
| 393 |
|
| 394 |
if ( !empty( $shipment->street2 ) ) { |
| 395 |
$shipment_address['address_2'] = $shipment->street2; |
| 396 |
} |
| 397 |
|
| 398 |
if ( !empty( $shipment->postalCode ) ) { |
| 399 |
$shipment_address['postcode'] = $shipment->postalCode; |
| 400 |
} |
| 401 |
|
| 402 |
if ( !empty( $shipment->firstname ) ) { |
| 403 |
$shipment_address['first_name'] = $shipment->firstname; |
| 404 |
} |
| 405 |
|
| 406 |
if ( !empty( $shipment->lastname ) ) { |
| 407 |
$shipment_address['last_name'] = $shipment->lastname; |
| 408 |
} |
| 409 |
|
| 410 |
return $shipment_address; |
| 411 |
} |
| 412 |
|
| 413 |
/** |
| 414 |
* Set billing address data |
| 415 |
* |
| 416 |
* @since 3.0.0 |
| 417 |
*/ |
| 418 |
private function set_billing_address( $billing_address, $invoice ) { |
| 419 |
|
| 420 |
if ( !empty( $invoice->firstname ) ) { |
| 421 |
$billing_address['first_name'] = $invoice->firstname; |
| 422 |
} |
| 423 |
|
| 424 |
if ( !empty( $invoice->lastname ) ) { |
| 425 |
$billing_address['last_name'] = $invoice->lastname; |
| 426 |
} |
| 427 |
|
| 428 |
if ( !empty( $invoice->country ) ) { |
| 429 |
$billing_address['country'] = $invoice->country; |
| 430 |
} |
| 431 |
|
| 432 |
if ( !empty( $invoice->county ) ) { |
| 433 |
$billing_address['state'] = $invoice->county; |
| 434 |
} |
| 435 |
|
| 436 |
if ( !empty( $invoice->city ) ) { |
| 437 |
$billing_address['city'] = $invoice->city; |
| 438 |
} |
| 439 |
|
| 440 |
if ( !empty( $invoice->street1 ) ) { |
| 441 |
$billing_address['address_1'] = $invoice->street1; |
| 442 |
} |
| 443 |
|
| 444 |
if ( !empty( $invoice->street2 ) ) { |
| 445 |
$billing_address['address_2'] = $invoice->street2; |
| 446 |
} |
| 447 |
|
| 448 |
if ( !empty( $invoice->postalCode ) ) { |
| 449 |
$billing_address['postcode'] = $invoice->postalCode; |
| 450 |
} |
| 451 |
|
| 452 |
if ( !empty( $invoice->legalName ) ) { |
| 453 |
$billing_address['company'] .= $invoice->legalName; |
| 454 |
} |
| 455 |
|
| 456 |
if ( !empty( $invoice->registryCode ) ) { |
| 457 |
$billing_address['company'] .= ' ' . $invoice->registryCode; |
| 458 |
} |
| 459 |
|
| 460 |
if ( !empty( $invoice->vatNum ) ) { |
| 461 |
$billing_address['company'] .= ' ' . $invoice->vatNum; |
| 462 |
} |
| 463 |
|
| 464 |
return $billing_address; |
| 465 |
} |
| 466 |
|
| 467 |
/** |
| 468 |
* Add products to newly created order. |
| 469 |
* |
| 470 |
* @since 3.0.0 |
| 471 |
*/ |
| 472 |
private function add_products_to_order( $content ) { |
| 473 |
|
| 474 |
foreach ( $content as $item_row ) { |
| 475 |
|
| 476 |
$product_id = !empty( $item_row->var ) ? $item_row->var : $item_row->id; |
| 477 |
|
| 478 |
if ( function_exists( 'wc_get_product' ) ) { |
| 479 |
$item_id = $this->order->add_product( wc_get_product( $product_id ), $item_row->qty ); |
| 480 |
} else { |
| 481 |
$item_id = $this->order->add_product( get_product( $product_id ), $item_row->qty ); |
| 482 |
} |
| 483 |
} |
| 484 |
} |
| 485 |
|
| 486 |
/** |
| 487 |
* Check if order has free shipping (coupons) |
| 488 |
* |
| 489 |
* @since 3.0.0 |
| 490 |
*/ |
| 491 |
private function free_shipping() { |
| 492 |
|
| 493 |
$free_shipping = false; |
| 494 |
|
| 495 |
$coupons = !empty( $this->tmp_order->content->coupons ) ? $this->tmp_order->content->coupons : array(); |
| 496 |
|
| 497 |
foreach ( $coupons as $coupon ) { |
| 498 |
|
| 499 |
$coupon = new \WC_Coupon( $coupon ); |
| 500 |
$amount = $coupon->get_amount(); |
| 501 |
|
| 502 |
if ( $coupon->is_type( 'percent' ) ) { |
| 503 |
$amount = $this->order->get_total() / 100 * $amount; |
| 504 |
} |
| 505 |
|
| 506 |
if ( method_exists( $this->order, 'add_item' ) ) { |
| 507 |
|
| 508 |
$item = new \WC_Order_Item_Coupon(); |
| 509 |
|
| 510 |
$item->set_props( array( |
| 511 |
'code' => $coupon->get_code(), |
| 512 |
'discount' => $amount, |
| 513 |
'discount_tax' => 0 |
| 514 |
) ); |
| 515 |
|
| 516 |
$this->order->add_item( $item ); |
| 517 |
} |
| 518 |
|
| 519 |
if ( ( method_exists( $coupon, 'get_free_shipping' ) && $coupon->get_free_shipping() ) || $coupon->free_shipping ) { |
| 520 |
$free_shipping = true; |
| 521 |
} |
| 522 |
} |
| 523 |
|
| 524 |
return $free_shipping; |
| 525 |
} |
| 526 |
|
| 527 |
/** |
| 528 |
* Creates json response for SCO |
| 529 |
* |
| 530 |
* @since 3.0.0 |
| 531 |
*/ |
| 532 |
private function create_json_response( $cart_id, $order_id ) { |
| 533 |
|
| 534 |
if ( isset( $_GET["lang1"] ) ) { |
| 535 |
$locale = $_GET["lang1"]; |
| 536 |
} else { |
| 537 |
$locale = \MakeCommerce\I18n::get_two_char_locale(); |
| 538 |
} |
| 539 |
|
| 540 |
$response = array( |
| 541 |
'cartId' => $cart_id, |
| 542 |
'reference' => $order_id, |
| 543 |
'locale' => $locale, |
| 544 |
'transactionUrl' => array( |
| 545 |
'returnUrl' => array( |
| 546 |
'url' => site_url( '/?mc_cart_update=1&lang1='.$locale ), |
| 547 |
'method' => 'POST' |
| 548 |
), |
| 549 |
'cancelUrl' => array( |
| 550 |
'url' => site_url( '/?mc_cart_update=2&lang1='.$locale ), |
| 551 |
'method' => 'POST' |
| 552 |
), |
| 553 |
'notificationUrl' => array( |
| 554 |
'url' => site_url( '/?mc_cart_update=3&lang1='.$locale ), |
| 555 |
'method' => 'POST' |
| 556 |
), |
| 557 |
) |
| 558 |
); |
| 559 |
|
| 560 |
return json_encode($response); |
| 561 |
} |
| 562 |
|
| 563 |
/** |
| 564 |
* This function is used to calculate shipment cost in SCO |
| 565 |
* Only used for courier and depends on address customers enter |
| 566 |
* |
| 567 |
* Currently not implemented. |
| 568 |
* |
| 569 |
* This functionality would work only when we dont send shipping methods and their cost to SCO. When you remove courier price then SCO should come to this function to get shipment price |
| 570 |
* |
| 571 |
* When some day implemented, also keep in mind the MITM check. Currently it would either fail or not work as intended. |
| 572 |
* |
| 573 |
* @since 3.0.0 |
| 574 |
*/ |
| 575 |
private function calculate_shipment_cost( $cart_info ) { |
| 576 |
|
| 577 |
throw new \Exception("Functionality not implemented yet."); |
| 578 |
|
| 579 |
/* |
| 580 |
Functionality from old code. Returned 2.99 hardcoded. |
| 581 |
$cart_info = json_decode(file_get_contents('php://input')); |
| 582 |
header('Content-type: application/json'); |
| 583 |
echo json_encode(array('amount' => 2.99)); |
| 584 |
*/ |
| 585 |
} |
| 586 |
|
| 587 |
/** |
| 588 |
* Update cart. Checks payment |
| 589 |
* |
| 590 |
* @since 3.0.0 |
| 591 |
*/ |
| 592 |
private function update_cart() { |
| 593 |
|
| 594 |
$return_url = \MakeCommerce\Payment::check_payment(); |
| 595 |
|
| 596 |
if ( isset( $_GET["lang1"] ) ) { |
| 597 |
|
| 598 |
$return_url .= "&lang1=".$_GET["lang1"]; |
| 599 |
\MakeCommerce\i18n::switch_language( $_GET["lang1"] ); |
| 600 |
} |
| 601 |
|
| 602 |
if ( intval( get_query_var( 'mc_cart_update' ) ) === 3 ) { |
| 603 |
echo json_encode( array( 'redirect' => $return_url ) ); |
| 604 |
} else { |
| 605 |
wp_redirect( $return_url ); |
| 606 |
} |
| 607 |
|
| 608 |
exit; |
| 609 |
} |
| 610 |
|
| 611 |
/** |
| 612 |
* Hides shipping methods from cart if option checked |
| 613 |
* |
| 614 |
* @since 3.0.0 |
| 615 |
*/ |
| 616 |
private function hide_shipping_methods() { |
| 617 |
|
| 618 |
if ( !empty( $this->settings['hide_shipping_methods'] ) && $this->settings['hide_shipping_methods'] === 'yes' ) { |
| 619 |
|
| 620 |
echo ' |
| 621 |
<style> |
| 622 |
.shipping,.order-total { |
| 623 |
display:none; |
| 624 |
} |
| 625 |
|
| 626 |
.tax-rate { |
| 627 |
display:none; |
| 628 |
} |
| 629 |
</style> |
| 630 |
'; |
| 631 |
} |
| 632 |
} |
| 633 |
|
| 634 |
/** |
| 635 |
* Run scripts needed on cart view for SCO |
| 636 |
* |
| 637 |
* @since 3.0.0 |
| 638 |
*/ |
| 639 |
public function cart_scripts() { |
| 640 |
|
| 641 |
//remember cart updates in browser history |
| 642 |
wp_enqueue_script( "simplecheckout-cart-scripts", plugin_dir_url(__FILE__) . 'js/cart-scripts.js', array( 'jquery' ), MAKECOMMERCE_VERSION ); |
| 643 |
|
| 644 |
//hide shipping methods if needed |
| 645 |
$this->hide_shipping_methods(); |
| 646 |
} |
| 647 |
|
| 648 |
/** |
| 649 |
* Overrides checkout from WooCommerce |
| 650 |
* |
| 651 |
* @since 3.0.0 |
| 652 |
*/ |
| 653 |
public function take_over_checkout( $checkout ) { |
| 654 |
|
| 655 |
global $woocommerce, $wpdb; |
| 656 |
|
| 657 |
//exit when guest checkout is enabled but user is not logged in. SCO is not possible in this scenario |
| 658 |
if ( get_option( 'woocommerce_enable_guest_checkout' ) !== 'yes' && !is_user_logged_in() ) { |
| 659 |
|
| 660 |
wc_add_notice( __( 'You have to log in to continue to checkout', 'wc_makecommerce_domain' ), 'error'); |
| 661 |
wp_redirect( $woocommerce->cart->get_cart_url() ); |
| 662 |
|
| 663 |
exit; |
| 664 |
} |
| 665 |
|
| 666 |
$data = array( |
| 667 |
'order' => array(), |
| 668 |
'coupons' => $woocommerce->cart->get_applied_coupons(), |
| 669 |
'discount' => $woocommerce->cart->get_cart_discount_total(), |
| 670 |
'discount_tax' => $woocommerce->cart->get_cart_discount_tax_total() |
| 671 |
); |
| 672 |
|
| 673 |
//do we have free shipping? |
| 674 |
$free_shipping = false; |
| 675 |
foreach ( $woocommerce->cart->get_applied_coupons() as $coupon ) { |
| 676 |
|
| 677 |
$coupon = new \WC_Coupon( $coupon ); |
| 678 |
if ( ( method_exists( $coupon, 'get_free_shipping' ) && $coupon->get_free_shipping() ) || $coupon->free_shipping ) { |
| 679 |
$free_shipping = true; |
| 680 |
} |
| 681 |
} |
| 682 |
|
| 683 |
$qty = 0; $amount = 0; |
| 684 |
$cart = $woocommerce->cart->get_cart(); |
| 685 |
foreach ( $cart as $cart_item ) { |
| 686 |
|
| 687 |
$data['order'][] = array( 'id' => $cart_item['product_id'], 'qty' => $cart_item['quantity'], 'var' => $cart_item['variation_id'] ); |
| 688 |
$qty += $cart_item['quantity']; |
| 689 |
$amount += $cart_item['line_total'] + $cart_item['line_tax']; |
| 690 |
} |
| 691 |
|
| 692 |
if ( count( $data ) > 0 ) { |
| 693 |
|
| 694 |
$wpdb->insert( $wpdb->prefix . MAKECOMMERCE_SCO_TABLENAME, array( |
| 695 |
'created' => time(), |
| 696 |
'modified' => time(), |
| 697 |
'status' => 0, |
| 698 |
'content' => json_encode( $data ) |
| 699 |
) ); |
| 700 |
|
| 701 |
$locale = \MakeCommerce\i18n::get_two_char_locale(); |
| 702 |
|
| 703 |
$tmp_order_id = $wpdb->insert_id; |
| 704 |
$cart_to_order_url = site_url( '/?mc_cart_to_order=1&lang1='.$locale ); |
| 705 |
$calculate_shipment_url = site_url( '/?mc_calculate_shipment=1&lang1='.$locale ); |
| 706 |
|
| 707 |
//set correct tos url. |
| 708 |
if ( !empty( $this->settings['shop_tos_url_'.$locale] ) ) { |
| 709 |
$tos_url = $this->settings['shop_tos_url_'.$locale]; |
| 710 |
} else { |
| 711 |
if ( !empty( $this->settings['shop_tos_url'] ) ) { |
| 712 |
$tos_url = $this->settings['shop_tos_url']; |
| 713 |
} else { |
| 714 |
$tos_url = site_url(); |
| 715 |
} |
| 716 |
} |
| 717 |
|
| 718 |
$data = array( |
| 719 |
'cartRef' => 'PreOrder '.$tmp_order_id, |
| 720 |
'pluginUrls' => array( |
| 721 |
'cartToOrder' => $cart_to_order_url, |
| 722 |
'calculateShipment' => $calculate_shipment_url, |
| 723 |
'tos' => $tos_url |
| 724 |
), |
| 725 |
'amount' => sprintf( "%.2f", round( max( $amount, 0.01 ), 2 ) ), |
| 726 |
'currency' => 'EUR', |
| 727 |
'sourceCountry' => WC()->countries->get_base_country(), |
| 728 |
'locale' => $locale, |
| 729 |
'shipmentMethods' => array() |
| 730 |
); |
| 731 |
|
| 732 |
$package = $woocommerce->cart->get_shipping_packages(); |
| 733 |
|
| 734 |
if ( !empty( $package ) ) { |
| 735 |
$package = $package[0]; |
| 736 |
} |
| 737 |
|
| 738 |
$zones = array(); |
| 739 |
|
| 740 |
$zone = new \WC_Shipping_Zone(0); |
| 741 |
$zones[ $zone->get_id() ] = $zone->get_data(); |
| 742 |
$zones[ $zone->get_id() ]['formatted_zone_location'] = $zone->get_formatted_location(); |
| 743 |
$zones[ $zone->get_id() ]['shipping_methods'] = $zone->get_shipping_methods(); |
| 744 |
$zones = array_merge( $zones, \WC_Shipping_Zones::get_zones() ); |
| 745 |
|
| 746 |
$continents = WC()->countries->get_continents(); |
| 747 |
|
| 748 |
$method_country_x = array(); |
| 749 |
|
| 750 |
$supported_methods = array( |
| 751 |
'parcelmachine_omniva' => 'APT', |
| 752 |
'parcelmachine_smartpost' => 'APT', |
| 753 |
'parcelmachine_dpd' => 'APT', |
| 754 |
'courier_omniva' => 'COU', |
| 755 |
'courier_smartpost' => 'COU', |
| 756 |
'local_pickup' => 'OTH', |
| 757 |
'flat_rate' => 'COU' |
| 758 |
); |
| 759 |
|
| 760 |
foreach ( $zones as $zone ) { |
| 761 |
|
| 762 |
foreach ( $zone['shipping_methods'] as $method_key => $method ) { |
| 763 |
|
| 764 |
//ship if shipping method isnt enabled |
| 765 |
if ( $method->enabled !== 'yes' ) { |
| 766 |
continue; |
| 767 |
} |
| 768 |
|
| 769 |
$carrier = array( 'countries' => array() ); |
| 770 |
|
| 771 |
if ( !empty( $supported_methods[$method->id] ) ) { |
| 772 |
|
| 773 |
//skip shipping methid if it is not available for a package |
| 774 |
foreach ( $woocommerce->cart->get_shipping_packages() as $package ) { |
| 775 |
if ( !$method->is_available( $package ) ) { |
| 776 |
continue( 2 ); |
| 777 |
} |
| 778 |
} |
| 779 |
|
| 780 |
$method_type = $supported_methods[$method->id]; |
| 781 |
|
| 782 |
if ( empty( $method_country_x[$method_type] ) ) { |
| 783 |
$method_country_x[$method_type] = array(); |
| 784 |
} |
| 785 |
|
| 786 |
if ( !empty( $method->carrier ) ) { |
| 787 |
$carrier['carrier'] = mb_strtoupper( $method->carrier ); |
| 788 |
} |
| 789 |
|
| 790 |
if ( empty( $zone['zone_locations'] ) ) { |
| 791 |
$carrier['countries'] = array_keys( WC()->countries->get_allowed_countries() ); |
| 792 |
} else { |
| 793 |
foreach ( $zone['zone_locations'] as $location ) { |
| 794 |
|
| 795 |
if ( $location->type === 'continent' && !empty( $continents[$location->code] ) ) { |
| 796 |
$countries = array_diff( $continents[$location->code]['countries'], $method_country_x[$method_type] ); |
| 797 |
$carrier['countries'] = array_merge( $carrier['countries'], $countries ); |
| 798 |
} else if ( $location->type === 'state' ) { |
| 799 |
list( $country, $state ) = explode( ':', $location->code ); |
| 800 |
$carrier['countries'][] = $country; |
| 801 |
} else if ( $location->type === 'country' ) { |
| 802 |
$carrier['countries'][] = $location->code; |
| 803 |
} |
| 804 |
} |
| 805 |
} |
| 806 |
|
| 807 |
$method_country_x[$method_type] = array_merge( $method_country_x[$method_type], $carrier['countries'] ); |
| 808 |
$prices = $method->get_rates_for_package( $package ); |
| 809 |
$price = ($free_shipping && $method->instance_settings["allow_free_shipping_coupons"] == "yes") ? 0.00 : \MakeCommerce\Payment::get_rate_with_taxes( $method->id.':'.$method_key, $prices ); |
| 810 |
$carrier['type'] = strtoupper( $method_type ); |
| 811 |
$carrier['name'] = $method->title; |
| 812 |
$carrier['methodId'] = $method->id . ':' . $method_key; |
| 813 |
$carrier['amount'] = sprintf( "%.2f", round( $price, 2 ) ); |
| 814 |
$data['shipmentMethods'][] = $carrier; |
| 815 |
} |
| 816 |
} |
| 817 |
} |
| 818 |
|
| 819 |
$cart = $this->MK->createCart( $data ); |
| 820 |
$wpdb->update( $wpdb->prefix . MAKECOMMERCE_SCO_TABLENAME, array( 'cart_id' => $cart->id ), array( 'id' => $tmp_order_id ) ); |
| 821 |
|
| 822 |
//add wp meta of the data provided to SCO. This way we can later check if the data values and so on were actually provided by us or the data has been manipulated by a mitm |
| 823 |
$wpdb->insert( $wpdb->prefix . MAKECOMMERCE_SCO_TABLENAME, array( |
| 824 |
'cart_id' => $cart->id."_provided_sco_data", |
| 825 |
'created' => time(), |
| 826 |
'modified' => time(), |
| 827 |
'status' => 0, |
| 828 |
'content' => json_encode( $data ) |
| 829 |
) ); |
| 830 |
|
| 831 |
wp_redirect( $cart->scoUrl ); |
| 832 |
|
| 833 |
exit; |
| 834 |
} |
| 835 |
|
| 836 |
die('no content'); |
| 837 |
} |
| 838 |
|
| 839 |
/** |
| 840 |
* Loads all form fields specific to this payment gateway |
| 841 |
* |
| 842 |
* @since 3.0.0 |
| 843 |
*/ |
| 844 |
public function initialize_gateway_type_form_fields() { |
| 845 |
|
| 846 |
$this->form_fields['scointro'] = array( |
| 847 |
'type' => 'title', |
| 848 |
'description' => __( 'SimpleCheckout replaces Woocommerce built-in check-out dialog with Makecommerce hosted dialog. It is more convenient and faster for your customers', 'wc_makecommerce_domain').'<br>'.__('See more about SimpleCheckout on: <a target=_blank href="https://makecommerce.net/simplecheckout/">makecommerce.net/simplecheckout</a>', 'wc_makecommerce_domain' ), |
| 849 |
); |
| 850 |
|
| 851 |
$this->form_fields['active'] = array( |
| 852 |
'title' => __( 'Enable/Disable', 'wc_makecommerce_domain' ), |
| 853 |
'type' => 'checkbox', |
| 854 |
'label' => __( 'Enable SimpleCheckout', 'wc_makecommerce_domain' ), |
| 855 |
'default' => 'yes' |
| 856 |
); |
| 857 |
|
| 858 |
//get a list of all active languages |
| 859 |
$languages = \MakeCommerce\i18n::get_active_languages(); |
| 860 |
|
| 861 |
//default version with no languages |
| 862 |
if ( empty( $languages ) ) { |
| 863 |
|
| 864 |
$this->form_fields['shop_tos_url'] = array( |
| 865 |
'title' => __( 'Shop ToS url', 'wc_makecommerce_domain' ), |
| 866 |
'description' => __( 'paste here url of your shop "Terms and Conditions" page', 'wc_makecommerce_domain' ), |
| 867 |
'type' => 'text', |
| 868 |
); |
| 869 |
} else { //version with different languages |
| 870 |
|
| 871 |
foreach ( $languages as $language_code=>$language ) { |
| 872 |
|
| 873 |
$shortLanguageCode = substr( $language_code, 0, 2 ); |
| 874 |
$this->form_fields['shop_tos_url_'.$shortLanguageCode] = array( |
| 875 |
'title' => __( 'Shop ToS url', 'wc_makecommerce_domain' ).sprintf( ' (%s)', $shortLanguageCode ), |
| 876 |
'description' => __( 'paste the url of your shops "Terms and Conditions" page here', 'wc_makecommerce_domain' ), |
| 877 |
'type' => 'text', |
| 878 |
); |
| 879 |
} |
| 880 |
} |
| 881 |
|
| 882 |
//hide shipping methods block option |
| 883 |
$this->form_fields['hide_shipping_methods'] = array( |
| 884 |
'title' => __( 'Hide shipping methods block', 'wc_makecommerce_domain' ), |
| 885 |
'type' => 'checkbox', |
| 886 |
'label' => __( 'Hide shipping methods block on cart page. This will make it look more clean and simple', 'wc_makecommerce_domain' ), |
| 887 |
'default' => 'no' |
| 888 |
); |
| 889 |
} |
| 890 |
|
| 891 |
/** |
| 892 |
* Checks whether this payment gateway is enabled |
| 893 |
* returns true or false |
| 894 |
* |
| 895 |
* @since 3.0.0 |
| 896 |
*/ |
| 897 |
public function enabled() { |
| 898 |
|
| 899 |
if ( get_option( 'mk_checkout_sco', 'no' ) == "yes" ) { |
| 900 |
return true; |
| 901 |
} |
| 902 |
|
| 903 |
return false; |
| 904 |
} |
| 905 |
} |