首页 > web前端 > js教程 > 正文

使用 Stripe 和 Netlify 功能构建自定义运费计算器,以支持多货币 (€/$)、数量和位置

Susan Sarandon
发布: 2024-11-01 17:11:02
原创
968 人浏览过

提交 3c90066

在您继续阅读之前,仅供参考,我自己学习和编码来构建我们运营业务所需的内容。因此,请按原样获取以下信息。这是我们自己使用的现实世界的例子吗?关于联合办公的黄皮书。当时我们找不到更好的解决方案,所以我为我们的电子商务网站构建了以下内容。

Building a Custom Shipping Calculator with Stripe and Netlify Functions for Multi-Currency (€/$), Quantity, and Location Support

在线销售单一产品(例如一本书)可以很简单,直到您遇到国际运费、多种货币和不同数量的复杂性 - 特别是因为 Stripe Checkout 默认情况下只允许一种运费。在本文中,我们将介绍如何使用 Netlify Functions 和 Stripe 构建自定义运费计算器来应对这些挑战。最后,您将拥有一个专为销售最多三本图书而定制的可行解决方案,并根据客户的货币(欧元/美元)、数量动态运输成本,以及位置

虽然这个示例非常适合我们的需求,但您可以对其进行调整以满足您自己的要求。请随时分享您的解决方案、升级或所做的任何改进。

?先决条件

在我们深入之前,请确保您具备以下条件:

  • 已部署站点的 Netlify 帐户。
  • 具有测试和实时 API 密钥的 Stripe 帐户。
  • 对 HTML、JavaScript 和无服务器函数有基本了解。
  • 熟悉环境变量。

?概述

让我们打造无缝结账体验:

  • 根据客户的货币商品数量位置确定运费。
  • 支持欧元和美元货币。
  • 处理欧洲和全球目的地的不同运费。
  • 与 Stripe Checkout 无缝集成。

下面我将介绍前端(HTML 和 JavaScript)和后端(Netlify 函数)组件。

?项目结构

项目应包含以下文件夹和文件:

/functions
  - create-checkout-session.js
/index.html
.env
netlify.toml
package.json
登录后复制
登录后复制
登录后复制
  • /functions:Netlify 函数目录。
  • create-checkout-session.js:自定义无服务器函数。
  • index.html:前端 HTML 文件。
  • .env:存储环境变量的文件
  • netlify.toml:Netlify 的配置文件。
  • package.json:列出像 stripe 这样的依赖项。

?️ 设置后端(Netlify 功能)

在 /functions 目录中创建一个名为 create-checkout-session.js 的新文件。

/functions
  - create-checkout-session.js
/index.html
.env
netlify.toml
package.json
登录后复制
登录后复制
登录后复制

?代码分解

导入条纹

// functions/create-checkout-session.js

// Add Stripe secret key
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

