VbzCart/docs/pieces/checkout: Difference between revisions

From Woozle Writes Code
< VbzCart‎ | docs‎ | pieces
Jump to navigation Jump to search
imported>Woozle
m (Woozle moved page VbzCart/VbzCart/pieces/checkout to VbzCart/docs/pieces/checkout without leaving a redirect: correct naming (was no way to import directly to this name))
 
(5 intermediate revisions by one other user not shown)
Line 1: Line 1:
''see also [[../../coding/checkout|coding/checkout]]''
==About==
==About==
The checkout subsystem handles customer interaction from the point when the customer presses "check out" on the shopping cart up to the point where the order is placed ("finish" button in old system).
The checkout subsystem handles customer interaction from the point when the customer presses "check out" on the shopping cart up to the point where the order is placed ("finish" button in old system).
===Requirements===
==Requirements==
* Record shipping information
* Record shipping information
* Record payment information
* Record payment information
* Prevent customer from proceeding if required fields are missing or contain invalid data
** Allow customer to indicate that payment address is same as shipping.
* Send notification email to customer and store when order is placed
* Prevent customer from proceeding if required fields are missing or contain invalid data.
==Code Flow==
* Keep records of customer information as entered and also as interpreted for order processing.
===Form Render===
* Send notification email to customer and store when order is placed.
* '''page/vbz-page-ckout.php''' class vcPageCkout protected function '''RenderShippingPage()'''
** Present customer with printable/saveable receipt.
** '''cart/cart-shop.php''' vcrCart_ShopUI public function '''RenderShippingPage()'''
==Process==
*** $oCDMgr = $this->FieldsManager();
*** $oCDMgr->FetchBlob();
*** $oCD_Buyer = $oCDMgr->BuyerObject();
*** $oCD_Recip = $oCDMgr->RecipObject();
*** $oCD_Buyer->RenderContact(TRUE) // edit email/phone
**** '''cart/cart.data.fg-ep.php''' trait vtCartData_EmailPhone public function '''RenderContact()'''
*** $oCD_Recip->RenderShipping(TRUE) // edit shipping address / instructions
**** '''cart/cart.data.fg.recip.php''' class vcCartData_Recip public function '''RenderShipping()'''
***** $this->LoadShippingFields();
* '''page/vbz-page-ckout.php''' class vcPageCkout protected function '''RenderBillingPage()'''
** '''cart/cart-shop.php''' vcrCart_ShopUI public function '''RenderBillingPage()'''
*** $oCDMgr = $this->FieldsManager();
*** $oCD_Buyer = $oCDMgr->BuyerObject();
*** $oCD_Buyer->RenderPayment(TRUE) // edit payment information
**** '''cart/cart.data.fg.buyer.php''' class vcCartData_Buyer public function '''RenderPayment()'''
 
===Form Capture===
* '''page/vbz-page-ckout.php''': class clsPageCkout function '''CapturePage()'''
** '''page/vbz-page-ckout.php''': class clsPageCkout function '''CaptureShipping()'''
*** $rcCart->CaptureShippingPage();
**** '''cart/cart.shop.php''': class vcrCart_ShopUI function '''CaptureShippingPage()'''
***** $oCD_Buyer->CaptureContact();
***** $oCD_Recip->CaptureShipping();
****** '''cart/cart.data.fg-na.php''': trait vtCartData_NameAddress function '''CaptureShipping()'''
******* $this->InvokeNameAddressFields();
******* $this->ReceiveForm();
***** $oCDMgr->FetchBlob();
****** '''cart/cart.data.mgr.php''': class vcCartDataManager function '''FetchBlob()'''
******* $sBlob = $this->GetBlobString();
******* $this->SetBlobArray(...)
***** $oCDMgr->UpdateBlob($oCD_Buyer);
***** $oCDMgr->UpdateBlob($oCD_Recip);
***** $oCDMgr->StoreBlob();
****** '''cart/cart.data.mgr.php''': class vcCartDataManager function '''StoreBlob()'''
******* $sBlob = serialize($this->GetBlobArray());
******* $this->SetBlobString($sBlob);
** '''page/vbz-page-ckout.php''': class clsPageCkout function '''CaptureBilling()'''
*** $rcCart->CaptureBillingPage();
**** '''cart/cart.shop.php''': class vcrCart_ShopUI function '''CaptureBillingPage()'''
***** $oCD_Buyer = $oCDMgr->BuyerObject();
***** $oCD_Buyer->CapturePayment(); // card #/exp, and I *think* name/address
***** $this->AddMissing($oCD_Buyer->GetMissingArray());
***** $oCDMgr->FetchBlob();
****** '''cart/cart.data.mgr.php''': class vcCartDataManager function '''FetchBlob()'''
******* $sBlob = $this->GetBlobString();
******* $this->SetBlobArray(...)
***** $oCDMgr->UpdateBlob($oCD_Buyer);
***** $oCDMgr->StoreBlob();
****** '''cart/cart.data.mgr.php''': class vcCartDataManager function '''StoreBlob()'''
******* $sBlob = serialize($this->GetBlobArray());
******* $this->SetBlobString($sBlob);
***** $this->Save();
 
 
InvokeNameAddressFields() defines which fields are handled.
 
===Conversion===
===Conversion===
Converting the cart data to order data seems to be one of the trickiest parts to get right.
Converting the cart data to order data seems to be one of the trickiest parts to get right.


