surprisehighway / craft-avatax
使用Avalara的Avatax服务计算并将销售税添加到订单的基础税额。
Requires
- php: ^8.2
- avalara/avataxclient: ^24
- craftcms/cms: ^5.0.0-beta.10
- craftcms/commerce: ^5.0.0-beta.1
This package is auto-updated.
Last update: 2024-09-05 21:21:40 UTC
README
使用Avalara的AvaTax服务计算并将销售税添加到订单的基础税额。

要求
此插件需要Craft 5和Commerce 5或更高版本。
安装
要安装此插件,请按照以下说明操作。
-
打开您的终端并转到您的Craft项目
cd /path/to/project
-
然后告诉Composer加载插件
composer require surprisehighway/craft-avatax
-
在控制面板中,转到设置 → 插件,并点击Avatax的“安装”按钮。
设置概述
设置和配置的详细信息如下,但以下是一个快速概述,说明您需要做什么才能开始
- 使用您的Avalara账户信息配置插件设置并测试连接。
- 使用您的原始地址和默认税代码配置插件设置。
- 将“Avatax”税类别设置为对产品类型可用。
- 将“Avatax”税类别分配给您的产品。
- 可选地,将特定于产品的税代码字段添加到您的产品类型字段中,以允许按产品设置税代码。
- 可选地,将客户使用类型字段添加到您的用户字段中,以设置免税客户。
配置AvaTax账户连接
- 访问设置页面设置 → Avatax
- 为每个环境输入账户ID、许可证密钥和公司代码凭证。
- 选择“沙盒”或“生产”将启用所选环境。
- 点击“测试连接”按钮以验证您的连接。
- 点击“保存”按钮以保存您的设置。
提示:建议您使用以下设置的环境变量:账户ID、许可证密钥、公司代码、沙盒账户ID、沙盒许可证密钥、沙盒公司代码,以防止敏感信息保存在项目配置或数据库中。有关更多示例,请参阅下面的配置覆盖。
配置AvaTax发货原产地
- 指定有效的发货地址。
- 点击“保存”按钮以保存您的设置。
配置AvaTax插件选项
- 访问设置页面设置 → Avatax
- 启用税务计算 - 独立于其他设置启用或禁用税务计算。
- 启用提交 - 启用或禁用文档提交。
- 启用地址验证 - 启用或禁用Avalara的地址验证。
- 启用调试 - 在设置和测试时启用调试以记录所有API交互。确保一旦上线就禁用。
- 点击“保存”按钮以保存您的设置。
使用AvaTax
完成安装和配置后,AvaTax将计算并应用销售税到所有带有有效发货地址且选择了Avatax税率类别的订单。
Craft 5提示:税率类别下拉菜单不再位于产品详细信息的侧边栏中。您必须双击一个变体才能在变体弹出窗口中查看税率和运输类别(并确保侧边栏可见)。如果您不需要为不同的产品使用不同的税率类别,请确保Avatax是默认设置。
税代码
例如,'P0000000' - 有形个人财产(TPP).
您可以通过在插件设置中设置默认税收代码值来设置默认的 Avalara 税收代码。这将作为所有产品的默认税收代码发送给 Avalara。
您还可以通过为您的产品添加自定义字段来为每个产品设置特定的税收代码。
设置产品字段
- 访问设置 → 字段。您应该会看到一个名为“AvaTax 税收代码”的字段,该字段是在插件安装期间创建的。如果没有,请创建一个。请注意,“名称”可以是任何您想的内容,例如“AvaTax 税收代码”或“产品税收代码”,但“处理”必须匹配
avataxTaxCode
并且是大小写敏感的。 - 访问商业 → 设置 → 产品类型,然后单击您的产品类型名称。
- 单击 产品字段 选项卡。
- 添加 AvaTax 税收代码字段并保存。
在您的产品条目中,您现在可以输入任何文本作为 AvaTax 税收代码发送。如果此字段不存在或为空,则将使用您的配置文件中的默认税收代码设置。
提示:默认情况下,字段是纯文本,但您可以将它改为下拉菜单,其中包含预配置的值,只要处理保持相同即可。
运费代码
例如,'FR' - 仅运费 - 公共承运人 - 目的地FOB。
运费作为单独的行项目发送到 AvaTax。您可以通过在插件设置中设置默认 Avalara 税收代码 来为运费设置默认的税收代码。
免税客户
您可以通过添加用于指定 Avalara 实体/使用代码 的自定义字段到您的用户设置中来指定一个免税客户。
设置用户字段
- 访问设置 → 字段。您应该会看到一个名为“AvaTax 客户使用类型”的字段,该字段是在插件安装期间创建的。如果没有,请创建一个。请注意,“名称”可以是任何您想的内容,例如“AvaTax 客户使用类型”或“实体/使用代码”,但“处理”必须匹配
avataxCustomerUsageType
并且是大小写敏感的。 - 访问设置 → 用户 → 字段。
- 添加 AvaTax 客户使用类型字段并保存。
在您的用户账户中,您现在可以设置一个实体/使用代码以发送到 Avalara。如果允许用户在前端编辑自己的个人资料,则您如何实现这一点取决于您,但在大多数情况下,这很可能是管理任务。
这需要用户在结账时登录,而不是匿名结账。
提示:默认情况下,此下拉字段包含所有默认的 Avalara 实体/使用代码,但您可以编辑选项以根据自己的用例进行自定义,或者如果您已在 AvaTax 网站上设置了自定义代码。
促销活动
促销活动受到支持。对于销售,销售价格简单地作为行项目金额发送到 Alavara。折扣作为单独的行项目发送,使用 默认折扣代码 插件设置作为 Avalara 税收代码。
退款
Craft Commerce 支持已完成交易的退款,如果 支付网关 支持退款。如果支持订单的退款,则 Commerce 在订单的交易历史中显示“退款”按钮。
截至 Commerce 2.0,管理员控制面板可以多次发起部分退款。触发全额退款并支付原始订单的准确金额将生成对应 AvaTax 交易全额的新退货发票。请注意,触发部分退款将生成对应 AvaTax 客户 部分金额的新退货发票,但与原始交易无关。这是因为 AvaTax 只对完整交易、特定行项目或百分比进行退款。
客户代码
默认情况下,插件会将订单电子邮件地址作为客户代码发送给 Avalara。利用此“隐藏”功能,您可以选择覆盖此行为,使用具有特定处理程序的用户或订单字段中保存的值。该字段在您安装插件时不会自动创建,您必须手动创建。
设置字段
- 创建一个名为“Avatax 客户编号”的“用户”或“订单”字段,处理程序为
avataxCustomerCode
。处理程序必须完全匹配且区分大小写。
请注意,您有权自行决定如何保存或验证字段值。如果该字段可用,插件将简单地使用字段值,或者如果该字段为空或不存在,则默认使用订单电子邮件地址。
配置覆盖
您可以使用 Craft 的插件配置文件支持来覆盖控制面板中许多插件设置。这对于“锁定”某些设置非常有用,还可以提供按环境设置。
- 将
config.php
从avataxtax
目录复制到您的 craft/config 文件夹,并将其重命名为avatax.php
- 更新
avatax.php
中的值并保存。
建议使用环境变量来以下账户设置
.ENV 文件
AVATAX_ACCOUNT_ID=123456
AVATAX_LICENSE_KEY=987654321
AVATAX_COMPANY_CODE=MYCOMPANY
AVATAX_SANDBOX_ACCOUNT_ID=123456
AVATAX_SANDBOX_LICENSE_KEY=987654321
AVATAX_SANDBOX_COMPANY_CODE=MYCOMPANY
config/avatax.php
<?php
return [
'*' => [
// The address you will be posting from.
'shipFromName' => 'John Doe',
'shipFromStreet1' => '201 E Randolph St',
'shipFromStreet2' => '',
'shipFromStreet3' => '',
'shipFromCity' => 'Chicago',
'shipFromState' => 'IL',
'shipFromZipCode' => '60601',
'shipFromCountry' => 'US',
// The default Avalara Tax Code to use for Products.
'defaultTaxCode' => 'P0000000',
// The default Avalara Tax Code to use for Shipping.
'defaultShippingCode' => 'FR',
// The default Avalara Tax Code to use for Discounts.
'defaultDiscountCode' => 'OD010000',
// Production account information from ENV.
'accountId' => '$AVATAX_ACCOUNT_ID',
'licenseKey' => '$AVATAX_LICENSE_KEY',
'companyCode' => '$AVATAX_COMPANY_CODE',
// Sandbox account information from ENV.
'sandboxAccountId' => '$AVATAX_SANDBOX_ACCOUNT_ID',
'sandboxLicenseKey' => '$AVATAX_SANDBOX_LICENSE_KEY',
'sandboxCompanyCode' => '$AVATAX_SANDBOX_COMPANY_CODE',
// Environment - 'production' or 'sandbox'.
'environment' => 'sandbox',
// AvaTax options - true or false
'enableTaxCalculation' => true,
'enableCommitting' => true,
'enableAddressValidation' => false,
'enablePartialRefunds' => true,
// Enable debugging - true or false
'debug' => true,
],
'production' => [
// Environment - 'production' or 'sandbox'.
'environment' => 'production',
// Enable debugging - true or false
'debug' => false,
],
];
表单输入覆盖
您可以使用隐藏表单输入字段来覆盖插件的税计算设置。
即使插件已启用税计算设置,您也可以在表单中添加以下输入来禁用表单的税计算
<input type="hidden" name="avatax_disable_tax_calculation" value="1">
...或 twig 辅助程序
{{ hiddenInput('avatax_disable_tax_calculation', 1) }}
即使插件已禁用税计算设置,您也可以在表单中添加以下输入来强制执行表单的税计算
<input type="hidden" name="avatax_disable_tax_calculation" value="1">
...或 twig 辅助程序
{{ hiddenInput('avatax_force_tax_calculation', 1) }}
注意:如果 Avatax 响应已缓存,则此设置不会强制执行新的 API 请求。它只会强制插件表现得好像已启用设置。
值使用 PHP validate 过滤器 FILTER_VALIDATE_BOOLEAN 进行解析,因此值为 "1"、"true"、"on" 和 "yes" 返回 true。否则返回 false。
AJAX 示例
您可以使用 JSON 控制器端点进行 AJAX 查找/验证。目前,唯一的端点是地址验证和通过客户编号进行 CertCapture 客户查找。
AJAX 地址验证
您可以使用前端 AJAX 查找来调用 AvaTax 的Resolve Address API。请注意,如果您在前端实现此功能,您可能希望禁用插件设置中的地址验证,以避免在结账过程中进行更多 API 调用(JSON 端点仍然有效)。
此示例使用默认 Commerce 2 地址表单字段和 jQuery 执行 AJAX 调用来提供起点,但是 jQuery 不是必需的,并且您必须根据您的结账流程进行实现。
{% js %}
$('#address-form').on('submit.addressValidation', function(e) {
e.preventDefault();
var $form = $(this);
var data = {
address1 : $('[name="shippingAddress[address1]"]').val(),
address2 : $('[name="shippingAddress[address2]"]').val(),
city : $('[name="shippingAddress[city]"]').val(),
zipCode : $('[name="shippingAddress[zipCode]"]').val(),
stateValue : $('[name="shippingAddress[stateValue]"]').val(),
countryId : $('[name="shippingAddress[countryId]"]').val()
};
var csrfTokenName = "{{ craft.app.config.general.csrfTokenName }}";
var csrfTokenValue = "{{ craft.app.request.csrfToken }}";
data[csrfTokenName] = csrfTokenValue;
$.ajax({
type: 'post',
url: '/actions/avatax/json/validate-address',
data: data,
dataType: 'json'
}).done(function(data){
console.log(data);
if(data.success) {
// valid address
$form.off('submit.addressValidation').submit();
} else {
// handle error here...
return false;
}
});
});
{% endjs %}
CertCapture 客户查找
将自定义客户代码传递给AvaTax的一个示例用例是,如果在连接的CertCapture账户中找到一个匹配的客户,则自动将基于该客户的证书的免税税项应用于AvaTax。
在这种情况下,您可能希望在将其传递给AvaTax之前验证客户编号字段,看是否在CertCapture中找到匹配的客户。
在使用此API之前,您需要将您的CertCapture凭据添加到您的config/avatax.php
文件中。
<?php
return [
// ... other settings ...
'certCaptureUsername' => 'username',
'certCapturePassword' => 'password',
'certCaptureClientId' => '123456',
];
此示例演示了一个潜在的按钮点击处理程序,该处理程序通过AJAX请求插件的自定义JSON端点触发CertCapture中的客户编号查找。如果找到匹配的客户,插件将返回成功和包含客户信息的CertCapture响应,如果没有找到匹配项,则返回错误。请注意,CertCapture客户编号是区分大小写的。jQuery不是必需的,您需要根据您的结账流程进行实现。
{% js %}
$('button.validate-customer').on('click', function(e) {
e.preventDefault();
var data = { number: $('[name="fields[avataxCustomerCode]"]').val() };
var csrfTokenName = "{{ craft.app.config.general.csrfTokenName }}";
var csrfTokenValue = "{{ craft.app.request.csrfToken }}";
data[csrfTokenName] = csrfTokenValue;
$.ajax({
type: 'post',
url: '/actions/avatax/json/cert-capture-customer',
data: data,
dataType: 'json'
}).done(function(data){
console.log(data);
if(data.success) {
// customer found, show valid state or submit form...
} else {
// invalid customer number, handle error here...
}
});
});
{% endjs %}
AvaTax插件路线图
一些待办事项和潜在功能的想法
- 更好的异常处理
- 在产品类型级别设置默认税码的配置设置。