結帳流程
簡介
本範例示範如何在 AMP 中實作簡易結帳頁面。本範例假設所有付款處理都在伺服器端完成。涵蓋的使用案例包括
- 如何動態呈現購物車資料。
- 如何支援使用者使用已儲存的地址和信用卡登入。
- 如何讓使用者自動填寫聯絡方式、地址和信用卡資訊。
- 如何處理促銷/折扣碼。
設定
我們使用了許多組件
amp-form
用於收集和提交使用者輸入。
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
amp-access
用於使用者登入。
<script async custom-element="amp-access" src="https://cdn.ampproject.org/v0/amp-access-0.1.js"></script>
amp-analytics
是 amp-access
擴充功能所必需的。
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
amp-list
用於呈現個人化內容,例如購物車。
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
amp-mustache
用於搭配 amp-list
呈現範本。
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
amp-bind
用於根據使用者輸入動態更新頁面。
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
登入支援
我們使用 amp-access
整合登入功能,並根據使用者是否已登入來顯示和隱藏登入按鈕。amp-access 需要定義 3 個端點,如此處所述。
本範例允許使用者使用電子郵件/密碼或 Google 登入來登入和登出。登出是透過在登入屬性 sign-out
中設定第二個端點來實作,如此處所述。
<script id="amp-access" type="application/json">
{
"authorization": "/documentation/examples/api/amp-access/authorization?rid=READER_ID&url=CANONICAL_URL&ref=DOCUMENT_REFERRER&_=RANDOM",
"noPingback": "true",
"login": {
"sign-in": "/documentation/examples/api/amp-access/login?rid=READER_ID",
"sign-out": "/documentation/examples/api/amp-access/logout?rid=READER_ID"
},
"authorizationFallbackResponse": {
"error": true,
"loggedIn": false
}
}
</script>
amp-access
讓我們可以根據使用者是否已登入來顯示登入或登出按鈕,例如,標記為 amp-access="NOT loggedIn"
的元素只會針對未登入的使用者顯示。按鈕的點擊時動作,例如 on="tap:amp-access.login-sign-in"
,指定點擊按鈕時應採取的動作:login
定義 amp-access
JSON 設定中的屬性,而 sign-in
定義端點。
<div [hidden]="checkoutSuccess">
<button amp-access="NOT loggedIn" on="tap:amp-access.login-sign-in">Login</button>
<button amp-access="loggedIn" tabindex="0" on="tap:amp-access.login-sign-out" amp-access-hide>Logout</button>
<span amp-access="NOT loggedIn">...or continue as guest</span>
</div>
檢視訂單 (購物車)
檢視訂單區段會顯示目前的購物車內容和總價。我們從 JSON 端點提取購物車內容,並在 amp-list
內呈現。使用者是根據 AMP CLIENT_ID 來識別,並以
請求參數的形式傳遞。另一種可能性是使用 Cookie,如果設定了屬性 credentials="include"
,則 Cookie 會包含在 amp-list 的來源請求中。此外,我們將 amp-list 的 src
屬性繫結至隱含狀態物件 [src]="shoppingCart.src"
,我們使用它透過 amp-bind
重新整理內容。
檢視訂單
<section [hidden]="checkoutSuccess" class="checkout-section">
<h3>Review Order</h3>
<amp-list width="auto" height="180" items="." single-item layout="fixed-height" credentials="include" src="https://amp.dev.org.tw/documentation/examples/e-commerce/checkout_flow/shoppingcart?clientId=CLIENT_ID(cart)" [src]="shoppingCart.src" binding="no">
<template type="amp-mustache">
<div class="shopping-cart">
<div class="item header">
<div class="name"></div>
<div class="price"><strong>Price</strong></div>
<div class="quantity"><strong>Quantity</strong></div>
</div>
{{#items}}
<div class="item">
<div class="name">{{name}}</div>
<div class="price">${{price}}</div>
<div class="quantity">{{quantity}}x</div>
</div>
{{/items}}
{{#discount}}
<div class="item summary">
<div class="name"></div>
<div class="price"><strong>Discount:</strong></div>
<div class="quantity"><strong>{{.}}</strong></div>
</div>
{{/discount}}
<div class="item summary">
<div class="name"></div>
<div class="price"><strong>Sum:</strong></div>
<div class="quantity"><strong>${{total}}</strong></div>
</div>
</div>
</template>
</amp-list>
</section>
促銷/折扣碼
此區段可讓您輸入促銷或折扣碼。這是一個簡單的 amp-form
,會將
代碼張貼到 XHR 端點。如果表單已成功提交,我們會重新整理購物車
內容,方法是使用更新的 src URL 更新 shoppingCart
物件。我們附加一個隨機值來使任何快取失效並強制
重新整理。
新增促銷代碼
<section [class]="checkoutSuccess ? 'hide' : 'checkout-section'" class="checkout-section">
<h3> Add a promotional code </h3>
<form method="post" action-xhr="https://amp.dev.org.tw/documentation/examples/e-commerce/checkout_flow/apply-code" on="submit-success:AMP.setState({
shoppingCart: {
src: 'https://amp.dev.org.tw/documentation/examples/e-commerce/checkout_flow/shoppingcart?clientId=CLIENT_ID(cart)&' + random()
}
})" target="_top">
<input name="clientId" type="hidden" value="CLIENT_ID(cart)" data-amp-replace="CLIENT_ID">
<input name="code" placeholder="Code" aria-label="code" value="abc123">
<button value="Apply">Apply</button>
</form>
</section>
結帳表單
這是實際的結帳表單。表單提交透過 XHR 進行。表單成功提交後,我們會將
checkoutSuccess
變數設定為 true
。這讓我們可以在結帳完成後隱藏表單。另一個選項是在成功結帳後重新導向至新頁面。
<form id="checkout-form" method="post" [hidden]="checkoutSuccess" action-xhr="https://amp.dev.org.tw/documentation/examples/e-commerce/checkout_flow/apply-code" on="submit-success:AMP.setState({checkoutSuccess: true})" target="_top">
聯絡方式
未登入的使用者 (amp-access="NOT loggedIn"
) 會看到此區段以輸入聯絡方式。
聯絡方式
<section class="checkout-section" amp-access="NOT loggedIn">
<h3>Contact</h3>
<label for="frmNameA">Name</label>
<input name="name" id="frmNameA" placeholder="Full name" autocomplete="name">
<label for="frmEmailA">Email</label>
<input type="email" name="email" id="frmEmailA" placeholder="name@example.com" autocomplete="email">
</section>
運送與帳單地址
已登入的使用者 (amp-access="loggedIn"
) 可以選取現有的地址,這些地址是使用另一個 amp-list 提取的。此區段最初透過 amp-access-hide
屬性隱藏。
我們提供第三個選項,讓使用者輸入新地址。單選按鈕的 [change 動作](//documentation/guides-and-tutorials/learn/amp-actions-and-events) 會觸發地址表單的可見性 `on="change:manualShippingAddress.toggleVisibility"`。
選取運送地址
- {{#addresses}}
- {{^default}} {{/default}} {{#default}} {{/default}} {{/addresses}} {{#manual}}
- {{/manual}}
<section class="checkout-section" amp-access="loggedIn" amp-access-hide>
<h3>Select Shipping Address</h3>
<amp-list width="auto" height="96" layout="fixed-height" items="." single-item credentials="include" src="/static/samples/json/addresses.json" binding="no">
<template type="amp-mustache">
<ul class="list-reset">
{{#addresses}}
<li>
{{^default}}
<input type="radio" id="address{{id}}" name="address" value="{{id}}" on="change:manualShippingAddress.hide">
<label for="address{{id}}">{{name}}, {{street}}, {{city}} </label>
{{/default}}
{{#default}}
<input type="radio" checked id="defaultAddress{{id}}" name="address" value="{{id}}" on="change:manualShippingAddress.hide">
<label for="defaultAddress{{id}}">{{name}}, {{street}}, {{city}} {{#default}}<strong>[DEFAULT]</strong>{{/default}}</label>
{{/default}}
{{/addresses}}
</li>
{{#manual}}
<li>
<input type="radio" id="ship-separate" name="address" value="{{id}}" on="change:manualShippingAddress.toggleVisibility">
<label for="ship-separate">Enter new Shipping Address</label>
</li>
{{/manual}}
</ul>
</template>
</amp-list>
<section class="sub-section" id="manualShippingAddress" hidden>
<label for="manualShipAddressS">Address</label>
<input name="ship-address" id="manualShipAddressS" placeholder="123 Any Street" autocomplete="shipping street-address">
<label for="manualShipCityS">City</label>
<input name="ship-city" id="manualShipCityS" placeholder="New York" autocomplete="shipping locality">
<label for="manualShipStateS">State</label>
<input name="ship-state" id="manualShipStateS" placeholder="NY" autocomplete="shipping region">
<label for="manualShipZipS">Zip</label>
<input name="ship-zip" id="manualShipZipS" placeholder="10011" autocomplete="shipping postal-code">
<label for="manualShipCountryS">Country</label>
<input name="ship-country" id="manualShipCountryS" placeholder="USA" autocomplete="shipping country">
<label for="saveNewAddress1">Save Address</label>
<input id="saveNewAddress1" type="checkbox" checked on="change:shippingAddress.toggleVisibility">
</section>
<label for="shippingAddressCheck">Use Shipping as Billing Address</label>
<input id="shippingAddressCheck" type="checkbox" checked on="change:shippingAddress.toggleVisibility">
</section>
未登入的使用者會看到一個簡單的表單,用於輸入運送地址。我們使用 autocomplete
屬性
啟用 地址自動填寫功能,這大大簡化了使用者的表單填寫。
輸入運送地址
<section class="checkout-section" amp-access="NOT loggedIn">
<h3>Enter Shipping Address</h3>
<label for="shipAddressS">Address</label>
<input name="ship-address" id="shipAddressS" placeholder="123 Any Street" autocomplete="shipping street-address">
<label for="shipCityS">City</label>
<input name="ship-city" id="shipCityS" placeholder="New York" autocomplete="shipping locality">
<label for="shipStateS">State</label>
<input name="ship-state" id="shipStateS" placeholder="NY" autocomplete="shipping region">
<label for="shipZipS">Zip</label>
<input name="ship-zip" id="shipZipS" placeholder="10011" autocomplete="shipping postal-code">
<label for="shipCountryS">Country</label>
<input name="ship-country" id="shipCountryS" placeholder="USA" autocomplete="shipping country">
<label for="shippingAddressCheck">Use Shipping as Billing Address</label>
<input type="checkbox" checked on="change:shippingAddress.toggleVisibility">
</section>
運送地址表單是選填的。我們最初使用 hidden
屬性隱藏它,以便可以透過
toggleVisibility
動作 (on="change:shippingAddress.toggleVisibility"
) 切換其可見性。
輸入帳單地址
<section class="checkout-section" hidden id="billingAddress">
<h3>Enter Billing Address</h3>
<label for="billingAddressS">Address</label>
<input name="billing-address" id="billingAddressS" placeholder="123 Any Street" autocomplete="billing street-address">
<label for="billingCityS">City</label>
<input name="billing-city" id="billingCityS" placeholder="New York" autocomplete="billing locality">
<label for="billingStateS">State</label>
<input name="billing-state" id="billingStateS" placeholder="NY" autocomplete="billing region">
<label for="billingZipS">Zip</label>
<input name="billing-zip" id="billingZipS" placeholder="10011" autocomplete="billing postal-code">
<label for="billingCountryS">Country</label>
<input name="billing-country" id="billingCountryS" placeholder="USA" autocomplete="billing country">
</section>
付款資訊
已登入的使用者 (amp-access="loggedIn"
) 可以選取現有的信用卡,其提取方式與上述動態呈現運送地址的方式類似,都是使用 amp-list
。也可以手動輸入信用卡資訊。
選取付款資訊
- {{#cards}}
- {{^default}}{{/default}} {{#default}}{{/default}}{{/cards}} {{#manual}}
- {{/manual}}
<section class="checkout-section" amp-access="loggedIn" amp-access-hide>
<h3>Select Payment Details</h3>
<amp-list width="auto" height="96" layout="fixed-height" items="." single-item credentials="include" src="/static/samples/json/credit-cards.json" binding="no">
<template type="amp-mustache">
<ul class="list-reset">
{{#cards}}
<li>
{{^default}}
<input type="radio" id="cc{{id}}" name="cc" value="{{id}}" on="change:manualCC.hide">
{{/default}}
{{#default}}
<input type="radio" checked id="defaultCC{{id}}" name="cc" value="{{id}}" on="change:manualCC.hide">
{{/default}}
<label for="defaultCC{{id}}">{{title}} {{#default}}<strong>[DEFAULT]</strong>{{/default}}</label>
{{/cards}}
</li>
{{#manual}}
<li>
<input type="radio" id="new-cc" name="cc" value="{{id}}" on="change:manualCC.toggleVisibility">
<label for="new-cc">Enter new Credit Card</label>
</li>
{{/manual}}
</ul>
</template>
</amp-list>
<section class="sub-section" id="manualCC" hidden>
<label for="manualCCNameCC">Name on card</label>
<input name="ccname" id="manualCCNameCC" placeholder="Full Name" autocomplete="cc-name">
<label for="manualCCCCNum">Card Number</label>
<input name="cardnumber" id="manualCCCCNum" autocomplete="cc-number">
<label for="manualCCCVC">CVC</label>
<input name="cvc" id="manualCCCVC" autocomplete="cc-csc">
<label for="manualCCExp">Expiry</label>
<input name="cc-exp" id="manualCCExp" placeholder="MM-YYYY" autocomplete="cc-exp">
<label for="saveNewAddress2">Save Credit Card</label>
<input id="saveNewAddress2" type="checkbox" checked on="change:shippingAddress.toggleVisibility">
</section>
</section>
未登入的使用者可以手動輸入信用卡資訊。請注意,我們正在使用信用卡自動填寫標記。
輸入信用卡資訊
<section class="checkout-section" amp-access="NOT loggedIn" amp-access-hide>
<h3>Enter Credit Card Details</h3>
<label for="nameCC">Name on card</label>
<input name="ccname" id="nameCC" placeholder="Full Name" autocomplete="cc-name">
<label for="ccNum">Card Number</label>
<input name="cardnumber" id="ccNum" autocomplete="cc-number">
<label for="ccCVC">CVC</label>
<input name="cvc" id="ccCVC" autocomplete="cc-csc">
<label for="ccExp">Expiry</label>
<input name="cc-exp" id="ccExp" placeholder="MM-YYYY" autocomplete="cc-exp">
</section>
表單提交
立即付款按鈕只會提交包含不同結帳表單區段的表單。
<div [hidden]="checkoutSuccess">
<input type="submit" value="Pay Now">
<span>Not for real ...</span>
</div>
這是我們在成功結帳且 checkoutSuccess
變數設定為 true
後將顯示的訊息。
結帳成功!
<section hidden [hidden]="checkoutSuccess" class="checkout-section">
<h3>Checkout success!</h3>
</section>
如果本頁面的說明未涵蓋您的所有問題,請隨時與其他 AMP 使用者聯繫,討論您的確切使用案例。
前往 Stack Overflow 有未說明的特色功能嗎?AMP 專案非常鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的長期參與者,但我們也歡迎您針對您特別感興趣的問題做出一次性貢獻。
在 GitHub 上編輯範例-
作者: @sebastianbenz