| 1 |
<?php |
| 2 |
/** |
| 3 |
* Cash on Delivery (pay on arrival) gateway for the native checkout. |
| 4 |
* |
| 5 |
* This is an "offline" gateway: there is no remote payment provider to |
| 6 |
* talk to. The booking is created immediately and the balance is |
| 7 |
* collected later (on arrival / at the property). Because nothing is |
| 8 |
* captured online, total_paid stays 0 and the full amount is recorded |
| 9 |
* as the due balance on the booking. |
| 10 |
* |
| 11 |
* Settings live in the existing eshb_settings option: |
| 12 |
* - gateway-cod-enable (switcher; on by default) |
| 13 |
* - cod-title (label shown at checkout) |
| 14 |
* - cod-description (instructions shown under the label) |
| 15 |
*/ |
| 16 |
|
| 17 |
if ( ! defined( 'ABSPATH' ) ) exit; |
| 18 |
|
| 19 |
class ESHB_Native_COD_Gateway extends ESHB_Native_Abstract_Gateway { |
| 20 |
|
| 21 |
protected $id = 'cod'; |
| 22 |
protected $title = ''; |
| 23 |
protected $description = ''; |
| 24 |
|
| 25 |
public function __construct() { |
| 26 |
$title = trim( (string) eshb_native_checkout_get_setting( 'cod-title', '' ) ); |
| 27 |
$desc = trim( (string) eshb_native_checkout_get_setting( 'cod-description', '' ) ); |
| 28 |
|
| 29 |
$this->title = $title !== '' ? $title : __( 'Cash on Delivery', 'easy-hotel' ); |
| 30 |
$this->description = $desc !== '' ? $desc : __( 'Pay with cash upon arrival / at the property.', 'easy-hotel' ); |
| 31 |
} |
| 32 |
|
| 33 |
/** |
| 34 |
* Enabled when the admin switch is on. Defaults to enabled when the |
| 35 |
* setting has never been saved, so COD is available out of the box. |
| 36 |
*/ |
| 37 |
public function is_enabled() { |
| 38 |
return ! empty( eshb_native_checkout_get_setting( 'gateway-cod-enable', true ) ); |
| 39 |
} |
| 40 |
|
| 41 |
/** |
| 42 |
* No remote order to create for an offline gateway — succeed |
| 43 |
* immediately so the checkout flow can proceed to completion. |
| 44 |
*/ |
| 45 |
public function create_payment( array $reservation, array $customer, array $pricing ) { |
| 46 |
return [ 'success' => true, 'data' => [] ]; |
| 47 |
} |
| 48 |
|
| 49 |
/** |
| 50 |
* Nothing is captured online for COD, but we still record the order |
| 51 |
* amount and currency so the payment entry reflects the real booking |
| 52 |
* total. The amount is recomputed from the current reservation using |
| 53 |
* the same coupon/email inputs the checkout handler uses, so it stays |
| 54 |
* in lockstep with the booking total. |
| 55 |
*/ |
| 56 |
public function capture_payment( array $params ) { |
| 57 |
$amount = 0.0; |
| 58 |
$currency = $this->get_currency_code(); |
| 59 |
|
| 60 |
if ( function_exists( 'eshb_native_checkout_get_items' ) && class_exists( 'ESHB_Native_Pricing' ) ) { |
| 61 |
$items = eshb_native_checkout_get_items(); |
| 62 |
if ( ! empty( $items ) ) { |
| 63 |
// Nonce is verified by ESHB_Native_Checkout before this |
| 64 |
// gateway method runs; mirror the handler's inputs so the |
| 65 |
// recalculated total matches the booking total exactly. |
| 66 |
// phpcs:disable WordPress.Security.NonceVerification.Missing |
| 67 |
$coupon = isset( $_POST['coupon'] ) ? sanitize_text_field( wp_unslash( $_POST['coupon'] ) ) : ''; |
| 68 |
$email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : ''; |
| 69 |
// phpcs:enable WordPress.Security.NonceVerification.Missing |
| 70 |
|
| 71 |
$pricing = ESHB_Native_Pricing::calculate_cart( $items, $coupon, $email ); |
| 72 |
$amount = (float) ( $pricing['grandTotal'] ?? $pricing['totalPrice'] ?? 0 ); |
| 73 |
} |
| 74 |
} |
| 75 |
|
| 76 |
return [ |
| 77 |
'success' => true, |
| 78 |
'transaction_id' => uniqid( 'COD-' ), |
| 79 |
'amount' => $amount, |
| 80 |
'currency' => $currency, |
| 81 |
'mode' => 'live', |
| 82 |
]; |
| 83 |
} |
| 84 |
|
| 85 |
/** |
| 86 |
* Resolve an ISO-4217 currency code for the payment record. Prefers |
| 87 |
* WooCommerce's configured currency (the plugin already integrates |
| 88 |
* with it for symbol formatting), then maps the configured symbol, |
| 89 |
* then falls back to USD. |
| 90 |
*/ |
| 91 |
private function get_currency_code() { |
| 92 |
if ( function_exists( 'get_woocommerce_currency' ) ) { |
| 93 |
$code = get_woocommerce_currency(); |
| 94 |
if ( ! empty( $code ) ) return $code; |
| 95 |
} |
| 96 |
|
| 97 |
$settings = get_option( 'eshb_settings', [] ); |
| 98 |
$symbol = isset( $settings['currency_symbol'] ) ? trim( (string) $settings['currency_symbol'] ) : ''; |
| 99 |
$map = [ |
| 100 |
'$' => 'USD', |
| 101 |
'€' => 'EUR', |
| 102 |
'£' => 'GBP', |
| 103 |
'¥' => 'JPY', |
| 104 |
'A$' => 'AUD', |
| 105 |
'C$' => 'CAD', |
| 106 |
'₹' => 'INR', |
| 107 |
'₺' => 'TRY', |
| 108 |
'₽' => 'RUB', |
| 109 |
]; |
| 110 |
if ( ! empty( $symbol ) && isset( $map[ $symbol ] ) ) { |
| 111 |
return $map[ $symbol ]; |
| 112 |
} |
| 113 |
|
| 114 |
return apply_filters( 'eshb_native_cod_currency', 'USD' ); |
| 115 |
} |
| 116 |
} |
| 117 |
|