exports.handler = async (event) => {
  // Parse the order data sent from the frontend
  const order = JSON.parse(event.body);

  // Define country groups
  const euCountries = ['AL', 'AM', 'AT', ...]; // Add the EU countries you ship to
  const worldCountries = ['AE', 'AR', 'AU', ...]; // Add worldwide countries you ship to
  let allowedCountries = [];

  // Payment methods based on currency
  let paymentMethods = [];

  // Determine shipping rates and allowed countries
  if (order.currency === 'EUR') {
    paymentMethods = ['card', 'sepa_debit', 'ideal', 'bancontact', 'p24', 'eps', 'giropay', 'sofort'];

    if (order.shippingOption === 'europe-eur') {
      allowedCountries = euCountries;
      // Set shipping rate IDs for Europe in EUR
      order.shippingRate = process.env[`SHIPPING_RATE_EUR_EU_${order.items}`];
    } else if (order.shippingOption === 'world-eur') {
      allowedCountries = worldCountries;
      // Set shipping rate IDs for World in EUR
      order.shippingRate = process.env[`SHIPPING_RATE_EUR_W_${order.items}`];
    }
  } else if (order.currency === 'USD') {
    paymentMethods = ['card'];

    if (order.shippingOption === 'europe-usd') {
      allowedCountries = euCountries;
      // Set shipping rate IDs for Europe in USD
      order.shippingRate = process.env[`SHIPPING_RATE_USD_EU_${order.items}`];
    } else if (order.shippingOption === 'world-usd') {
      allowedCountries = worldCountries;
      // Set shipping rate IDs for World in USD
      order.shippingRate = process.env[`SHIPPING_RATE_USD_W_${order.items}`];
    }
  }

  // Create the Stripe Checkout session
  const session = await stripe.checkout.sessions.create({
    payment_method_types: paymentMethods,
    line_items: [
      {
        price: order.priceId, // The price ID of your product
        quantity: order.items,
      },
    ],
    mode: 'payment',
    billing_address_collection: 'auto',
    shipping_rates: [order.shippingRate],
    shipping_address_collection: {
      allowed_countries: allowedCountries,
    },
    success_url: `${process.env.URL}/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.URL}/cancel`,
  });

  return {
    statusCode: 200,
    body: JSON.stringify({
      sessionId: session.id,
      publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
    }),
  };
};
登录后复制
登录后复制

使用您的密钥初始化 Stripe SDK。

处理事件

解析前端传入的订单数据。

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
登录后复制
登录后复制

定义国家组

exports.handler = async (event) => {
  const order = JSON.parse(event.body);
  // Rest of the code...
};
登录后复制
登录后复制
  • 欧盟和全球航运国家/地区列表。
  • allowedCountries 将根据运送选项进行设置。

设置付款方式

根据币种确定可用的付款方式。

const euCountries = [/* ... */];
const worldCountries = [/* ... */];
let allowedCountries = [];
登录后复制

确定运费

let paymentMethods = [];
登录后复制
  • 使用环境变量根据货币、区域和数量设置正确的运费 ID。
  • 环境变量示例:SHIPPING_RATE_EUR_EU_1 表示欧洲 1 件商品使用欧元货币。

创建结账会话

if (order.currency === 'EUR') {
  paymentMethods = [/* ... */];

  if (order.shippingOption === 'europe-eur') {
    allowedCountries = euCountries;
    order.shippingRate = process.env[`SHIPPING_RATE_EUR_EU_${order.items}`];
  } else if (order.shippingOption === 'world-eur') {
    allowedCountries = worldCountries;
    order.shippingRate = process.env[`SHIPPING_RATE_EUR_W_${order.items}`];
  }
} else if (order.currency === 'USD') {
  // Similar logic for USD
}
登录后复制
  • 使用动态配置创建新的 Stripe Checkout 会话。

?️ 设置前端

下面是与我们的 Netlify 函数交互的 HTML 和 JavaScript 代码的简短示例。

? HTML 结构 (index.html)

const session = await stripe.checkout.sessions.create({
  payment_method_types: paymentMethods,
  line_items: [/* ... */],
  mode: 'payment',
  billing_address_collection: 'auto',
  shipping_rates: [order.shippingRate],
  shipping_address_collection: {
    allowed_countries: allowedCountries,
  },
  success_url: `${process.env.URL}/success?session_id={CHECKOUT_SESSION_ID}`,
  cancel_url: `${process.env.URL}/cancel`,
});
登录后复制

? HTML 细分

  • 货币选项卡:允许用户在欧元和美元定价之间进行选择。
  • 书籍数量:用户最多可以选择三本书。
  • 运送目的地:下拉列表中填充了国家/地区,按运费分组。
  • 结帐按钮:单击时启动结帐过程。

? JavaScript 逻辑 (script.js)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Book Pre-Order</title>
  <!-- Include any CSS or Meta tags here -->
