Custom Order Customer Form

In some cases you may wish to use your own customer form to capture customer details at checkout. At a minimum, your form needs to capture the customer's email address and country information. Everything else is optional.

In order to process customer details for the order, Padloper needs to know about your form. You need to tell it the names and types of the inputs in the form and how they map to the expected inbuilt customer fields for an order.

TIP

You can hook into form submission process if you want to process custom details not required by Padloper, for instance, asking customers to opt in to a newsletter subscription.

You tell Padloper about your custom form by passing an $options argument to $padloper->checkout()->render($options).

Supported Form Inputs

The following form inputs are supported in your custom form. The inputs with the specified names will be processed and saved in the order customer details alongside the order. The input tpes are shown in parentheses. However, you can change some of them and indicate the type in the array of $options passed to $padloper->checkout()->render($options). Please see the example below.

WARNING

Email and customer country are required form inputs.

You can make other inputs required if desired. Please see the example below this table.

Input NameDescription
firstNameCustomer's first name (text).
middleNameCustomer's middle name (text).
lastNameCustomer's last name (text).
emailCustomer's email (email).
shippingAddressFirstNameCustomer shipping address first name (text).
shippingAddressMiddleNameCustomer shipping address middle name (text).
shippingAddressLastNameCustomer shipping address last name (text).
shippingAddressPhoneCustomer shipping address phone (text).
shippingAddressCompanyCustomer shipping address company name (text).
shippingAddressLineOneFirst line of customer shipping address (text).
shippingAddressLineTwoSecond line of customer shipping address (text).
shippingAddressCityShipping address city (text).
shippingAddressRegionShipping address region/state/province (text).
shippingAddressCountryShipping address country (integer with country ID matching a country page in Padloper).
shippingAddressPostalCodeShipping Address Postal/Zip Code (text).
billingAddressFirstNameCustomer billing address first name (text).
billingAddressMiddleNameCustomer billing address middle name (text).
billingAddressLastNameCustomer billing address last name (text).
billingAddressPhoneCustomer billing address phone (text).
billingAddressCompanyCustomer billing address company name (text).
billingAddressLineOneFirst line of customer billing address (text).
billingAddressLineTwoSecond line of customer billing address (text).
billingAddressCityBilling address city (text).
billingAddressRegionBilling address region/state/province (text).
billingAddressCountryBilling address country (integer with country ID matching a country page in Padloper).
billingAddressPostalCodeBilling Address Postal/Zip Code (text).

Example Custom Customer Form

The code below should be placed in your checkout template file. This is the file your created when you set up the checkout process.

namespace ProcessWire;

$checkout = $padloper->checkout;
// for comparison only. These no longer in use in this format in Padloper
// $checkout = $modules->get("PadCheckout"); // This is the old one, use above for most streamlined checkout
// @see notes below: Padloper utilises Shipping zones. Shipping will be automatically calculated based on matched shipping rates in matched shipping zone.
// @todo: delete when done; no longer in use
// $checkout->setShippingModule("ShippingFixed"); // This means that all orders will use this specific

/*
 @note:
 - EXAMPLE OF HOW TO PROCESS A CUSTOM ORDER CUSTOMER FORM
 - Padloper also ships with an inbuilt form similar to Padloper 1
 - The inbuilt form utilises ProcessWire Inputfields
 - Not everyone prefers that due to CSS styling issues
 - Both the inbuilt and the custom form processors will validate the form
 - The inbuilt one will utilise ProcessWire $form->getErrors()
 - IF YOUR FORM USES CUSTOM NAMES FOR ITS INPUT, you will need to indicate this + provide a 'schema' for input matching
 - The NAMES of the INPUT must match what Padloper Expects. Please see below for examples as well as the documentation
 - The custom form processor will need the schema of the custom form passed to it
 - e.g.:

 	$customFormFieldsExampleArray = [
			[
				// the name of the input of the custom form {must match Padloper expected names}
				'input_name' => 'email',
				// the input type (for sanitization)
				'type' => 'email',
				// if field/input is required
				'required' => true
			],
			[
				// customer first name 'firstName'
				'input_name' => 'firstName',
				'type' => 'text',
				'required' => false // can be left out
			],

		];

		// @note: the payment class input names do not have aliases. They need to be used as is, i.e.
		'padloper_order_payment_id'
		// @note: shipping is handled using Shipping Zones in Padloper. There is no need to select a shipping method
		in a future release, customers will be able to select shipping rate if more than one shipping rate has been matched
		e.g. standard delivery - 7.99; express delivery 13.50, etc.

*/