Revised code flow:
Basically, the Cart object now supervises the creation of new records as needed. Customer objects just create customer records, not address or name or whatever.
* '''cart/cart.logic.php''': function ToOrder_Data(clsOrder $rcOrd)
===Navigation===
** $tCust->CreateRecord_fromContact($idUser,$oBuyer);
We'll treat the shopping cart as being Page 0 of the checkout process, even though it's handled by a different page class, because it is part of the checkout navigation flow i.e. from Page 1, the "back" button takes you back to the shopping cart page.
** $tCust->CreateRecord_fromContact($idUser,$oRecip);


Basically, the Cart object now supervises the creation of new records as needed. Customer objects just create customer records, not address or name or whatever.
It looks like the best way to handle form navigation is to have constant control names for the "back" and "next" buttons and to include the name of the submitting form in a hidden field.<ref name=navbtns />


===Navigation===
Where form data does not need to be saved, switching modes for a given page can be done with a clickable link rather than a button.
It looks like the best way to handle form navigation is to have constant control names for the "back" and "next" buttons and to include the name of the submitting form in a hidden field.
* '''{{l/sub|page 0}}''': shopping cart - handled by a different Page class, but can be navigated to from here (i.e. pressing the "back" button on Page 1)
** '''output''': <code>RenderCart()</code>
* '''{{l/sub|page 1}}''': shipping info
* '''{{l/sub|page 2}}''': payment info
** '''input''': <code>CaptureBilling()</code>
* '''{{l/sub|page 3}}''': confirmation
* '''{{l/sub|page 4}}''': take action, provide receipt


For the 2009 rewrite, I initially tried to have the "back" and "next" buttons specify the target form, removing the need for the submitting-form-identifier, but this causes problems under the following circumstances:
I/O functions are handled by the <code>vcPageContent_ckout</code> class.
==Related Pages==
* [[/archive]]: outdated stuff
==Footnote==
<references>
<ref name=navbtns>For the 2009 rewrite, I initially tried to have the "back" and "next" buttons specify the target form, removing the need for the submitting-form-identifier, but this causes problems under the following circumstances:
* determining if the user should be allowed to load the requested form when required fields in the current form have been left empty:
* determining if the user should be allowed to load the requested form when required fields in the current form have been left empty:
** If the user is moving forward, then NO - the submitting form should be re-displayed with a message listing the missing fields
** If the user is moving forward, then NO - the submitting form should be re-displayed with a message listing the missing fields
Line 87: Line 42:
** If this page has been submitted previously, then the stored data should be checked
** If this page has been submitted previously, then the stored data should be checked
** If this page is being re-loaded because the user requested a forward move while leaving one or more required fields blank, then the submitted data must be checked (this rule can be simplified by storing it first and then always checking stored data)
** If this page is being re-loaded because the user requested a forward move while leaving one or more required fields blank, then the submitted data must be checked (this rule can be simplified by storing it first and then always checking stored data)
 
</ref>
==Related Pages==
</references>
* [[/archive]]: outdated stuff

Latest revision as of 01:53, 25 February 2024

see also coding/checkout

About

The checkout subsystem handles customer interaction from the point when the customer presses "check out" on the shopping cart up to the point where the order is placed ("finish" button in old system).

Requirements

  • Record shipping information
  • Record payment information
    • Allow customer to indicate that payment address is same as shipping.
  • Prevent customer from proceeding if required fields are missing or contain invalid data.
  • Keep records of customer information as entered and also as interpreted for order processing.
  • Send notification email to customer and store when order is placed.
    • Present customer with printable/saveable receipt.

Process

Conversion

Converting the cart data to order data seems to be one of the trickiest parts to get right.

Basically, the Cart object now supervises the creation of new records as needed. Customer objects just create customer records, not address or name or whatever.

Navigation

We'll treat the shopping cart as being Page 0 of the checkout process, even though it's handled by a different page class, because it is part of the checkout navigation flow i.e. from Page 1, the "back" button takes you back to the shopping cart page.

It looks like the best way to handle form navigation is to have constant control names for the "back" and "next" buttons and to include the name of the submitting form in a hidden field.[1]

Where form data does not need to be saved, switching modes for a given page can be done with a clickable link rather than a button.

  • page 0: shopping cart - handled by a different Page class, but can be navigated to from here (i.e. pressing the "back" button on Page 1)
    • output: RenderCart()
  • page 1: shipping info
  • page 2: payment info
    • input: CaptureBilling()
  • page 3: confirmation
  • page 4: take action, provide receipt

I/O functions are handled by the vcPageContent_ckout class.

Related Pages

Footnote

  1. For the 2009 rewrite, I initially tried to have the "back" and "next" buttons specify the target form, removing the need for the submitting-form-identifier, but this causes problems under the following circumstances:
    • determining if the user should be allowed to load the requested form when required fields in the current form have been left empty:
      • If the user is moving forward, then NO - the submitting form should be re-displayed with a message listing the missing fields
      • If the user is moving backward, then YES - the requested form should be displayed regardless
    • determining the status of the data on the target page, so as to display the proper status message (indicating what fields, if any, are missing):
      • If this page has never been submitted, then no message should be displayed
      • If this page has been submitted previously, then the stored data should be checked
      • If this page is being re-loaded because the user requested a forward move while leaving one or more required fields blank, then the submitted data must be checked (this rule can be simplified by storing it first and then always checking stored data)