AMP
  • 网站

结账流程

简介

此示例演示如何在 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-analyticsamp-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.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"`。

选择送货地址

<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 拉取的现有信用卡,类似于动态渲染上述送货地址的方式。也可以手动输入信用卡详细信息。

选择付款明细

<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 对 自定义表单验证 的支持轻松添加此功能。

需要进一步解释吗?

如果此页面上的解释未涵盖您的所有问题,请随时联系其他 AMP 用户以讨论您的确切用例。

转到 Stack Overflow
无法解释的功能?

AMP 项目强烈鼓励您的参与和贡献!我们希望您成为我们开源社区的持续参与者,但我们也欢迎您对您特别热衷的问题做出一次性贡献。

在 GitHub 上编辑示例