$customFormFields = [
	// first name
	[
		// the name of the input of the custom form
		'input_name' => 'firstName',
		// the input type (for sanitization)
		// @todo: @note: for selects and checkbox, use the expected value type
		'type' => 'text',
		// if field/input is required
		'required' => true
	],
	// last name
	[
		'input_name' => 'lastName',
		'type' => 'text',
		'required' => true
	],
	// email
	[
		'input_name' => 'email',
		'type' => 'email',
		'required' => true
	],
	// address line one
	[
		'input_name' => 'shippingAddressLineOne',
		'type' => 'text',
		'required' => true
	],
	// address line two
	[
		'input_name' => 'shippingAddressLineTwo',
		'type' => 'text',
	],
	// city/town
	[
		'input_name' => 'shippingAddressCity',
		'type' => 'text',
		'required' => true
	],
	// postcode
	[
		'input_name' => 'shippingAddressPostalCode',
		'type' => 'text',
		'required' => true
	],
	// country
	[
		'input_name' => 'shippingAddressCountry',
		// @note: country ID, hence integer!
		'type' => 'integer',
		'required' => true
	],
	// region/state/province
	[
		'input_name' => 'shippingAddressRegion',
		'type' => 'text'
	],
	// ------------------------

	// SPECIAL (NON-ALIASED)
	// PAYMENT TYPE/CLASS
	// @todo: @note: name might change!
	[
		'input_name' => 'padloper_order_payment_id',
		'type' => 'integer',
		'required' => true
	],

];

// -------------
// Primary content
$content = "";
$formErrors = [];
$previousValues = null;
$sectionHeader = __("Continue Shopping");
$sectionURL = "/products/";
$isShowSectionBackArrow = true;
$isShowCart = false;
$isCustomForm = true;

// options for render()
// ----------------
$options = [
		// determines if to output internal form using renderForm() vs dev using custom form
		'is_custom_form' => $isCustomForm,
		// will hold schema for form inputs if custom form will be used
		'custom_form_fields' => $customFormFields,
		// when custom form is used, will it use custom input names or identical names to internal form
		'is_use_custom_form_input_names' => true

];

// ----------
// @TODO: @NOTE: JUST SHOWING HOW TO USE INBUILT VS CUSTOM FORM
// YOU WOULDN'T NEED THIS CHECK IF YOU KNEW YOU ARE USING A CUSTOM FORM :-)
if (!empty($isCustomForm)) {
		// FOR CUSTOM FORMS, THE RESPOSE IS A WIREDATA OBJECT
/** @var WireData $response */
		$response = $checkout->render($options);

		// @NOTE: renderCheckoutForm() is a custom function in this example
		// it returns a custom order form

		// handle errors
		if (!empty($response->errors)) {
				$formErrors = $response->errors;
				$previousValues = $response->previousValues;
				// -----------
				$content .= renderCheckoutForm($formErrors, $previousValues);
		} elseif (!empty($response->isProcessedForm)) {
				// @note: this will be result of renderConfirmation, success, etc when using custom form
				$content .= $response->content;
		} else {
				// initial render of custom form
				$content .= renderCheckoutForm($formErrors, $previousValues);
		}
		// ---------
} else {
		// @note: left here for comparison. In this demo, we use a custom form. Below would utilise the inbuit ProcessWire form
		$content .= $checkout->render();
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

You are now ready to start testing your order checkout form.