Receipt or invoice in the block checkout (Απόδειξη / Τιμολόγιο)
The block checkout version: customers choose a receipt or an invoice; for an invoice they fill in company name, VAT number (ΑΦΜ, checked), tax office (ΔΟΥ) and business activity. The details are saved with the order and shown in the admin, the emails and the order page.
<?php
// Labels are in Greek; change them if you like.
$document_label = 'Παραστατικό';
$choices = array(
'receipt' => 'Απόδειξη',
'invoice' => 'Τιμολόγιο',
);
$fields = array(
'company' => 'Επωνυμία εταιρείας',
'vat' => 'ΑΦΜ',
'tax-office' => 'ΔΟΥ',
'activity' => 'Δραστηριότητα',
);
$vat_error = 'Ο ΑΦΜ δεν είναι έγκυρος.';
add_action(
'woocommerce_init',
static function () use ( $document_label, $choices, $fields, $vat_error ) {
if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
return;
}
woocommerce_register_additional_checkout_field(
array(
'id' => 'snipfire/document',
'label' => $document_label,
'location' => 'order',
'type' => 'select',
'required' => true,
'options' => array_map(
static fn( $value, $label ) => array(
'value' => $value,
'label' => $label,
),
array_keys( $choices ),
$choices
),
)
);
// The invoice fields show, and are required, only when "invoice" is picked.
$not_invoice = array(
'checkout' => array(
'properties' => array(
'additional_fields' => array(
'properties' => array(
'snipfire/document' => array( 'not' => array( 'const' => 'invoice' ) ),
),
),
),
),
);
foreach ( $fields as $key => $label ) {
$field = array(
'id' => 'snipfire/invoice-' . $key,
'label' => $label,
'location' => 'order',
'type' => 'text',
'required' => true,
'hidden' => $not_invoice,
);
if ( 'vat' === $key ) {
// A Greek VAT number: 9 digits with a check digit ("EL" and spaces are fine).
$clean = static fn( $value ) => (string) preg_replace( '/^(EL|GR)/i', '', (string) preg_replace( '/[\s.\-]/', '', (string) $value ) );
$field['sanitize_callback'] = $clean;
$field['validate_callback'] = static function ( $value ) use ( $vat_error, $clean ) {
$vat = $clean( $value );
if ( '' === $vat ) {
return true;
}
$sum = 0;
for ( $i = 0; $i < 8 && preg_match( '/^\d{9}$/', $vat ); $i++ ) {
$sum += (int) $vat[ $i ] * ( 2 ** ( 8 - $i ) );
}
if ( ! preg_match( '/^\d{9}$/', $vat ) || '000000000' === $vat || ( $sum % 11 ) % 10 !== (int) $vat[8] ) {
return new WP_Error( 'snippet_gr_invalid_vat', $vat_error );
}
return true;
};
}
woocommerce_register_additional_checkout_field( $field );
}
}
);
Good to know
For the Checkout block (WooCommerce 9.9 or later). The fields appear under “Additional order information”. With the classic checkout use “Receipt or invoice at checkout” instead. The details are saved as the order’s additional fields (snipfire/document, snipfire/invoice-vat…).
In these packs
- Greek e-shop: For shops in Greece: receipt or invoice with a checked VAT number (ΑΦΜ), Greek phone and postcode checks, a cash on delivery fee, and greeklish addresses.