</head>
<body>
  <!-- Book Purchase Section -->
  <section id="pricing">
    <div class="pricing-content">
      <!-- Currency Tabs -->
      <ul class="tabs-menu">
        <li id="active_currency_eur" class="current"><a href="#tab-1">Buy in ?? EUR</a></li>
        <li id="active_currency"><a href="#tab-2">Buy in ?? USD</a></li>
      </ul>

      <!-- EUR Tab Content -->
      <div id="tab-1" class="tab-content">
        <h3>1 Print Book</h3>
        <p>A beautiful, 350 pages book.</p>
        <p>Price: <span id="book-price-eur">€95</span></p>

        <!-- Number of Books -->
        <label for="num-books">Number of Books (Max 3)</label>
        <select name="num-books" id="num-books" required>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>

        <!-- Shipping Destination -->
        <label for="shipping-amount-eur">Select Shipping Destination</label>
        <select name="shipping-amount" id="shipping-amount-eur" required>
          <optgroup label="Europe €14">
            <option value="europe-eur">Austria</option>
            <option value="europe-eur">Belgium</option>
            <!-- Add other European countries -->
          </optgroup>
          <optgroup label="Worldwide €22">
            <option value="world-eur">United States</option>
            <option value="world-eur">Canada</option>
            <!-- Add other worldwide countries -->
          </optgroup>
        </select>

        <!-- Checkout Button -->
        <button id="checkout-button-eur" type="button">PRE-ORDER</button>
      </div>

      <!-- USD Tab Content -->
      <div id="tab-2" class="tab-content">
        <h3>1 Print Book</h3>
        <p>A beautiful, 350 pages book.</p>
        <p>Price: <span id="book-price-usd"></span></p>

        <!-- Number of Books -->
        <label for="num-books-usd">Number of Books (Max 3)</label>
        <select name="num-books-usd" id="num-books-usd" required>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>

        <!-- Shipping Destination -->
        <label for="shipping-amount-usd">Select Shipping Destination</label>
        <select name="shipping-amount" id="shipping-amount-usd" required>
          <optgroup label="Europe ">
            <option value="europe-usd">Austria</option>
            <option value="europe-usd">Belgium</option>
            <!-- Add other European countries -->
          </optgroup>
          <optgroup label="Worldwide ">
            <option value="world-usd">United States</option>
            <option value="world-usd">Canada</option>
            <!-- Add other worldwide countries -->
          </optgroup>
        </select>

        <!-- Checkout Button -->
        <button id="checkout-button-usd" type="button">PRE-ORDER</button>
      </div>
    </div>
  </section>

  <!-- Include Stripe.js -->
  <script src="https://js.stripe.com/v3/"></script>

  <!-- Include your JavaScript file -->
  <script src="script.js"></script>
</body>
</html>
登录后复制

? JavaScript 细分

  • 事件监听器:将点击事件附加到结帐按钮。
  • 确定订单详细信息:根据单击的按钮,提取货币、运输选项、书籍数量和价格 ID。
  • 准备订单数据:创建一个包含所有必要订单信息的对象。
  • 获取结帐会话:使用订单数据向 Netlify 函数发送 POST 请求。
  • 重定向到 Stripe Checkout:使用后端返回的会话 ID 将用户重定向到 Stripe Checkout。

?设置环境变量

确保在 Stirpe Dashboard 上添加您的产品和运费。

条纹:
Building a Custom Shipping Calculator with Stripe and Netlify Functions for Multi-Currency (€/$), Quantity, and Location Support
在 Netlify 上:
Building a Custom Shipping Calculator with Stripe and Netlify Functions for Multi-Currency (€/$), Quantity, and Location Support

在项目的根目录中创建一个 .env 文件并添加环境变量(或在 Netlify UI 上执行,如上所示“站点配置 > 环境变量”):

/functions
  - create-checkout-session.js
/index.html
.env
netlify.toml
package.json
登录后复制
登录后复制
登录后复制
  • 将这些值替换为您的实际 Stripe 键和运费 ID。
  • 确保在您的 Stripe 仪表板中创建这些运费。

