结账流程
简介
此示例演示了如何在 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 进行标识,该 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.org.cn/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.org.cn/documentation/examples/e-commerce/checkout_flow/apply-code" on="submit-success:AMP.setState({
shoppingCart: {
src: 'https://amp.org.cn/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.org.cn/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
属性隐藏。
我们为用户提供了第三个选项来输入新地址。单选按钮的 [更改操作](/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