first commit

This commit is contained in:
dwindown
2025-08-21 20:39:34 +07:00
commit 58c1497171
576 changed files with 177044 additions and 0 deletions

View File

@@ -0,0 +1,581 @@
<?php
namespace Formipay\Payment;
use Formipay\Traits\SingletonTrait;
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
class CashOnDelivery extends Payment {
use SingletonTrait;
private $gateway = 'cod';
protected function __construct() {
parent::__construct();
add_filter( 'formipay/global-settings/tab:payment', [$this, 'add_settings'] );
add_filter( 'formipay/form-config/tab:payments', [$this, 'add_cod_setings'] );
add_filter( 'formipay/form-config/tab:payments/gateways', [$this, 'add_gateway'] );
add_filter( 'formipay/payment-list/cod/logo', [$this, 'set_frontend_logo'] );
add_filter( 'formipay/order/order-details', [$this, 'add_fee'], 999, 3 );
add_filter( 'formipay/order/payment-details/cod', [$this, 'render_payment_details'], 999, 4 );
add_action( 'template_redirect', [$this, 'check_parse_query'], 999 );
add_filter( 'formipay/thankyou/shortcodes', [$this, 'add_order_shortcodes'], 999, 4 );
add_action('wp_ajax_formipay_cod_confirmation', [$this, 'handle_formipay_cod_confirmation'] );
add_action('wp_ajax_nopriv_formipay_cod_confirmation', [$this, 'handle_formipay_cod_confirmation'] );
}
public function add_transaction($order_data){
return;
}
public function cancel_payment($order_id) {
return;
}
public function add_settings($settings) {
$cod = array(
$this->gateway.'_toggle' => array(
'type' => 'checkbox',
'label' => __('Activate Cash On Delivery', 'formipay'),
'submenu' => __( 'Cash On Delivery', 'formipay' )
),
$this->gateway.'_settings_group' => array(
'type' => 'group_title',
'label' => __( 'General', 'formipay' ),
'description' => __( 'Set the rule of Cash On Delivery', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
),
'group' => 'started'
),
$this->gateway.'_label' => array(
'type' => 'text',
'label' => __('Label', 'formipay'),
'value' => __( 'COD', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_item_name' => array(
'type' => 'text',
'label' => __('Item Name', 'formipay'),
'value' => __( 'COD Fee', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_icon' => array(
'type' => 'image',
'label' => __('Icon', 'formipay'),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_fee_amount' => array(
'type' => 'number',
'label' => __('Fee Amount', 'formipay'),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_fee_type' => array(
'type' => 'select',
'label' => __('Fee Type', 'formipay'),
'options' => array(
'fixed' => __( 'Fixed Amount', 'formipay' ),
'percentage' => __( 'Percentage', 'formipay' )
),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
),
'group' => 'ended'
),
$this->gateway.'_details_group' => array(
'type' => 'group_title',
'label' => __( 'Instruction', 'formipay' ),
'description' => __( 'Set instruction to buyer how to pay with COD method.', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
),
'group' => 'started'
),
$this->gateway.'_instruction_thankyou' => array(
'type' => 'tinymce',
'label' => __( 'Thankyou Screen', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'hints' => array(
'product_name' => __( 'Product Name', 'formipay' ),
'order_id' => __( 'Order ID', 'formipay' ),
'grand_total' => __( 'Order Total', 'formipay' ),
'confirmation_page_link' => __( 'Confirmation Page Link', 'formipay' )
),
'value' => '<p>Please prepare your cash of <span style="text-align: var(--bs-body-text-align);">{{grand_total}}&nbsp;</span><span style="text-align: var(--bs-body-text-align);">and pay it to the courier who delivers your&nbsp;</span>{{product_name}}.</p>',
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
),
),
$this->gateway.'_instruction_whatsapp' => array(
'type' => 'hint_textarea',
'label' => __( 'WhatsApp Message', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'hints' => array(
'product_name' => __( 'Product Name', 'formipay' ),
'order_id' => __( 'Order ID', 'formipay' ),
'grand_total' => __( 'Order Total', 'formipay' ),
'confirmation_page_link' => __( 'Confirmation Page Link', 'formipay' )
),
'value' => 'Please prepare your cash of {{grand_total}} and pay it to the courier who delivers your {{product_name}}.',
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
),
'group' => 'ended'
),
$this->gateway.'_confirmation_page_group' => array(
'type' => 'group_title',
'label' => __( 'Confirmation Page', 'formipay' ),
'description' => sprintf(
// translators: %s is the site URL.
__(
'<p>Set confirmation page for buyer to confirm that they have receive the package and pay the order to courier.</p>
<p>Confirmation magic URL: <code>%s/payment-confirm/cod/{{autogenerated_token}}</code></p>'
, 'formipay' ), site_url()),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
),
'group' => 'started'
),
$this->gateway.'_confirmation_page_content' => array(
'type' => 'tinymce',
'label' => __( 'Page Content', 'formipay' ),
'hints' => array(
'order_details' => __( 'Order Details', 'formipay' ),
'confirmation_form' => __( 'Confirmation Form', 'formipay' ),
),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_confirmation_page_width' => array(
'type' => 'number',
'label' => __( 'Page Width', 'formipay' ),
'value' => '600',
'description' => __( 'in pixel (px)', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_confirmation_table_alignment' => array(
'type' => 'radio',
'label' => __('Table Content Alignment', 'formipay'),
'value' => 'center',
'options' => array(
'left' => '<i class="bi bi-text-left"></i> Left',
'center' => '<i class="bi bi-text-center"></i> Center',
'right' => '<i class="bi bi-text-right"></i> Right',
),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_confirmation_form_agreement' => array(
'type' => 'text',
'label' => __( 'Agreement', 'formipay' ),
'value' => __( 'I have receipt the package and pay as billed to the courier.', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
)
),
$this->gateway.'_confirmation_form_button' => array(
'type' => 'text',
'label' => __( 'Button Text', 'formipay' ),
'value' => __( 'Confirm', 'formipay' ),
'submenu' => __( 'Cash On Delivery', 'formipay' ),
'dependency' => array(
'key' => $this->gateway.'_toggle',
'value' => 'not_empty'
),
'group' => 'ended',
)
);
foreach($cod as $key => $value){
$settings[$key] = $value;
}
return $settings;
}
public function add_cod_setings($fields) {
$cod_settings = array(
$this->gateway.'_confirmation_notice_message_group' => array(
'type' => 'group_title',
'label' => __( 'Confirmation Notice Messages', 'formipay' ),
'description' => __( 'Set notice message on every condition about attempting to confirm the payment', 'formipay' ),
'submenu' => __( 'COD', 'formipay' ),
'group' => 'started'
),
$this->gateway.'_confirmation_update_to_status' => array(
'type' => 'select',
'label' => __( 'Change status order to', 'formipay' ),
'options' => formipay_order_status_list(),
'value' => 'payment-confirm',
'submenu' => __( 'COD', 'formipay' ),
),
$this->gateway.'_confirmation_message_success' => array(
'type' => 'hint_textarea',
'label' => __( 'Successfully Confirmed Message', 'formipay' ),
'hints' => array(
'order_id' => __('Order ID', 'formipay')
),
'value' => __('Successfully confirmed COD #{{order_id}}', 'formipay'),
'description' => __('When successfully change the order status to the preferred one', 'formipay'),
'submenu' => __( 'COD', 'formipay' ),
),
$this->gateway.'_confirmation_message_already_confirmed' => array(
'type' => 'hint_textarea',
'label' => __( 'Has Been Confirmed Message', 'formipay' ),
'hints' => array(
'order_id' => __('Order ID', 'formipay')
),
'value' => __('#{{order_id}} has been confirmed', 'formipay'),
'description' => __('When the order status has been the preferred one', 'formipay'),
'submenu' => __( 'COD', 'formipay' ),
),
$this->gateway.'_confirmation_message_error' => array(
'type' => 'hint_textarea',
'label' => __( 'Failed to Confirm Message', 'formipay' ),
'hints' => array(
'order_id' => __('Order ID', 'formipay'),
'system_error_message' => __('System Error Message', 'formipay')
),
'value' => __('Failed to proceed. Error: {{system_error_message}}', 'formipay'),
'description' => __('When error to change the order status to the preferred one', 'formipay'),
'submenu' => __( 'COD', 'formipay' ),
'group' => 'ended'
)
);
foreach($cod_settings as $key => $value){
$fields[$key] = $value;
}
return $fields;
}
public function add_gateway($gateways) {
$formipay_settings = get_option('formipay_settings');
if(isset($formipay_settings['cod_toggle']) && false !== $formipay_settings['cod_toggle']){
// $gateways['cod'] = __('Cash On Delivery', 'formipay');
$gateways[] = [
'id' => $this->gateway,
'gateway' => __( 'COD', 'formipay' ),
];
}
return $gateways;
}
public function set_frontend_logo($logo){
if($logo == false){
$logo = FORMIPAY_URL . 'public/assets/img/cod_default_icon.png';
}
return $logo;
}
public function add_fee($details, $form_id, $order_data){
if($order_data['payment_gateway'] == 'cod'){
$formipay_settings = get_option('formipay_settings');
$fee_amount = $formipay_settings['cod_fee_amount'];
$fee_type = $formipay_settings['cod_fee_type'];
if($fee_type == 'percentage'){
$grand_total = 0;
if(!empty($details)){
foreach($details as $detail){
$grand_total += $detail['subtotal'];
}
}
$fee_amount = $grand_total * floatval($fee_amount) / 100;
}
$details[] = [
'item' => $formipay_settings['cod_item_name'],
'amount' => $fee_amount,
'subtotal' => $fee_amount
];
}
return $details;
}
public function render_payment_details($render, $form_id, $order_data, $submit_action_type) {
if($order_data['payment_gateway'] == 'cod'){
$render = '';
$formipay_settings = get_option('formipay_settings');
$render .= ($submit_action_type == 'thankyou') ? '<div class="cod-instruction" style="text-align:'.formipay_get_post_meta($form_id, 'thankyou_screen_table_alignment').';">' : '';
$replacements = [
'{{product_name}}' => get_the_title($form_id),
'{{order_id}}' => $order_data['id'],
'{{grand_total}}' => formipay_price_format($order_data['total'], $form_id),
'{{confirmation_page_link}}' => site_url('/payment-confirm/'.$this->gateway.'/'.base64_encode($form_id.':::'.$order_data['id']))
];
$render .= strtr( $formipay_settings['cod_instruction_'.$submit_action_type], $replacements );
$render .= ($submit_action_type == 'thankyou') ? '</div>' : '';
}
return $render;
}
public function check_parse_query() {
global $wp_query;
$formipay_settings = get_option('formipay_settings');
if(is_admin()) :
return;
endif;
if(
!is_admin() &&
is_array($wp_query->query) &&
array_key_exists('formipay-payment-confirm', $wp_query->query) &&
true === boolval($wp_query->query['formipay-payment-confirm']) &&
array_key_exists('gateway', $wp_query->query) &&
'cod' === $wp_query->query['gateway']
) :
$token = explode(':::', base64_decode($wp_query->query['formipay-token']));
$form_id = $token[0];
$order_id = $token[1];
$thankyou_slug = 'thankyou';
if(!empty($formipay_settings['thankyou_link'])){
$thankyou_slug = $formipay_settings['thankyou_link'];
}
$order = formipay_get_order($order_id);
if($order['payment_gateway'] !== 'cod'){
wp_safe_redirect( site_url('/'.$thankyou_slug.'/'.$wp_query->query['formipay-token']) );
}
$button_background_color = json_decode(formipay_get_post_meta($form_id, 'button_bg_color'), true );
$button_text_color = json_decode(formipay_get_post_meta($form_id, 'button_text_color'), true );
$button_border_color = json_decode( formipay_get_post_meta($form_id, 'button_border_color'), true );
get_header();
?>
<style>
body {
--formipay-confirmation-page-width: <?php echo esc_html($formipay_settings[$this->gateway.'_confirmation_page_width']); ?>px;
--formipay-confirmation-page-table-alignment: <?php echo esc_html($formipay_settings[$this->gateway.'_confirmation_table_alignment']) ?>;
--formipay-button-submit-bg-color: <?php echo esc_html($button_background_color['regular']) ?? '#000000'; ?>;
--formipay-button-submit-bg-color-hover: <?php echo esc_html($button_background_color['hover']) ?? '#ffffff'; ?>;
--formipay-button-submit-bg-color-active: <?php echo esc_html($button_background_color['active']) ?? '#ffffff'; ?>;
--formipay-button-submit-text-color: <?php echo esc_html($button_text_color['regular']) ?? '#ffffff'; ?>;
--formipay-button-submit-text-color-hover: <?php echo esc_html($button_text_color['hover']) ?? '#000000'; ?>;
--formipay-button-submit-text-color-active: <?php echo esc_html($button_text_color['active']) ?? '#000000'; ?>;
--formipay-button-submit-border-color: <?php echo esc_html($button_border_color['regular']) ?? '#000000;' ?>;
--formipay-button-submit-border-color-hover: <?php echo esc_html($button_border_color['hover']) ?? '#ffffff'; ?>;
--formipay-button-submit-border-color-active: <?php echo esc_html($button_border_color['active']) ?? '#ffffff'; ?>;
}
</style>
<div class="formipay-container">
<div class="formipay-content-wrapper">
<?php
echo wp_kses_post(str_replace(
[
'{{order_details}}',
'{{confirmation_form}}'
],
[
$this->render_order_details_table($form_id, $order_id),
$this->render_confirmation_form($form_id, $order_id)
],
$formipay_settings[$this->gateway.'_confirmation_page_content']
))
?>
</div>
</div>
<?php
get_footer();
exit;
endif;
}
public function render_confirmation_form($form_id, $order_id){
$formipay_settings = get_option( 'formipay_settings' );
$order = formipay_get_order($order_id);
ob_start();
if($order['status'] == 'on-hold') {
?>
<form id="formipay-cod-confirmation">
<input type="hidden" id="form_id" value="<?php echo intval($form_id); ?>">
<input type="hidden" id="order_id" value="<?php echo intval($order_id); ?>">
<?php wp_nonce_field('formipay_cod_confirmation', 'formipay_nonce'); ?>
<div class="formipay-agreement">
<input id="cod_agreement" type="checkbox" class="formipay-input">
<label for="cod_agreement"><?php echo esc_html($formipay_settings['cod_confirmation_form_agreement']); ?></label>
</div>
<div class="formipay-button-wrapper">
<button type="button" id="confirm-cod-order" class="formipay-submit-button" disabled><?php echo esc_html($formipay_settings['cod_confirmation_form_button']); ?></button>
</div>
</form>
<?php
}
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function render_order_details_table($form_id, $order_id) {
ob_start();
?>
<table id="order-details">
<tbody>
<?php
$order = formipay_get_order($order_id);
if(false !== $order){
$items = maybe_unserialize($order['items']);
foreach($items as $item){
$label = ucwords(str_replace('_', ' ', $item['item']));
if(!in_array($label, ['payment', 'payment_gateway'])){
$qty = '';
if(isset($item['qty']) && !empty($item['qty'])){
$qty = ' × '.$item['qty'];
}
?>
<tr>
<th><?php echo esc_html($label) . esc_html($qty); ?></th>
<td><?php echo esc_html(formipay_price_format($item['subtotal'], $form_id)); ?></td>
</tr>
<?php
}
}
}
?>
<tr class="formipay-grand-total-row">
<th><?php echo esc_html__( 'Total', 'formipay' ); ?></th>
<td><?php echo esc_html(formipay_price_format($order['total'], $form_id)); ?></td>
</tr>
</tbody>
</table>
<?php
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function handle_formipay_cod_confirmation() {
// Check nonce
$nonce_valid = check_ajax_referer('formipay_cod_confirmation', 'formipay_nonce', false);
// Handle the valid nonce case
if ($nonce_valid) {
// Retrieve the data
$form_id = isset($_POST['form_id']) ? sanitize_text_field( wp_unslash($_POST['form_id']) ) : '';
$order_id = isset($_POST['order_id']) ? sanitize_text_field( wp_unslash($_POST['order_id']) ) : '';
$update = formipay_update_order_status([
'form_id' => $form_id,
'order_id' => $order_id,
'status' => 'payment-confirm',
'payment_gateway' => 'cod'
]);
wp_send_json( [
'success' => boolval($update['valid']),
'data' => [
'message' => $update['message'],
'icon' => (boolval($update['valid']) == true) ? 'success' : 'info'
]
] );
}
// Nonce is invalid, handle the error
wp_send_json_error([
'message' => 'Security check failed. Please try again.',
'icon' => 'error'
]);
}
public function add_order_shortcodes($shortcodes, $form_id, $order_data, $submit_action_type) {
if($order_data['payment_gateway'] == $this->gateway){
$confirmation_page_link = site_url('/payment-confirm/'.$this->gateway.'/'.base64_encode($form_id.':::'.$order_data['id']));
$shortcodes['payment_confirmation_form'] = '<a href="'.$confirmation_page_link.'" target="_blank">C.O.D Confirmation</a>';
}
return $shortcodes;
}
public function process_payment($order_data) {
return $order_data;
}
}