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 Name | Description |
---|---|
firstName | Customer's first name (text). |
middleName | Customer's middle name (text). |
lastName | Customer's last name (text). |
Customer's email (email). | |
shippingAddressFirstName | Customer shipping address first name (text). |
shippingAddressMiddleName | Customer shipping address middle name (text). |
shippingAddressLastName | Customer shipping address last name (text). |
shippingAddressPhone | Customer shipping address phone (text). |
shippingAddressCompany | Customer shipping address company name (text). |
shippingAddressLineOne | First line of customer shipping address (text). |
shippingAddressLineTwo | Second line of customer shipping address (text). |
shippingAddressCity | Shipping address city (text). |
shippingAddressRegion | Shipping address region/state/province (text). |
shippingAddressCountry | Shipping address country (integer with country ID matching a country page in Padloper). |
shippingAddressPostalCode | Shipping Address Postal/Zip Code (text). |
billingAddressFirstName | Customer billing address first name (text). |
billingAddressMiddleName | Customer billing address middle name (text). |
billingAddressLastName | Customer billing address last name (text). |
billingAddressPhone | Customer billing address phone (text). |
billingAddressCompany | Customer billing address company name (text). |
billingAddressLineOne | First line of customer billing address (text). |
billingAddressLineTwo | Second line of customer billing address (text). |
billingAddressCity | Billing address city (text). |
billingAddressRegion | Billing address region/state/province (text). |
billingAddressCountry | Billing address country (integer with country ID matching a country page in Padloper). |
billingAddressPostalCode | Billing 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();
}
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.