?更新 netlify.toml

配置 Netlify 在函数中使用环境变量:

// functions/create-checkout-session.js

// Add Stripe secret key
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

exports.handler = async (event) => {
  // Parse the order data sent from the frontend
  const order = JSON.parse(event.body);

  // Define country groups
  const euCountries = ['AL', 'AM', 'AT', ...]; // Add the EU countries you ship to
  const worldCountries = ['AE', 'AR', 'AU', ...]; // Add worldwide countries you ship to
  let allowedCountries = [];

  // Payment methods based on currency
  let paymentMethods = [];

  // Determine shipping rates and allowed countries
  if (order.currency === 'EUR') {
    paymentMethods = ['card', 'sepa_debit', 'ideal', 'bancontact', 'p24', 'eps', 'giropay', 'sofort'];

    if (order.shippingOption === 'europe-eur') {
      allowedCountries = euCountries;
      // Set shipping rate IDs for Europe in EUR
      order.shippingRate = process.env[`SHIPPING_RATE_EUR_EU_${order.items}`];
    } else if (order.shippingOption === 'world-eur') {
      allowedCountries = worldCountries;
      // Set shipping rate IDs for World in EUR
      order.shippingRate = process.env[`SHIPPING_RATE_EUR_W_${order.items}`];
    }
  } else if (order.currency === 'USD') {
    paymentMethods = ['card'];

    if (order.shippingOption === 'europe-usd') {
      allowedCountries = euCountries;
      // Set shipping rate IDs for Europe in USD
      order.shippingRate = process.env[`SHIPPING_RATE_USD_EU_${order.items}`];
    } else if (order.shippingOption === 'world-usd') {
      allowedCountries = worldCountries;
      // Set shipping rate IDs for World in USD
      order.shippingRate = process.env[`SHIPPING_RATE_USD_W_${order.items}`];
    }
  }

  // Create the Stripe Checkout session
  const session = await stripe.checkout.sessions.create({
    payment_method_types: paymentMethods,
    line_items: [
      {
        price: order.priceId, // The price ID of your product
        quantity: order.items,
      },
    ],
    mode: 'payment',
    billing_address_collection: 'auto',
    shipping_rates: [order.shippingRate],
    shipping_address_collection: {
      allowed_countries: allowedCountries,
    },
    success_url: `${process.env.URL}/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.URL}/cancel`,
  });

  return {
    statusCode: 200,
    body: JSON.stringify({
      sessionId: session.id,
      publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
    }),
  };
};
登录后复制
登录后复制

?安装依赖项

运行以下命令安装 Stripe SDK:

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
登录后复制
登录后复制

?测试功能

  1. 启动 Netlify 开发服务器
exports.handler = async (event) => {
  const order = JSON.parse(event.body);
  // Rest of the code...
};
登录后复制
登录后复制
  1. 下订单
  • 在浏览器中打开您的index.html 文件。
  • 选择您的选项并单击“预购”按钮。
  • 确保 Stripe Checkout 中显示正确的运费和付款方式。
  1. 测试不同的场景
  • 在欧元和美元货币之间切换。
  • 更改运送选项和商品数量。
  • 确认允许的国家/地区与您的配置相符。

?结论

瞧!您已设置自定义运费计算器功能,该功能可根据货币数量位置动态调整运费。

您可以随意调整和扩展此设置,以适应您自己的产品和运输政策。

?其他资源

  • Stripe Checkout 文档
  • Netlify 函数文档
  • 在 Stripe 中创建运费
  • Stripe.js 参考

注意:本文基于预订/销售最多三本一本书的真实场景,并演示了一种处理涉及货币、数量和位置变量的运输计算的方法。根据您的具体需求,可能会有更有效的方法。

以上是使用 Stripe 和 Netlify 功能构建自定义运费计算器,以支持多货币 (€/$)、数量和位置的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!